CSAWCTF 2021

1. Password Checker

IDA:

Hàm password_checker()

int password_checker()
{
  int result; // eax
  char s2[48]; // [rsp+0h] [rbp-A0h] BYREF
  char dest[48]; // [rsp+30h] [rbp-70h] BYREF
  char src[60]; // [rsp+60h] [rbp-40h] BYREF

  printf("Enter the password to get in: \n>");
  gets(src);
  strcpy(dest, src);
  strcpy(s2, "password");
  if ( strcmp(dest, s2) )
    result = printf("This is not the password");
  else
    result = printf("You got in!!!!");
  return result;
}

Phân tích mã giả thấy có lỗi BOF ở hàm gets() trong hàm password_checker(), và hàm backdoor() chạy lệnh system("/bin/sh") nên chúng ta sẽ đè return address của hàm password_checker() vào hàm backdoor(), lúc đó ta sẽ gọi được shell lên và cat flag.

2. Alien math

Đầu tiên minh sẽ đi qua các lệnh như file và checksec:

IDA:

Mình sẽ mô tả sơ về luồng thực thi chương trình như sau:

Hàm main

Ở đây hàm main sẽ khai báo 2 biến là v5 và v6, 1 chuỗi kí tự v4 có size là 36. Hàm scanf thứ nhất sẽ cho ta nhập vào biến v5, sau đó sử dụng hàm rand() để tạo số ngẫu nhiên cho v6. Sau đó so sánh v5 và v6 nếu bằng nhau thì chúng ta sẽ tiếp tục được nhập vào chuỗi v4 với độ dài 24 và truyền v4 vào hàm second_question().

Hàm second_question

Hàm second_question() sẽ nhận đối số chuỗi v4 mới nãy ta nhập vào, đoạn code từ dòng 8 đến dòng 16 sẽ thay đổi chuỗi v4. Sau đó sẽ tiến hành so sánh với chuỗi s1 có giá trị là "7759406485255323229225", nếu 2 chuỗi bằng nhau thì ta nhảy vào hàm final_question()

Hàm final_question()

Ở đây sẽ thấy lỗi BOF tại hàm gets(), và tình cờ thay trong chương trình lại có hàm print_flag()

Hướng giải quyết bài này thì mình sẽ bypass từng question rồi đè return address của hàm final_question() hướng vào hàm print_flag().

Vậy thì làm sao để bypass chỗ (v6==v5) để nhảy vào hàm second_question()? Mình biết sơ qua hàm rand(), nếu rand() được gọi mà không gọi srand() trước đó thì sẽ luôn cho cùng 1 giá trị khi chạy chương trình, các bạn có thể tìm hiểu ở đây, qua debug thì mình biết được giá trị đó là 1804289383

Giá trị decimal của 0x6b8b4567 là 1804289383

Còn bypass qua đoạn second_question() thì mình sẽ viết code để reverse lại chuỗi chương trình đã cho.

Đoạn code trên sẽ cho ta chuỗi có giá trị là "7856445899213065428791" đây chính là chuỗi cần nhập vào. Xong! vậy là chỉ còn việc tìm return address của hàm final_question() nằm ở đâu và get flag thôi

Code solve của mình:

Last updated