Flare-on9 2022

Flare-on9 2022


Nguồn ở đây nhá các bạn: 💀👆👆👆💀

Xin chào các bạn đến với writeupp lần này. Lần đầu gà con vào đảo của các lãnh làng sẽ như thế nào nhỉ? Hốt hoảng thật sự hí hí… Sau quá trình nghiên cứu và tìm hiểu tôi sẽ viết hoàn thành tất của các chall của mùa giải năm nay cho mn được tham khảo nhé. (Link)

Ok bắt đầu thôi… gét gô…

1: Flaredle (Solved)

Description:

Welcome to Flare-On 9!

You probably won't win. Maybe you're like us and spent the year playing Wordle. We made our own version that is too hard to beat without cheating.

Play it live at: http://flare-on.com/flaredle/

title Chúng ta được nhận 4 file. Đầu tiên sẽ mở file đuôi .html để xem nội dung hiện thị là gì? Ta thấy nó sử dụng js được cung cấp sẵn. Thế nên là tôi mở file js check xem họ viết gì và dấu gì ở đó. Xem qua ta thấy có hàm if kiểm tra chuỗi từ người dùng và chuỗi flag nằm trong file script.js: function check Ta tìm kiếm rightGuessString xem nó là gì?? var right Ok nhận thấy biến này được lấy từ thứ 57 trong file words.js. Từ đó ta nhận được: flareonisallaboutcats. Kiểm tra lại trên web thỏa mãn. check result

2: PixelPocker (Solved)

Description

I said you wouldn't win that last one. I lied. The last challenge was basically a captcha. Now the real work begins. Shall we play another game?

Công cụ được sử dụng:

  • CFF Explorer
  • IDA Pro
  • Python
    • PIL: pip install pillow (1 fork từ thư viện PIL của python được sử dụng để xử lý hình ảnh)

Nội dung của readme.txt

Welcome to PixelPoker ^_^, the pixel game that's sweeping the nation!

Your goal is simple: find the correct pixel and click it

Good luck!

Đầu tiên ta mở bằng CFF Explorer quan sát metadata của file exe. Và ta có chú ý về resourse là dạng Bitmaps (ảnh) gồm 2 bức ảnh với tên 129 và 133. check metadata Chương trình hướng đến việc cần phải lưạ chọn 1 điểm ảnh với tọa độ hiện thị trên cửa sổ và có đối ta 10 lần thử. open file

và tôi thử xem ra kết quả là gì: test Ta nhận được thông báo Womp womp...:(. Rồi chúng ta sẽ mở chúng bằng IDA Pro kiếm strings này nằm ở hàm nào?. open ida Ta sửa đổi lại tên của một số biến nhận diện rồi. Như đã thấy thì ta thấy có hàm kiểm tra 2 vị trí x,y với một giá trị có sẵn lấy dư với uXuY. see var ux Ta cần tìm hiểu xem biến dword_413280 là gì? thì nó nằm trong hàm BitBlt - 1 hàm thực hiện truyền khối bit dữ liệu tương ứng với một hình chữ nhật pixel từ ngữ cảnh thiết bị nguồn đã chỉ định sang ngữ cảnh thiết bị đích.

BOOL BitBlt(
    [in] HDC   hdc,
    [in] int   x,
    [in] int   y,
    [in] int   cx,
    [in] int   cy,
    [in] HDC   hdcSrc,
    [in] int   x1,
    [in] int   y1,
    [in] DWORD rop
);

Do đó dword_413280cx - là chiều rộng của nguồn (ở trường hợp này là hình ảnh); còn cy - là chiều cao của hình ảnh.

[in] cx
The width, in logical units, of the source and destination rectangles.

[in] cy
The height, in logical units, of the source and the destination rectangles.

so sanh Bước so sánh ở dòng 43 và 46 kiểm tra giá trị của tọa độ click chuột theo trục (x,y) thỏa mãn điều kiện sau:

x = 0x52414c46 % độ rộng ảnh = 0x52414c46 % 741 = 95

y = 0x6e4f2d45 % độ cao ảnh = 0x6e4f2d45 % 641 = 313

Như vậy ta click đúng tọa độ trên thì sẽ chuyển sang luồng khác và có kết quả: result

3: Magic_8_Ball (Solved)

Description:

You got a question? Ask the 8 ball!

Đầu tiên ta giải nén thì ta nhận được nhiều file không biết file nào sẽ là quan trọng nên chúng ta trước mắt ta cứ quan tâm chính vào file chương trình .exe nha. giai nen Mở file thực thi nên thấy nhập 1 gì đó rồi Enter thì ta nhập được các thông điệp và nhấn các mũi tên thì ta thấy quả bóng lắc: open Ta mở nó bằng IDA Pro xem sao nhá. Thì thấy được các string hiện thị lúc nãy đều nằm cùng 1 hàm sub_4012B0: string Tiếp tục theo dấu xem hàm nào sẽ call đến hàm này (chúng ta sẽ rename là predict_string_func) thì thấy nó được gọi từ sub_4027A0, có lẽ đây là hàm main của chương trình. Để ý phía dưới có một vòng lặp do while, rất giống với vòng lặp xử lý các sự kiện (event) rất hay gặp trong các ứng dụng GUI. main Đi dạo quanh các hàm trong vòng lặp do while thì ta nhận ra đoạn này giống như đoạn điều hướng của quả bóng: 04 và kéo xuống dưới thì là các câu lệnh điều kiện kiểm tra lồng nhau. Trường hợp này ta convert các số 76,85,82,68 sang kiểu dữ liệu char: command if

Ta nhận được: LLURULDUL. Sau khi kiểm tra chuỗi này xong thì sẽ so sánh chuỗi có độ dài 15 ký tự:

result = strncmp(v21, (const char *)(this + 92), 15u);

Ta debug tại IDA luôn điều hướng quả bóng như trên mình phân tích rồi ta nhập 1 string nào đó rồi đặt breakpoint (F2) tại hàm so sánh này thì ta nhận được như sau: debug check Như vậy ta nhận thấy có 2 câu lệnh 3 câu lệnh push trước khi gọi hàm strncmp có nghĩa là truyền tham số vào hàm đó tương ứng: push từ phải qua trái -> ta thấy thanh ghi ecx sẽ là string mình nhập và thanh ghi eax chính là nguồn sẽ so sánh. eax và mọi thứ coi như đã xong kiếm được string so sánh là: gimme flag pls? Chạy lại chương trình, nhập đúng chuỗi phím định hướng quả bóng và nhập câu hỏi vừa tìm được sẽ in ra flag: flag

U_cRackeD_th1$_maG1cBaLL_!!_@flare-on.com

4: darn_mice

Description:

"If it crashes its user error." - Flare Team

Đề bài cho 1 file darn_mice.exe. Đầu tiên tôi sẽ kiểm tra các thông tin của file bằng phần mềm Detect It Easy (viết tắt của chương trình sẽ là die màu vàng) chúng ta biết được đây là 1 ứng dụng console viết bằng C++. open check die Tôi vào console chạy thử không cho tham số thì không thấy ra gì và thêm tham số thì có ra kết quả -> bài yêu cầu truyền tham số như password nếu đúng sẽ in ra flag gì đó. open console Để kiểm tra và làm tôi mở IDA thì ta thấy open ida check main Như vậy hàm này chính xác là yêu cầu ta truyền vào là 2 argc. Nếu đủ sẽ vào chương trình kiểm tra password: func check pass Ở đây ta phân tích như sau: (sửa tên lại ta có như sau) rename

  • Chuỗi ta nhập thì sẽ gọi là pbPassword.
  • Sau đó sẽ in ra màn hình -> tiếp đến là kiểm tra kích thước của pbPassword: if (!v3 || v3 > 0x23) phần này check strlen phải thỏa mãn tồn tại và không được lớn hơn 0x23 nó là 35 -> kích thước của pbPassword35:

Tiếp đến ta để ý đến vòng lặp for:

  • Đầu tiên, thực hiện allocation một vùng nhớ, kích thước 0x1000 lưu vào v2
  • Sau đó là lấy từng ký tự của pbPassword đem cộng tương ứng với vị trí của biến magic đã được khai báo và gán giá trị ở đầu func.
  • Gán giá trị này cho byte đầu tiên của vùng nhớ vừa được khởi tạo
  • Nhảy đến vào chạy code tại vùng nhớ đó (tương ứng với lệnh gọi v2(v2))
  • in ra chuỗi Nibble...
  • Tiếp tục vòng lặp

Qua đoạn for này nếu nhập đúng, chương trình sẽ dùng password này để decrypt ra flag

Vậy là bài toán đặt ra là xây dựng code làm sao để thực hiện đúng 1 lệnh assembly (opcode) để chương trình không bị crash và sau đó lại quay lại thực hiện theo flow cũ của chương trình (tiếp tục in ra dòng Nubble...).

debug

Tôi thử với pass là 123456789. Ta thấy dòng code vị trí .text:01011155 là nó cộng rồi lưu vào thanh ghi ecx; tiếp theo mov địa chỉ ô nhớ sẽ gọi cho thanh ghi edx. Khi gọi vào vùng nhớ, gặp opcode nào đó để ngay lập tức quay lại để tiếp tục flow cũ chạy như bình thường.

06

Như vậy hex(ord('1') + ord('P')) = '0x81' nó là câu lệnh add ))). Thử kết quả là NOP thì code lại chạy tiếp tục trong vùng nhớ đó và báo lỗi, và thử opcode RET = 'C3' câu lệnh cuối của mỗi hàm thì nó trở về và xong.

retn

