Reverse Engineering

Challenge
Link

Count the Flag but Easier (331 pts)🥇

Reinvent the Wheel (499 pts)🥇

Flaggy Bird V2 (500 pts)🥇

Count the Flag but Easier (331 pts)

Description

-

Solution

Diberikan file txt, berikut isinya

fungsi():
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 20
        mov     DWORD PTR [rbp-8], 10
        mov     DWORD PTR [rbp-12], 20
        mov     eax, DWORD PTR [rbp-4]
        imul    eax, DWORD PTR [rbp-8]
        lea     ecx, [rax+2]
        mov     eax, DWORD PTR [rbp-12]
        mov     edx, eax
        sal     eax, 2
        sub     edx, eax
        lea     eax, [rcx+rdx]
        mov     DWORD PTR [rbp-16], eax
        sal     DWORD PTR [rbp-16], 20
        cmp     DWORD PTR [rbp-16], 100000000
        jg      .L2
        mov     eax, DWORD PTR [rbp-16]
        lea     edx, [rax+3]
        test    eax, eax
        cmovs   eax, edx
        sar     eax, 2
        mov     DWORD PTR [rbp-16], eax
        jmp     .L3
.L2:
        cmp     DWORD PTR [rbp-16], 100000000
        jle     .L4
        cmp     DWORD PTR [rbp-16], 500000000
        jg      .L4
        mov     eax, DWORD PTR [rbp-16]
        lea     edx, [rax+7]
        test    eax, eax
        cmovs   eax, edx
        sar     eax, 3
        mov     DWORD PTR [rbp-16], eax
        jmp     .L3
.L4:
        mov     eax, DWORD PTR [rbp-16]
        mov     edx, eax
        shr     edx, 31
        add     eax, edx
        sar     eax
        mov     DWORD PTR [rbp-16], eax
.L3:
        nop
        pop     rbp
        ret

Tujuannya jelas, jadi mencari tahu nilai akhir dari fungsi(). Disini kami lakukan konversi secara menual, karena kode assemblynya terhitung pendek. Berikut hasil konversi dari asm ke python

rbp_4 = 20
rbp_8 = 10
rbp_12 = 20
eax = rbp_4
eax *= rbp_8
ecx = eax + 2
eax = rbp_12
edx = eax
eax <<= 2
edx -= eax
eax = ecx + edx
rbp_16 = eax
rbp_16 <<= 20
if(rbp_16 > 100000000):
	#L2
	if(rbp_16 <= 100000000):
		#L4
		eax = rbp_16
		edx = eax
		edx >>= 31
		eax += edx
		eax >>= 1
		rbp_16 = eax
	elif(rbp_16>500000000):
		eax = rbp_16
		edx = eax
		edx >>= 31
		eax += edx
		eax >>= 1
		rbp_16 = eax
	eax = rbp_16
	edx = eax+7
	eax >>= 3
	rbp_16 = eax
else:
	eax = rbp_16
	edx = eax + 3
	eax >>= 2
	rbp_16 = eax
print(rbp_16)

Flag : NCW22{18612224}

Reinvent the Wheel (499 pts)

Description

-

Solution

Diberikan file elf 64 bit. Kami membukanya menggunakan IDA

Pada start terlihat ada pemanggilan fungsi init dan fungsi init mengeksekusi fungsi anti debug

Jadi lakukan bypass terhadap pengecekan debug tersebut ketika melakukan dynamic analysis dengan gdb.

Setelah bypass maka kita akan masuk ke fungsi main.

Terlihat pada IDA terdapat anti dissasembly pada fungsi main. Maka kita perlu lakukan sedikit dynamic analysis untuk ini.

Setelah masuk fungsi main lakukan next instruction sampai masuk ke alamat yang tidak bisa disassembly pada IDA. Jika sudah, cek instruksi pertama kali yang bisa di disassembly pada main (GDB) di alamat yang tidak bisa di disassembly pada IDA.

Terlihat pada 0x5555555553f6 sudah bisa didissassembly dengan benar, maka convert ke assembly mulai dari address tersebut lalu create new function pada address tersebut.

Langkah selanjutnya analisis fungsi pengecekan, terlihat bahwa terdapat fungsi swap yang dilakukan pada algoritma diatas. Jadi karena algoritmanya hanya swap, maka kita bisa lakukan pemetaan dengan cara menginputkan nilai yang berbeda sebesar 30 bytes dan set breakpoint pada 0x017CE .

Berikut solver yang kami gunakan untuk mendapatkan input yang valid.

import string

ori = string.printable[:0x1e]
mapp = "stcdefgh01stcdefgh012345ijklmn45ijklmn6789abopqr"

ct = "ss_is_beusss_is_beuse_sttter_isttter_iring_h_gue"
index = []
flag = [0 for i in range(0x1e)]
for i in mapp:
	index.append(ori.index(i))
for i in range(len(ct)):
	flag[index[i]] = ct[i]
print(''.join(flag))

Flag : NCW22{use_string_h_is_better_i_guess}

Last updated