中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何從一道CTF題目談PHP中的命令執行

發布時間:2021-11-11 18:16:37 來源:億速云 閱讀:147 作者:柒染 欄目:網絡安全

這篇文章給大家介紹如何從一道CTF題目談PHP中的命令執行,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

快睡的時候,打開B站發現有位用戶留言,大意就是讓我幫忙看一道題,正好當時有空,于是就打開了他發的鏈接,代碼如下

如何從一道CTF題目談PHP中的命令執行

很明顯是一道PHP代碼審計的題目,而且只需要繞過第三行的if即可進行任意命令執行。

解決思路

看了代碼之后覺得是道普通的題目,對于/a-zA-Z/這個正則表達式,我們可以利用PHP動態函數的特性,構造出字符串即可。

對于想要的字符串,我們可以通過以下三種方式來構造:

1. 異或

對于PHP中的字符串,兩個字符串異或的結果是將兩個字符串逐位異或,返回一個新字符串。那么我們便可以使用此特性進行構造。

例如我們需要構造phpinfo,則可以用腳本得到('0302181', '@[@[_^^')這兩個字符串,腳本如下:

如何從一道CTF題目談PHP中的命令執行

其中valid是可用的字符,answer是我們需要構造的字符串。那么我們得到了這個字符串,又該如何去執行呢。我們可以通過一個變量存儲兩字符串異或后的值,再讓這個變量進行動態函數執行即可,而變量的話因為PHP的變量命名規則和C語言相同,可以使用下劃線進行命名,如下:

如何從一道CTF題目談PHP中的命令執行

2. 取反構造

和第一種類似,都是基于PHP字符串位運算的特點(會逐位進行位運算)。而取反構造某些情況比異或構造要方便,因為異或的情況某些字符是無法直接通過其他字符進行異或構造的,而取反卻可以利用漢字或者其他特殊字符進行構造(不會有題目會限制某個漢字吧)。比如字母s我們可以通過~('和'{2})得到。而這個時候如果要用異或去構造的話,你得找到兩個異或值為s的特殊字符。

取反構造的腳本和異或構造類似,在此不再給出。

3. 自增構造

`++'a' == 'b'`

這個特點是利用了PHP是弱類型語言的特性,在對變量進行操作的時候,PHP會隱式的轉換其變量類型,很多代碼審計的題目也是利用了這一特性。

遇到障礙

有了上面的思路后,而且也成功執行了phpinfo(),下一步是不是就可以直接構造命令執行函數去進行讀取文件,當時我也是這么想的,于是我構造了passthru(), system(), shell_exec(), exec()等函數,都受到了阻礙,沒有回顯,通過進一步的調試之后發現是禁用了這些函數(通過在函數后面加一個打印函數觀察是否執行)。

在這里我停留了很久,試過打印$GLOBALS等都沒有任何有用的信息。最后通過使用glob()函數進行目錄掃描,發現了flag.php文件,以及file_get_contents()進行獲取,最終的payload如下

?mess=$_="`0123"^"?`~``";${$_}[_](${$_}[__]);&_=assert&__=print_r(base64_encode(file_put_contents("flag.php")))

如何從一道CTF題目談PHP中的命令執行

最后再將其界面就可以得到最終的flag了。在最終的payload中我沒有去一個一個的構造字符串異或,因為那太長了,而是構造了一個$_POST[_]($_POST[__])的動態函數,這樣就可以在其他參數位置直接寫函數了。

深入分析

題目到這里就結束了,其實并沒有多難,首先是通過特性去構造動態函數,然后發現了命令執行被禁用之后,能夠知道使用其他函數去進行獲取信息就行了。但是做完這道題后,不僅引發了我的思考,PHP中的命令執行就只有這些方式了嗎,肯定不是。于是,我總結了幾種新的命令執行技巧供大家參考。

1. 當打印函數被禁用時

如果沒有了打印函數,意味著你無法看到回顯,這時候即使命令執行成功了你也無法得到信息,這個時候你就得利用其他方式去獲取回顯了。

首先是網上很多blog使用的方式,phpinfo如果發現開啟了curl,或者其他文件傳輸擴展的的話,可以自建一個靶機,將所有訪問信息存入數據庫或是文件,然后將回顯信息發送到你的靶機地址,這樣你去看日志就可以了,這種方式不是很方便而且有一定的局限性。這里我要介紹的是一種新的方式。

如果你使用過Django或者jsp開發web的話,你肯定知道輸出一個變量可以使用{{xxx}}或是<%=xxx%>的方式,那么在PHP中是否也有這種方式呢,答案是肯定的,PHP中的<?=xxx?>就可以將一個變量輸出,那么如果使用它呢,你只需要構造如下的payload

$_="xxx";?><?=$_?>

這樣就可以將變量$_里面的內容打印到屏幕上,而且關鍵的是這個輸出方式默認是開啟的,管理員很容易就忽視這個選項。所以在做題時不妨一試。

2. 其他的命令執行方式

當system,passthru等不能用時,網上會告訴你可以使用popen,proc_open這些管道命令去進行執行命令,當然這沒有問題,而這里我向你介紹一種新方式,使用反引號,在PHP中,被兩個反引號括起來的內容將會作為shell命令執行,并將輸出信息返回,所以你可以構造下面的payload進行命令執行

$_=`ls`;

3. 不能使用數字字母的命令執行

當不能使用字母數字時,當然你可以使用上述的方式構造字符串進行執行,但是這里提供一些新東西,對于linux中的shell是支持正則表達式的,當你忘記某些字符時可以通過? % *來代替,經過測試,這里的匹配方式也是按照順序進行匹配,所以你可以查看你的linux中/bin目錄下面的順序,來獲取一些可以使用的命令,比如

 => /bin/cat

那么這樣的話,如果要獲取/var/www/html/index.php(你得感謝apache默認目錄如此之深),則可以直接使用來獲取

這篇文章只是針對這道題而延展出的一些東西,在真正做題時,情況可能更加復雜,例如限制長度,限制參數等等情況,而我們的做法也不可能千篇一律,可能某些時候我們甚至會用到一些CVE漏洞。而本篇文章只是告訴讀者一些可能以前沒有見過的新東西。

關于如何從一道CTF題目談PHP中的命令執行就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

彰化市| 卫辉市| 秭归县| 张掖市| 文化| 罗城| 宝鸡市| 冀州市| 阿图什市| 宝兴县| 长汀县| 凤阳县| 禄丰县| 柘荣县| 湘乡市| 丹阳市| 高唐县| 德阳市| 镶黄旗| 石狮市| 大邑县| 德保县| 龙门县| 那曲县| 北流市| 湖口县| 广元市| 汨罗市| 泰州市| 梅河口市| 房产| 顺义区| 合阳县| 蕲春县| 维西| 北海市| 济南市| 铁岭市| 花莲县| 色达县| 沁水县|