war-ftp 缓冲区溢出攻击
实验目的
- 掌握缓冲区溢出的原理
- 掌握常用的缓冲区溢出方法
- 理解缓冲区溢出的危害性
- 掌握防范和避免缓冲区溢出攻击的方法
实验环境
虚拟机 winXP sp3
- 安装war-ftp 服务器
- 关闭DEP
- 安装OllyDBG
主机 mac (攻击方)
1
2» uname -a
Darwin challengedeMacBook-Pro.local 18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20 20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64 x86_64安装ftp命令
1
2
3
4
5
6安装
brew install telnet
brew install inetutils
brew link --overwrite inetutils
使用
ftp server-ip
其他
- ActivePerl:提供perl运行环境
- patternCreate.pl:构造不重复的字符
- patternOffset.pl:计算来前者产生的字符串中某段字符的偏移量。
实验内容
分析war-ftp v1.65的基于用户名的缓冲溢出漏洞。漏洞点:向服务器发送超过480字节的用户名可以触发漏洞(即使用命令USER longString\r\n)。
详细过程
验证漏洞
在虚拟机开启 ftp 服务。
tips:
初次打开可能会显示War-FTP refuses to restart with the error Unknown format for user database
解决:删除FtpDaemon.dat 和 FtpDaemon.ini文件 再重新打开即可。
主机连接ftp,在用户名处输入500个a测试
发现服务器端并没有崩溃,并且显示的字符显然没有500个,查阅资料ftp命令对USER长度有限制,当USER长度超过78个字符时,系统只截取前78个字符发送给目标主机。
试了几个ftp客户端发现同样会截断,最后选择直接采用socket编程实现发送命令,如下
1 | expftp.py |
测试 发现程序确实收到字符并且卡住了
od调试 分析栈结构
为了定位程序溢出时栈中 ret、esp 等的精确位置,这里用 patternCreate.pl 构造1000个不重复的字节。
OD attach 调试
payload 修改之后发送 exp
1 | test = b'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B' |
可以看到,此时,esp 为 00B2FD58 该地址内容为71413471,eip 为 32714131。通过patternOffset.pl计算出它在整个长为 1000的字符串中的偏移分别是493和485.
在return指令执行之前 栈的结构如下,
1 | +-----------------+ |
执行ret之后,0x32714131赋给eip,esp 往后4个字节,指向0x00B2FD58,此时eip执行0x32714131处的指令,显然出错。
1 | +-----------------+ |
构造exploit
如果将0x32714131换成指令jmp esp的地址(0x7ffa4512),再将0x00B2FD58位置的0x71413471填入shellcode,程序在ret之后即执行shellcode。构造如下:在偏移485的位置填入jmp esp指令的地址,偏移493的位置写shellcode,其他填充NOP指令。
1 | 0--->+-----------------+ |
完整的exp如下:
1 | expftp.py |
测试结果
测试成功,shellcode的功能是打开CMD