[30C3 CTF] fourier (Numbers200)

Heres one for those that like numbers and mathematics…

fourier.tar.gz

File dự phòng

Mở bài

Chúng ta được cung cấp cho 1 file fourier (elf) và 1 file flag.four (data). File fourier dùng để mã hóa, còn file flag.four, dĩ nhiên, là flag đã được mã hóa. feel_good

Thân bài

Sau một chút thời gian (rất dài) bỡ ngỡ khi thấy các thím ấy sử dụng GMP cho việc tính toán, mình cũng thể hiện được phẩm chất vượt trội trong thao tác mò code để mô phỏng lại thuật toán mã hóa như sau (nhìn chung thì khá dễ, mỗi tội hơi khó) emo_popo_shame:

[python]import random

random.seed(69)

in_file = open(‘flag’, ‘r’).read()
out_file = open(‘flag.four’, ‘wb’)

secret = int(in_file.encode(‘hex’), 16)
while (secret >= 24):
random_number = number_3 = 0

number_3 = secret – 4
number_3 <<= 2 number_3 -= 5 if (number_3 > 0x444):
number_3 = 0x444

random_number = random.randint(0, number_3 – 1)
random_number += 5

number_4 = 0
while (number_4 != random_number):
number_4 += 1
out_file.write(‘4’)

out_file.write(‘ ‘)
number_4 = 4
number_5 = 0

while (number_4 < secret): out_file.write('4') number_5 = number_4 number_4 *= random_number number_4 += 4 secret -= number_5 out_file.write(' ') while (secret != 0): secret -= 1 out_file.write('4') out_file.close()[/python] Ngoại trừ các thao tác mà mình đã đối chiếu và thấy khá tương đồng, vấn đề duy nhất tồn đọng là hàm random. [asm].text:0000000000400CA1 lea rdi, [rsp+98h+random_handle] ; Load Effective Address .text:0000000000400CA6 call ___gmp_randinit_default ; Call Procedure[/asm] Target sử dụng hàm ___gmp_randinit_default và hơi lạ là khi mình debug lại thấy các kết quả random bị lặp lại. Mình cũng mất hơi nhiều thời gian cho việc cài đặt và chạy thử cái GMP này, rồi nhờ luật nhân quả nên sau đó điểm sáng xuất hiện: emo_popo_haha

[python] number_4 = 0
while (number_4 != random_number):
number_4 += 1
out_file.write(‘4’)[/python]

Ở đây ta thấy rằng chương trình làm một việc, đó là ghi ra giá trị sau khi random (mỗi đơn vị ứng với một byte ‘4‘). Và tổng quan thì cái thuật toán mã hóa khi hiểu đơn giản sẽ như sau:

  1. Nếu secret còn lớn hơn 24, thì chạy một vòng lặp, mỗi lượt ghi ra 2 giá trị:
    1. random_number.
    2. Số lần lặp có đụng chạm đến number_5 (mật danh là X_LOOP). Lưu ý rằng number_5 là một giá trị then chốt, vì nó là yếu tố duy nhất gây ra sự thay đổi giá trị của secret. emo_popo_choler
  2. Khi secret nhỏ hơn 24, ghi ra secret.

Như thế, nếu ta chia file flag.four ra các phần ngăn cách bởi dấu cách (0x20), giá trị mỗi phần là độ dài của phần đó (vd ‘444‘ = 3), thì hàm giải mã có nhiệm vụ:

  1. Đọc ngược từ phần cuối về phần đầu (tức phần đầu tiên được đọc sẽ là phần cuối của file).
  2. Gán secret = phần đầu.
  3. Chạy vòng lặp cho đến khi hết nội dung:
    1. Đọc phần tiếp theo, đó chính là số lần lặp của X_LOOP.
    2. Đọc phần tiếp theo, đó chính là random_number.
    3. Tất cả giá trị đều đã đủ, ta có thể tính toán được number_5, và thêm vào secret.
  4. Chuyển đổi secret từ DEC qua ASCII.

(lý do vì sao lại đọc từ cuối trở về mà không đọc từ đầu trở đi trong khi 2 hướng nó như nhau, thì là vì, mình thích thế đấy sexy_girl
Code minh họa:

[python]cipher = open(‘flag.four’, ‘r’).read()
parts = cipher.split(‘ ‘)

secret = len(parts[len(parts) – 1])
part_index = len(parts) – 2

while (part_index > 0):
loop_count = len(parts[part_index])
random_number = len(parts[part_index – 1])

number_4 = 4
number_5 = 0
for i in range(loop_count):
number_5 = number_4
number_4 *= random_number
number_4 += 4
secret += number_5

part_index -= 2

print hex(secret)[2:-1].decode(‘hex’)[/python]

Kết bài

[sh]30C3_the_challenge_is_named_fourier_what_else_did_you_expect?[/sh]

emo_popo_smile

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *