# ghost-in-the-system
## Description
```I think my ls is being haunted... the colors are all weird!!! What's that? It's highlighting things?! Where!!?```
### Hints
```Flag is 100 characters long.It starts with rtcp{ and ends with }The first character is w```
```The flag is written in standard leet, the only exceptions are the flag wrapping (rtcp{}) and underscores (_)```
## Walkthrough
First, let's open the provided `ls` binary in IDA. After the initial analysis, check out the `main` function. We see an interesting stack variable: `flg`.
```flg= byte ptr -80h```
This is worth looking into. Highlight `flg` and press `x` to view cross references to `flg`.
![Cross references to `flg`](https://raw.githubusercontent.com/ori0nx3/CTF-Writeups/master/riceteacatpanda/2020/general/ghost-in-the-system/img/xrefs-flg.png)
We see 100 writes and two reads. Interesting. Our first hint told us the flag is 100 characters long. Let's take a closer look at these writes. Double-click on the first xref to end up at address `main+145`.
```main+145                  lea     rax, [rbp+__for_end]main+14C                  mov     rdi, raxmain+14F                  call    __ZNSaIcEC1Ev   ; std::allocator<char>::allocator(void)main+154                  lea     rdx, [rbp+__for_end]main+15B                  lea     rax, [rbp+otxt]main+162                  lea     rsi, aSYvzezqr6x45jx ; "s}yvzezqr_6x45jx2yp4d38qq1mvnsl0u7w32lr"...main+169                  mov     rdi, raxmain+16C                  call    __ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_ ; std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(char const*,std::allocator<char> const&)main+171                  lea     rax, [rbp+__for_end]main+178                  mov     rdi, raxmain+17B                  call    __ZNSaIcED1Ev   ; std::allocator<char>::~allocator()main+180                  lea     rax, [rbp+otxt]main+187                  mov     esi, 1F0hmain+18C                  mov     rdi, raxmain+18F                  call    __ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEm ; std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[](ulong)main+194                  movzx   eax, byte ptr [rax]main+197                  mov     [rbp+flg], almain+19A                  lea     rax, [rbp+otxt]main+1A1                  mov     esi, 192hmain+1A6                  mov     rdi, raxmain+1A9                  call    __ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEm ; std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[](ulong)main+1AE                  movzx   eax, byte ptr [rax]main+1B1                  mov     [rbp+flg+1], almain+1B4                  lea     rax, [rbp+otxt]main+1BB                  mov     esi, 322hmain+1C0                  mov     rdi, raxmain+1C3                  call    __ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEm ; std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[](ulong)main+1C8                  movzx   eax, byte ptr [rax]main+1CB                  mov     [rbp+flg+2], al
; etc...
```
So what is this code doing? It seems like it is first initializing a C++ `std::string` object at `[rbp+otxt]` with the string stored at `aSYvzezqr6x45jx`. If we follow this location in the binary, we will see a long string of seemingly random characters:
![Random character buffer](https://raw.githubusercontent.com/ori0nx3/CTF-Writeups/master/riceteacatpanda/2020/general/ghost-in-the-system/img/random-chars.png)
Then, it begins to make many calls to the `[]` operator of the `std::string` object at `[rbp+otxt]`, with seemingly random offsets, storing each result to an increasing offset from `[ebp+flg]`. So the code effectively becomes something like:
```flg[0] = otxt[496]; // 1f0hflg[1] = otxt[402]; // 192hflg[2] = otxt[802]; // 322h// etc...```
At this point, we could write a script to assemble a flag by pulling the appropriate offset from the "random" text for each index of our flag. An easier way would be to use a decompiler to generate C code, reformat as necessary, and print the assembled flag. These would both, of course, be tedious and time-consuming processes. There is a better way.
Remember the reads to `[rbp+flg]`?
![Reads from `flg`](https://raw.githubusercontent.com/ori0nx3/CTF-Writeups/master/riceteacatpanda/2020/general/ghost-in-the-system/img/xrefs-flg-reads.png)
Let's check out the first one. Double-click on it to jump here:
```main+BB2                  lea     rdx, [rbp+flg]main+BB6                  lea     rax, [rbp+str]main+BBD                  mov     rsi, rdx        ; __rhsmain+BC0                  mov     rdi, rax        ; __lhsmain+BC3                  call    _ZSteqIcSt11char_traitsIcESaIcEEbRKNSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_ ; std::operator==<char,std::char_traits<char>,std::allocator<char>>(std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> const&,char const*)main+BC8                  test    al, almain+BCA                  jz      short loc_1D2F```
Here we see where the assembled "real" flag at `[rbp+flg]` is being compared with a string we've supposedly entered, at `[rbp+str]`. If we jump into a debugger and set a breakpoint at `main+0xbb6`, the "real" flag should conveniently be sitting at an address pointed to by `rdx`. But there's still one small problem: we need to ensure execution actually reaches this block of code.
So let's fire up `gdb`. Set a breakpoint on the `main` function with `b *main`. Run the program with `run`, and we arrive at the beginning of the `main` function.
![Beginning of `main`](https://raw.githubusercontent.com/ori0nx3/CTF-Writeups/master/riceteacatpanda/2020/general/ghost-in-the-system/img/gdb-main.png)
We need to `jump` to the instructions that build the flag, but first we need to ensure that our stack is set up correctly. Using `n`, step through the first few lines of the `main` procedure. Stepping until the `call opendir` is more than enough.
Now, set a breakpoint at the beginning of the code block that builds the flag: `b *main+0x145`. Jump to the same instruction with `jump *main+0x145`. Next, set a breakpoint directly after a pointer to our "real" flag is stored in `rdx`: `b *main+0xbb6`. Now `continue`.
When `gdb` reaches our breakpoint, a pointer to the flag string will be stored in `rdx`. Simply use `x/s $rdx` and our flag will be printed for us!
```> x/s $rdx0x7fffffffe2f0: "rtcp{wh37h3r_1n4n1m473_f16ur35_0r_un4u7h0r1z3d_c0d3_7h3r35_4lw4y5_4_6h057_1n_7h3_5y573m_1056_726_00}UU"```
There are a few extra junk characters printed after the flag. No problem. Simply remove the extra characters and submit.