Rating: 5.0

For a better view check our [githubpage](https://bsempir0x65.github.io/CTF_Writeups/Decompetition_CTF_2022/#baby_c) or [github](https://github.com/bsempir0x65/CTF_Writeups/tree/main/Decompetition_CTF_2022#baby_c) out
# Baby_c

```assembly
; This is the disassembly you're trying to reproduce.
; It uses Intel syntax (mov dst, src).

main:
endbr64
push rbp
mov rbp, rsp
push rbx
sub rsp, 0x18
mov [rbp-0x15], 1
block1:
mov rax, [stdin]
mov rdi, rax
call [email protected]
mov [rbp-0x14], eax
cmp [rbp-0x14], -1
je block7
block2:
call [email protected]
mov rax, [rax]
mov edx, [rbp-0x14]
movsxd rdx, edx
add rdx, rdx
add rax, rdx
movzx eax, [rax]
movzx eax, ax
and eax, 0x2000
test eax, eax
je block4
block3:
mov rdx, [stdout]
mov eax, [rbp-0x14]
mov rsi, rdx
mov edi, eax
call [email protected]
mov [rbp-0x15], 1
jmp block1
block4:
cmp [rbp-0x15], 0
je block6
block5:
mov rbx, [stdout]
mov eax, [rbp-0x14]
mov edi, eax
call [email protected]
mov rsi, rbx
mov edi, eax
call [email protected]
mov [rbp-0x15], 0
jmp block1
block6:
mov rbx, [stdout]
mov eax, [rbp-0x14]
mov edi, eax
call [email protected]
mov rsi, rbx
mov edi, eax
call [email protected]
jmp block1
block7:
mov eax, 0
add rsp, 0x18
pop rbx
pop rbp
ret
```

We started with the probably "easy" C challenge base on the name. Our plan was to

- [ ] Figure out what the binary does
- [ ] Figure out what the different assemble statements would be in conjunction to the behaviour do
- [ ] Figure out how to programm in C

Based on the tip of the maker we uplouded the binary to [binary ninja](https://cloud.binary.ninja) and realized why to stop there. So we went ahead and also used [ghidra](https://ghidra-sre.org/) and [ida](https://hex-rays.com/ida-free/). Which showed us already interesting outputs.

![Ghidra](https://raw.githubusercontent.com/bsempir0x65/CTF_Writeups/main/Decompetition_CTF_2022/img/baby_c_ghidra.png)

![Binary Ninja](https://raw.githubusercontent.com/bsempir0x65/CTF_Writeups/main/Decompetition_CTF_2022/img/baby_c_ninja.png)

![IDA](https://raw.githubusercontent.com/bsempir0x65/CTF_Writeups/main/Decompetition_CTF_2022/img/baby_c_ida.png)

As you can see we have slightly 3 different versions when we use the decompiler of each tool. You know what they say more tools = more fun.
But back to our plan what does the programm do ?
Based on the outputs we have at the start a variable which is set to 1 and an endless loop until the the break signal is sent to the binary, we think. Next observation is that we have a check on \_\_ctype_b_loc() with the value 0x2000 and if that is true it writes out the input it took to stdout or the console. If that is false depending on the first variable it either uses toupper on the input or tolower and set the original variable to 0.
Cause we were not sure if we should uses imports or not, cause they were already given as the starter code, we decided to use the ida output as base cause it did not need any additional imports:
```C
#include <ctype.h>
#include <stdio.h>
int __cdecl main(int argc, const char **argv, const char **envp)
{
FILE *v3; // rbx
int v4; // eax
int v5; // eax
char v7; // [rsp+Bh] [rbp-15h]
int c; // [rsp+Ch] [rbp-14h]

v7 = 1; // counter variable
while ( 1 )
{
c = getc(stdin);
if ( c == -1 )
break;
if ( ((*__ctype_b_loc())[c] & 0x2000) != 0 ) //no clue what that is
{
putc(c, _bss_start); // based on google search and the other decompiler _bss_start in this case == stdout
v7 = 1;
}
else
{
v3 = _bss_start;
if ( v7 )
{
v4 = toupper(c);
putc(v4, v3);
v7 = 0;
}
else
{
v5 = tolower(c);
putc(v5, v3);
}
}
}
return 0;
}
```
So after that we were sure its not malicious code so we also just ran the code in our VM and did a little black box testing. Cause some parts were still unclear for us.
After that we saw that whatever input we give if the first character is from an alphabet and its lower case the output would have an upper case and all other characters would be just printed out and if its from an alphabet it would be lower case.
So for example:
```console
└─$ ./baby-c
hello
Hello
WORLD
World
123bs
123bs
bs123
Bs123
empir0x65
Empir0x65

```
**Disclaimer: Never execute something you don't know or trust. We are usually just stupid and execute everything from CTFs**

- [X] Figure out what the binary does

We were now confident that we know what the programm does so lets dive in and see what we can achive with the nice outputs our dicompilers.
The first thing we did was some clean up of the original code to make it more readable for us, with some comments for you:
```C
#include <ctype.h>
#include <stdio.h>
int main() //int __cdecl main(int argc, const char **argv, const char **envp) no clue why it was there but we don't need any input to start the programm
{
// FILE *v3; // rbx again no clue why its heres based on the ghidra output for the decompiler the stdout stream is some kind of bit stream which can be declared this way in C we think
// int v4; // eax not used after clean up
// int v5; // eax not used after clean up
char runtime_counter; // char v7; // [rsp+Bh] [rbp-15h] renamed to understand the code better
int input_output; // int c; // [rsp+Ch] [rbp-14h] same here

runtime_counter = 1; // counter variable
while ( 1 )
{
input_output = getc(stdin);
if ( input_output == -1 )
break;
if ( isalpha(input_output) == 0 ) // based on our understanding this would be the check for the character of the input if its part of an alphabet
{
putc(input_output, stdout); // _bss_start replaced with stdout
runtime_counter = 1;
}
else
{
if ( runtime_counter )
{
putc(toupper(input_output), stdout); // made it a one liner to kick out v4 and v5
runtime_counter = 0;
}
else
{
putc(tolower(input_output), stdout); // made it a one liner to kick out v4 and v5
}
}
}
return 0;
}
```
With this code we were already quite near to the searched original code or one of its variations. Only the isalpha check was wrong. Instead of a JNE instruction we had a JE. Also we relaized that our code always make the first character of the input uppercase regardless of its position.
So probably ((*__ctype_b_loc())[c] & 0x2000) != 0 is the culprit. Based on some googling we found out that
* 0x2000 is a check if the char is big or small == 0x2000 2 == is a alphabet char and any of the 0 are for upper 1 would be lower [stackoverflow](https://stackoverflow.com/questions/37702434/ctype-b-loc-what-is-its-purpose)
* != 0 check if true or false 0 means false [stackoverflow](https://stackoverflow.com/questions/14267081/difference-between-je-jne-and-jz-jnz)
Not sure if the first observations is right or wrong but it make sense that it is a lookup on a given list. And based on the second finding and this nice instructions manual [intel](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html) we found on page 1000 whatever that JE and JNE in this context means that we would need a check if something is not equal instead of if something is equal.

- [X] Figure out what the different assemble statements would be in conjunction to the behaviour do

We did it Jonny.

So for testing we did exchanged the isalpha with isdigit but it check 800 instead of 2000 of that list. Until now we have no clue what (*__ctype_b_loc())[c] & 0x2000) was originally the right function but when we just use this we have a 100% Solution:
```C
#include <ctype.h>
#include <stdio.h>

int main() {
// glhf
char runtime_counter; // [rsp+Bh] [rbp-15h]
int input_output; // [rsp+Ch] [rbp-14h]

runtime_counter = 1;
while ( 1 )
{
input_output = getc(stdin);
if ( input_output == -1 )
break;
if ( ((*__ctype_b_loc())[input_output] & 0x2000) != 0 ) //isalpha(input_output) == 0
{
putc(input_output, stdout);
runtime_counter = 1;
}
else
{
if ( runtime_counter )
{
putc(toupper(input_output), stdout);
runtime_counter = 0;
}
else
{
putc(tolower(input_output), stdout);
}
}
}
return 0;
}
```
Also we saw that with that implementation it also worked for us if the second character is from an alphabet it would not be made to upper case. So no clue what is difference but you cant argue with that

![Result](https://raw.githubusercontent.com/bsempir0x65/CTF_Writeups/main/Decompetition_CTF_2022/img/baby_c_result.png)

We did not managed to do the last point on the list

- [ ] Figure out how to programm in C

But at least we got something which was more than we expected and with this little story we might help a student to understand the pleps a bit better.

Original writeup (https://bsempir0x65.github.io/CTF_Writeups/Decompetition_CTF_2022/#baby_c).