# Reverse engineering chall
chall 32-bit ELF binary өгөгдсөн.
Ажилуулж үзвэл argument аваад youtube линк буцааж байна. Disassemble хийж үзье.
```bash
$: gdb chall
$: disassemble main
```
```asm
0x00001e8f <+0>: endbr32
0x00001e93 <+4>: lea ecx,[esp+0x4]
0x00001e97 <+8>: and esp,0xfffffff0
0x00001e9a <+11>: push DWORD PTR [ecx-0x4]
0x00001e9d <+14>: push ebp
0x00001e9e <+15>: mov ebp,esp
0x00001ea0 <+17>: push esi
0x00001ea1 <+18>: push ebx
0x00001ea2 <+19>: push ecx
0x00001ea3 <+20>: sub esp,0xc
0x00001ea6 <+23>: call 0x1130 <__x86.get_pc_thunk.bx>
0x00001eab <+28>: add ebx,0x3121
0x00001eb1 <+34>: mov esi,ecx
0x00001eb3 <+36>: push 0x0
0x00001eb5 <+38>: push 0x1
0x00001eb7 <+40>: push 0x0
0x00001eb9 <+42>: push 0x0
0x00001ebb <+44>: call 0x10e0 <ptrace@plt>
0x00001ec0 <+49>: add esp,0x10
0x00001ec3 <+52>: test eax,eax
0x00001ec5 <+54>: jns 0x1ee3 <main+84>
0x00001ec7 <+56>: sub esp,0xc
0x00001eca <+59>: lea eax,[ebx-0x1fc4]
0x00001ed0 <+65>: push eax
0x00001ed1 <+66>: call 0x10c0 <puts@plt>
0x00001ed6 <+71>: add esp,0x10
0x00001ed9 <+74>: mov eax,0x0
0x00001ede <+79>: jmp 0x1f69 <main+218>
0x00001ee3 <+84>: cmp DWORD PTR [esi],0x2
0x00001ee6 <+87>: je 0x1f01 <main+114>
0x00001ee8 <+89>: sub esp,0xc
0x00001eeb <+92>: lea eax,[ebx-0x1fa2]
0x00001ef1 <+98>: push eax
0x00001ef2 <+99>: call 0x10c0 <puts@plt>
0x00001ef7 <+104>: add esp,0x10
0x00001efa <+107>: mov eax,0x0
0x00001eff <+112>: jmp 0x1f69 <main+218>
0x00001f01 <+114>: call 0x122d <hidden_func>
0x00001f06 <+119>: mov eax,DWORD PTR [esi+0x4]
0x00001f09 <+122>: add eax,0x4
0x00001f0c <+125>: mov eax,DWORD PTR [eax]
0x00001f0e <+127>: sub esp,0x8
0x00001f11 <+130>: lea edx,[ebx+0x84]
0x00001f17 <+136>: push edx
0x00001f18 <+137>: push eax
0x00001f19 <+138>: call 0x10a0 <strcmp@plt>
0x00001f1e <+143>: add esp,0x10
0x00001f21 <+146>: test eax,eax
0x00001f23 <+148>: jne 0x1f52 <main+195>
0x00001f25 <+150>: sub esp,0xc
0x00001f28 <+153>: lea eax,[ebx-0x1f8d]
0x00001f2e <+159>: push eax
0x00001f2f <+160>: call 0x10c0 <puts@plt>
0x00001f34 <+165>: add esp,0x10
0x00001f37 <+168>: sub esp,0x8
0x00001f3a <+171>: lea eax,[ebx+0x84]
0x00001f40 <+177>: push eax
0x00001f41 <+178>: lea eax,[ebx-0x1f70]
0x00001f47 <+184>: push eax
0x00001f48 <+185>: call 0x10b0 <printf@plt>
0x00001f4d <+190>: add esp,0x10
0x00001f50 <+193>: jmp 0x1f64 <main+213>
0x00001f52 <+195>: sub esp,0xc
0x00001f55 <+198>: lea eax,[ebx-0x1f64]
0x00001f5b <+204>: push eax
0x00001f5c <+205>: call 0x10c0 <puts@plt>
0x00001f61 <+210>: add esp,0x10
0x00001f64 <+213>: mov eax,0x0
0x00001f69 <+218>: lea esp,[ebp-0xc]
0x00001f6c <+221>: pop ecx
0x00001f6d <+222>: pop ebx
0x00001f6e <+223>: pop esi
0x00001f6f <+224>: pop ebp
0x00001f70 <+225>: lea esp,[ecx-0x4]
0x00001f73 <+228>: ret
```
Хальт ажиглаад hidden_func, strcmp, puts, printf гэх мэт функц дуудсаныг харж болно. Эхлээд шууд юу болоод байгааг хурдан ойлгохын тулд IDA гаар pseudocode гаргаж үзэв.
```cpp
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
if ( ptrace(PTRACE_TRACEME, 0, 1, 0) >= 0 )
{
if ( argc == 2 )
{
hidden_func();
if ( !strcmp(argv[1], "************") )
{
puts("https://youtu.be/43TmnIaL3n4");
printf("oyusec{%s}\n", "************");
}
else
{
puts("https://youtu.be/tYzMYcUty6s");
}
result = 0;
}
else
{
puts("[-] Give me argument");
result = 0;
}
}
else
{
puts("https://youtu.be/1FkuDWxh8_o?t=35");
result = 0;
}
return result;
}
```
Эхний if `ptrace(PTRACE_TRACEME, 0, 1, 0)` нь debugger дээр ажиллаж байгаа эсэхийг шалгаж байна. Тийм болохоор шууд gdb гээр ажилуулвал "https://youtu.be/1FkuDWxh8_o?t=35" гэж хэвлэж байна.
Хоёрдох нь argument ийн тоог.
Тэрний дараа `hidden_func()` гэх функц дуудсан байна.
Тэгээд дараа нь `argv[1]` буюу өгсөн argument-ийг "************" той жишсэн байна. Хэрвээ таарж байвал тэрийгээ хэвлэж байна.
Анх харахад "\*\*\*\*\*\*\*\*\*\*\*\*" гээд оруулахад болох юм шиг харагдаж байна. Гэхдээ decompiler нь variable ийг const утга гэж андуураад шууд ингэж хэвлэсэн тул болохгүй. "\*\*\*\*\*\*\*\*\*\*\*\*" нь яг үнэндээ variable.
Runtime үед буюу `hidden_func()` ийг дуудах үед энэ variable нь өөрчлөгдсөн байх нь.
Debugger-аа асаагаад program-аа ажилуулаад яг `hidden_func()` ажилласны дараа breakpoint тавиад variable-ийн утгыг шалгаж үзье.
Хэрвээ `strcmp` таарвал манай program угаасаа өөрөө энэ утгаа хэвлээд өгж байгаа болохоор зүгээр `hidden_func()`, `printf("oyusec{%s}\n", "************")` хоёрыг ажилуулахад л хангалттай.
Debugger-aa ажилуулаад breakpoint уудаа тавья.
```bash
$ gdb chall
(gdb) disassemble main
```
Эхний if (debugger эсэхийг шалгах if)
```asm
0x00001ec3 <+52>: test eax,eax
0x00001ec5 <+54>: jns 0x1ee3 <main+84>
```
Хоёрдох if (strcmp)
```asm
0x00001f19 <+138>: call 0x10a0 <strcmp@plt>
0x00001f1e <+143>: add esp,0x10
0x00001f21 <+146>: test eax,eax
0x00001f23 <+148>: jne 0x1f52 <main+195>
```
Яг if буюу jns, jne болгоны өмнөх test-ийн утгыг өөрчлөхөд if-ийг давчихна. test болгон дээр breakpoint тавья.
```bash
(gdb) break *main+52
(gdb) break *main+146
```
Одоо програмаа ажилуулья. Argument шаардлагатай тул ямар ч хамаагүй argument өгье.
```bash
(gdb) run 123
```
Breakpoint дээр очоод test ийн утгыг буюу eax ийн утгыг 0 болгоод програмаа үргэлжлүүлж ажилуулна. 2 breakpoint дээр адилхан.
```bash
(gdb) set $eax=0
(gdb) continue
```
Хэрвээ яг дагаж хийсэн бол printf дээр очих ёстой.
```bash
(gdb) break *main+52
Breakpoint 1 at 0x1ec3
(gdb) break *main+146
Breakpoint 2 at 0x1f21
(gdb) run 123
Starting program: ./chall 123
Breakpoint 1, 0x56556ec3 in main ()
(gdb) set $eax=0
(gdb) continue
Continuing.
Breakpoint 2, 0x56556f21 in main ()
(gdb) set $eax=0
(gdb) continue
Continuing.
https://youtu.be/43TmnIaL3n4
oyusec{OopC_M!CTAK3}
[Inferior 1 (process 101) exited normally]
(gdb)
```
FLAG: oyusec{OopC_M!CTAK3}