Capture The Flag (CTF) Competition organize by HTsP
CRYPTOGRAPHY
Scrambled Carol
We got two files which are output.txt and the python script
The output looks like this
3b180e0b05d71802070d0ed31918.....
I tried to play with the script and input only a and got this as output
After the event I tried to read @Hong5489 writeup which he is a very good CTF player >.<. I tried to bruteforce random character mapping and found out one that looks like a sentence but with random letters.
It starts with spaces so how about we try create a list with spaces in front and shuffle after that.
import string,randomfrom collections import Counter, OrderedDict#Read outputoutput =open("output.txt","r").read().decode('hex')#Get ASCii Letterstemp_alpha =list(string.ascii_uppercase)#Guessing TimewhileTrue: random.shuffle(temp_alpha) alpha = [" "] + temp_alpha#Get Distinct Letters & Frequency freq =Counter(output)#Sorts and get the frequency sorts =sorted(freq.items(), key=lambdai: i[1], reverse=True)#Mapping each with alphabet mapping ={}for i,text inenumerate(sorts):if i <27: mapping[text[0]]= alpha[i]#If in mapping get the text flag =""for t in output:if t in mapping.keys(): flag += mapping[t]#If "flag" found in text printif ("flag"in flag.lower()):print("Alphabets : ",alpha)print(flag.lower())
Get a few results and tried with quipquip and manage to get the flag.
FLAG => xmaswasneverasgoodasitisthisyear
FORENSIC
Conversation
We are given one logs.pcapng file and when I encounter with pcap I will try to strings with a larger length specify and try looks for the flag format or = symbol which could be it encoded with BASE64 .
stringslogs.pcapng-n50|grep=
This give us one result like this
Let's decode the BASE64 and we got the flag!
MISC
Complaint
This challenge will accept an input and it will redirect to /dev/null. We can imagine it looks like this
INPUT>/dev/nulll
So one idea i got is to append bash before the input so that we can get shell first instead of redirect to /dev/null . Thus we will get a shell using commands below.
bash;bash;
And once we get the shell just use base64 to encode and decode the flag.txt because there is no strings or cat . We got the flag!
Whisper's of Ascalon
Thanks to one of my teammate @AsylumxUhsylum We are given one image.png
He manage to reverse search this image and found out that this is from Guild Wars 2 . He found this!
Thus we can decode it and will get the flag!
X-MAS{GW2MYFAVORITEGAME}
PROGRAMMING
Biggest Lowest
This challenge credits to my teammate @Kaitorque who manage to solve this. This one is a simple challenge where we will get 50 test number and it will give us k1 and k2 which we need to sort the array and input ascending;descending with the amount specify in k1 and k2.
Here is the full flag.py
from pwn import*import rer =remote("challs.xmas.htsp.ro", 6051)for x inrange(50): t = r.recvuntil("array = ") t = r.recvline().decode('UTF-8').rstrip()print(t) t = re.sub(r'[^\w\s]', '', t) arr =list(map(int, t.split(' ')))print("Array: ", arr) t = r.recvuntil("k1 = ") k1 =int(r.recvline().decode('UTF-8').rstrip())print("K1: ", k1) t = r.recvuntil("k2 = ") k2 =int(r.recvline().decode('UTF-8').rstrip())print("K2: ", k2) arr.sort()print("Sorted Array: ", arr) inp =', '.join(map(str, arr[:k1]))+"; "+', '.join(map(str, arr[:-k2-1:-1]))print(inp) r.sendline(inp)t = r.recvuntil("}").decode('UTF-8').rstrip()print(t)
Thus we will get the flag!
Least Greatest
This one me and @Kaitorque struggle on getting the code run quickly. We have try using a lot of ways but the finally manage to make it fast. Here is reference for this challenge
Reminder if you encounter with some sort of problem when do division just try
Try a//b if a/b isnot working
Here is flag.py
from pwn import*deftotalPrimeFactors(n): # To keep track of count count =0; # 2s that divide n if ((n %2) ==0): count +=1; while ((n %2) ==0): n //=2; # n must be odd at this point. # So we can skip one element # (Note i = i +2) i =3; while (i * i <= n):# i divides n if ((n % i) ==0): count +=1; while ((n % i) ==0): n //= i; i +=2; # This condition is to handle the # case when n is a prime number # greater than 2 if (n >2): count +=1; return count;defcountPairs(G,L): if (L % G !=0):return0 div =int(L // G)print("Division: ", div)return (1<<totalPrimeFactors(div))defmain():for x inrange(100):print("Question: ", (x+1)) t = r.recvuntil("gcd(x, y) = ") gcd_n =int(r.recvline().decode('UTF-8').rstrip())print("GCD: ", gcd_n) t = r.recvuntil("lcm(x, y) = ") lcm_n=int(r.recvline().decode('UTF-8').rstrip())print("LCM: ", lcm_n) inp =countPairs(gcd_n, lcm_n) r.sendline(str(inp))print("Pair: ", inp) t = r.recvuntil("!").decode('UTF-8').rstrip()print(t)if t =="That is not the correct answer!":return t = r.recvuntil("}").decode('UTF-8').rstrip()print(t)r =remote("challs.xmas.htsp.ro", 6050)t = r.recvuntil("90 seconds.")main()
Thus we get the flag!
WEB EXPLOITATION
Santa's Consolation
We are given one code in the link they give.
Let's try run the code.
It's a Javascript Challenge and need to identify the correct parameter for win(). If we try to enter something in win("something") . We will get the output like below.
I tried to understand their code by reverse engineering and here is what I can get.
functioncheck(s) {constk="<BASE64>";//Base64 Decode => Reverseconstk1=atob(k).split('').reverse().join('');console.log(bobify(s));//Compare bobify(input) with k1returnbobify(s) === k1;}functionbobify(s) {//Cannot Have a t e i z in inputif (~s.indexOf('a') ||~s.indexOf('t') ||~s.indexOf('e') ||~s.indexOf('i') ||~s.indexOf('z'))return"[REDACTED]";//Replace 4 with a//Replace 3 with e//Replace 1 with i//Replace 7 with t//Replace _ with z const s1 = s.replace(/4/g, 'a').replace(/3/g, 'e').replace(/1/g, 'i').replace(/7/g, 't').replace(/_/g, 'z').split('').join('[]');
//Input wil be join with [] => b[]j[]l[]l[]consts2=encodeURI(s1).split('').map(c=>c.charCodeAt(0)).join('|');//Convert to ascii(a)+ascii([)+ascii(])+ascii(c)consts3=btoa("D@\xc0\t1\x03\xd3M4"+ s2);return s3;}functionwin(x) {//Check if true return flag else REDACTEDreturncheck(x) ?"X-MAS{"+ x +"}":"[REDACTED]";}
To get the flag we can try reverse the variable k1 that we had.
FROM BASE64 > REVERSE > FROM BASE64 => btoa("D@\xc0\t1\x03\xd3M4" + s2)
Remove that part btoa("D@\xc0\t1\x03\xd3M4")and decode it like below
1. REPLACE "|37|53|" = " "
2. REPLACE "|" = " "
3. REPLACE "BD" = ""
4. REPLACE a = 4
5. REPLACE e = 3
6. REPLACE i = 1
7. REPLACE t = 7
8. REPLACE z = _