Pwn-guess[攻防世界]

J0ck3r / 2023-08-23 / 原文

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函数