0x01 基础分析
题目中共有两个附件guess和libc-2.27.so
先运行guess:
captain@ubuntu:~/Desktop$ ./guess
1. Login to guess
2. Exit
Choice:
和密码账户相关,应该是硬编码写入了程序中,下面通过IDA分析尝试获取密码账户
0x02 IDA逆向分析
一、main函数
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
alarm(0x60u);
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
while ( 1 )
{
sub_9C0(); // 选择功能1、2
if ( sub_9F0() != 1 ) // 判断用户输入
break;
sub_A43();
}
return 0LL;
}
二、继续分析关键函数sub_A43():
unsigned __int64 sub_A43()
{
int i; // [rsp+4h] [rbp-22Ch]
char buf[256]; // [rsp+10h] [rbp-220h]
char v3[16]; // [rsp+110h] [rbp-120h]
FILE *v4; // [rsp+120h] [rbp-110h]
unsigned __int64 v5; // [rsp+218h] [rbp-18h]
v5 = __readfsqword(0x28u);
v4 = stderr;
printf("Account: ");
read(0, buf, 0x100uLL);
printf("Password: ", buf);
read(0, v3, 0x100uLL); // Account=buf;Password=v3
for ( i = 0; i < strlen(buf); ++i )
{
if ( buf[i] != v3[i] ) // Account=Password即可登录
{
puts("Login fail");
return __readfsqword(0x28u) ^ v5;
}
}
sub_91A(buf, v3);
return __readfsqword(0x28u) ^ v5;
}
尝试登录:
test@ubuntu:~/Desktop$ ./guess
1. Login to guess
2. Exit
Choice: 1
Account: hello
Password: hello
Welcome, Boss. Leave your valuable comments: Alarm clock
三、登录验证成功之后指向sub_91A(buf, v3)函数,跟进分析,其反汇编代码如下
unsigned __int64 sub_91A()
{
char v1[64]; // [rsp+10h] [rbp-50h]
int i; // [rsp+50h] [rbp-10h]
unsigned __int64 v3; // [rsp+58h] [rbp-8h]
v3 = __readfsqword(0x28u);
printf("Welcome, Boss. Leave your valuable comments: ");
for ( i = 0; i != 65; ++i )
{
read(0, &v1[i], 1uLL);
if ( v1[i] == 10 )
break;
}
return __readfsqword(0x28u) ^ v3;
}
一眼就看出read()函数不是人,因为函数中只定义了64bytes大小的空间存储用户存储用户的comments,读取comments的时候是通过for循环一个字符接一个字符的读入,以换行符作为comments的结束,但是for的判断条件为i!=65,因此那么第0~64能够读入,66往后也会被读入,最终会超过v1的栈空间,出现栈溢出漏洞。
0x03 触发奔溃
Tips:
1、反汇编伪代码中多次出现的readfsqword函数