Giờ viết mà code để tìm pass nhá:

str_magic = [0x50, 0x5E, 0x5E, 0xA3, 0x4F, 0x5B, 0x51, 0x5E, 0x5E, 0x97, 0xA3, 0x80, 0x90, 0xA3, 0x80, 0x90, 0xA3, 0x80, 0x90, 0xA3, 0x80, 0x90, 0xA3, 0x80, 0x90, 0xA3, 0x80, 0x90, 0xA3, 0x80, 0x90, 0xA2, 0xA3, 0x6B, 0x7F]
password = "".join([chr(0xC3 - m) for m in str_magic])
print(password)
#see three, C3 C3 C3 C3 C3 C3 C3! XD

Và chạy password vừa tìm được thì ta nhận được: result

Xong flag sẽ là: i_w0uld_l1k3_to_RETurn_this_joke@flare-on.com

5: t8

FLARE FACT #823: Studies show that C++ Reversers have fewer friends on average than normal people do. That's why you're here, reversing this, instead of with them, because they don't exist.

We’ve found an unknown executable on one of our hosts. The file has been there for a while, but our networking logs only show suspicious traffic on one day. Can you tell us what happened?

7-zip password: flare

Ta nhận được 2 file t8.exetrafic.pcapng - file chứa các thông tin networking log của file nghi ngờ. Sử dụng Wireshark để quan sát tập tin chứa dữ liệu mạng.

Đối với TCP Stream là loại HTTP thì Wireshark cho phép thao tác để lấy dữ liệu trong trường data của method POST một cách dễ dàng.

Quay trở lại với file t8.exe, để bước vào phân tích thì cần kiểm tra một số thông tin cần thiết liên quan. Đọc metadata sử dụng CFF Explorer cho thấy tập tin là PE32 và có khả năng là sử dụng chương trình biên dịch là VS C++. Do đó cần sử dụng công cụ như x64dbg, IDA Pro hoặc Ghidra để phân tích tĩnh và động.

Trong hàm main có kiểm tra điều kiện:

while ( sub_404570(xmmword_45088C, DWORD1(xmmword_45088C), DWORD2(xmmword_45088C), HIDWORD(xmmword_45088C)) != 15 )
    Sleep(0x2932E00u);

Ta kiểm tra xem xmmword_45088C biến này là gì? Kiểm tra xem xref các các địa chỉ xmmword_45088C, thì kiếm được hàm sub_401020() khởi tạo giá trị này. Biến này được gná bằng thời gian hiện tại của chương trình lúc thực thi.

int sub_401020()
{
  struct _SYSTEMTIME SystemTime; // [esp+4h] [ebp-20h] BYREF
  int v2; // [esp+20h] [ebp-4h]

  v2 = 0;
  sub_405930(&dword_450874, L"FO9", 3);
  GetLocalTime(&SystemTime);
  srand(SystemTime.wMilliseconds + 1000 * (SystemTime.wSecond + 60 * SystemTime.wMinute));
  dword_450870 = rand();
  xmmword_45088C = (__int128)SystemTime;
  return atexit(sub_43DC50);
}

Tiếp đến là đi sâu vào hàm sub_404570 thì được:

int __cdecl sub_404570(unsigned int a1, unsigned int a2)
{
  unsigned int v2; // ecx
  int v3; // esi
  unsigned int v4; // eax
  float v5; // xmm0_4
  float v9; // [esp+2Ch] [ebp+14h]

  v2 = HIWORD(a1);
  v3 = (unsigned __int16)a1 - 1;
  if ( HIWORD(a1) > 2u )
    v3 = (unsigned __int16)a1;
  v4 = v2 + 12;
  if ( v2 > 2 )
    v4 = HIWORD(a1);
  v9 = (float)((float)((double)(int)(v3 / 100 / 4
                                   + HIWORD(a2)
                                   + (int)((double)(v3 + 4716) * 365.25)
                                   - (int)((double)(int)(v4 + 1) * -30.6001)
                                   - v3 / 100
                                   + 2)
                     - 1524.5)
             - 2451549.5)
     / 29.53;
  v5 = floor(v9);
  return (int)roundf((float)(v9 - v5) * 29.53);
}

Có các con số lạ thì ta tra google xem nó là gì thì nhận thấy đây là hàm tính toán có liên quan tới xác định chu kì mặt trăng (Moon phase). Với kết quả sub_404570() ==15 thì có thể xác định là thời điểm hiện tại là ngày rằm (trăng tròn).

Để vượt qua kiểm tra thì đơn giản là ta chỉnh lại thời gian ngày là ngày rằm (full moon).

Chạy chương trình và bắt dữ liệu mạng bằng Wireshark ta biết t8.exe sẽ phân giải tên miền flare-on.com và kết nối bằng giao thức HTTP.

(tiếp sẽ có sau)

results matching ""

    No results matching ""