├── Crypto ├── Feedback │ ├── Feedback.pdf │ ├── solution.mp4 │ └── solution.py └── Sliding Windows │ ├── Sliding Windows.pdf │ ├── soln-script.mp4 │ └── solve.py ├── Misc ├── Alpha Do You Copy │ └── Alpha Do You Copy.pdf └── Easy-Peasy │ └── Easy-Peasy.pdf ├── Osint ├── Coin-B │ └── Coin-B.pdf └── Wactch │ └── Watch.pdf ├── README.md ├── Reverse ├── Rookie │ └── Rookie.pdf └── World’s Strongest Cipher │ └── World’s Strongest Cipher.pdf ├── WEB ├── Command Executor │ └── Command Executor.pdf └── Loser Agent │ └── Loser Agent.pdf └── logo.png /Crypto/Feedback/Feedback.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Crypto/Feedback/Feedback.pdf -------------------------------------------------------------------------------- /Crypto/Feedback/solution.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Crypto/Feedback/solution.mp4 -------------------------------------------------------------------------------- /Crypto/Feedback/solution.py: -------------------------------------------------------------------------------- 1 | from Crypto import Random 2 | from Crypto.Cipher import AES 3 | import base64 4 | import binascii 5 | import socket 6 | import sys 7 | import time 8 | 9 | HOST = '127.0.0.1' 10 | PORT = 4444 11 | 12 | 13 | def xor(x1, x2): 14 | return bytearray(a^b for a, b in zip(*map(bytearray, [x1, x2]))) 15 | 16 | 17 | flag_enc = binascii.unhexlify("b398bffadbdad3f1d2f2ff75f55babf7d775f9eb8988c97d70bb2e4db447f746d52c88a6681ab225fbafcaa480e0db88f8709828263ad3af83ba50d6348b49900e6c7db4cfedf7ff701c61743cacf587") 18 | flag='' 19 | 20 | 21 | red="\033[1;31;40m" 22 | green = "\033[1;32;40m" 23 | gray = "\033[1;30;40m" 24 | normal = "\033[0;37;40m" 25 | 26 | with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 27 | s.connect((HOST, PORT)) 28 | 29 | data = s.recv(1024) 30 | for i in range(0,len(flag_enc)): 31 | print(">>> ", end='') 32 | pld = flag + '\x00' + "\r\n" 33 | s.send(pld.encode()) 34 | print(green + pld + normal) 35 | 36 | time.sleep(0.1) 37 | r = s.recv(1024) 38 | r = r.decode().split('\n') 39 | print(gray + r[0] + normal) 40 | c = binascii.unhexlify(r[0]) 41 | flag+=chr(c[i]^flag_enc[i]) 42 | sys.stdout.write("\033[F\033[F\033[F") 43 | 44 | print("\n\n") 45 | 46 | -------------------------------------------------------------------------------- /Crypto/Sliding Windows/Sliding Windows.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Crypto/Sliding Windows/Sliding Windows.pdf -------------------------------------------------------------------------------- /Crypto/Sliding Windows/soln-script.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Crypto/Sliding Windows/soln-script.mp4 -------------------------------------------------------------------------------- /Crypto/Sliding Windows/solve.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import base64 3 | import binascii 4 | import math 5 | import string 6 | import sys 7 | import time 8 | import re 9 | 10 | 11 | 12 | #flag alphabet 13 | flag_alphabet = string.digits + string.ascii_uppercase + string.ascii_lowercase + '{}_' 14 | 15 | url = "http://localhost:8080/app/resetlink" 16 | data = {"email":"a"} 17 | 18 | #for debugging/better understanding of the script 19 | verbose = False 20 | if(len(sys.argv)==2 and sys.argv[1]=='v'): 21 | verbose = 1 22 | if(len(sys.argv)==2 and sys.argv[1]=='vv'): 23 | verbose = 2 24 | if(len(sys.argv)==2 and sys.argv[1]=='vvv'): 25 | verbose = 3 26 | 27 | request_counter = 0 28 | def getResetToken(msg): 29 | global request_counter 30 | request_counter+=1 31 | '''Get password reset token for the given string''' 32 | data["email"]=msg 33 | r = requests.post(url,data=data) 34 | #time.sleep(0.02) 35 | return base64.b64decode(r.text) 36 | 37 | def details(token): 38 | ''' 39 | Token length, number of blocks, and token itself 40 | Returns number of AES blocks in token 41 | ''' 42 | print(f"len: {len(token)}", end=', ') 43 | print(f"blocks: {math.ceil(len(token)/16)}") 44 | if verbose: print(f"token:\n{token}") 45 | return len(token)//16+1 46 | 47 | def blockify(st): 48 | 'Split a string per 16 characters, return a list' 49 | return [st[i:i+16] for i in range(0, len(st), 16)] 50 | 51 | def blockifyPrint(blocks,delim, binasci=False, end='\n'): 52 | '''Print blockify result, delimiting each block with delim parameter 53 | convert to hex representation if binasci=True 54 | ''' 55 | for bl in blocks: 56 | if(binasci): 57 | print(binascii.hexlify(bl), end=delim) 58 | else: 59 | print(bl, end=delim) 60 | 61 | print('', end=end) 62 | 63 | 64 | 65 | #terminal color codes 66 | red="\033[1;31;40m" 67 | green = "\033[1;32;40m" 68 | gray = "\033[1;30;40m" 69 | normal = "\033[0;37;40m" 70 | 71 | #blockify print, but padding is red, flag is green, and unknown is gray 72 | def blockifyColored(blocks): 73 | bucket = '' 74 | for bl in blocks: 75 | bucket = bucket + bl + " " 76 | 77 | bucket = re.sub('((A| ){2,128} ?)', (red + r"\1" + green), bucket) 78 | bucket = re.sub('((\?| ){2,128})', (gray + r"\1" + normal), bucket) 79 | print(bucket + " ", end='\r') 80 | 81 | 82 | 83 | flaglen = 0 84 | lastBlockCount=0 85 | #Need to send 15 requests at most to calculate the flag length 86 | for i in range(15): 87 | 88 | #send only pad 89 | token = getResetToken('A'*i) 90 | print(f"i: {i}", end=', ') 91 | newBlockCount = details(token) 92 | 93 | #if block count changed for this pad, we've hit (pad+flag)%16==1 94 | if(lastBlockCount and lastBlockCount!=newBlockCount): 95 | print(f"Block size change at {i} from {lastBlockCount} to {newBlockCount}") 96 | flaglen = (lastBlockCount-1)*16-i 97 | print(f"Flag length is {flaglen}.") 98 | break 99 | lastBlockCount=newBlockCount 100 | 101 | #minimum number of blocks we need to pad to left to get complete flag 102 | slideBlockCount=math.ceil(flaglen/16) 103 | 104 | #iterator for the left-pad 105 | slideLength=slideBlockCount*16 -1 106 | print(f"Need {slideBlockCount} blocks and {slideLength} characters to have space for sliding.") 107 | print("Starting right to left sliding window attack.") 108 | 109 | 110 | 111 | flag = '' 112 | 113 | #remove a character from left pad each iteration, brute forcing the flag one character at a time 114 | #stop when flaglen is exhausted 115 | for i in range(flaglen): 116 | 117 | #get token for the base request of this iteration, last character is unknown. 118 | #we will need to match this ciphertext when brute forcing 119 | leftpad = 'A'*(slideLength-i) 120 | token = getResetToken(leftpad) 121 | 122 | #currentSignificantBlockIndex is the index of first block that will matter. 123 | #Blocks where no change has happened will always match 124 | blocks = blockify(token) 125 | currentSignificantBlockIndex = ((slideLength-1)//16) 126 | 127 | #debugging - show blocks 128 | if verbose>=2: 129 | print("\n\n\n\n") 130 | print("New block map") 131 | blockifyPrint(blocks,'\n', 1) 132 | 133 | #will only compare block at SBI 134 | significantBlock = blocks[currentSignificantBlockIndex] 135 | 136 | #print the state, show left pad + found flag + unknown in block format 137 | pld = leftpad+flag+(flaglen-i)*'?' 138 | #blockifyPrint(blockify(pld),' ', '') 139 | if verbose>=2: 140 | print(f"Significant block is: {binascii.hexlify(significantBlock)}") 141 | print(f"Brute forcing last character to get letter") 142 | print("\n") 143 | 144 | 145 | 146 | #brute force last character of significant block from flag_alphabet 147 | for symbol in flag_alphabet: 148 | #brute force payload 149 | brutepld = 'A'*(slideLength-i) + flag + symbol 150 | 151 | #print current payload in blockified format 152 | if verbose>=2: blockifyColored(blockify(brutepld + '?'*(flaglen-i))) 153 | 154 | #get reset token and split it in blocks 155 | brutetoken = getResetToken(brutepld) 156 | bruteblocks = blockify(brutetoken) 157 | if verbose>=3: print(f"\nCipher Blocks: (looking for {currentSignificantBlockIndex+1}:{binascii.hexlify(significantBlock)})") 158 | if verbose>=3: blockifyPrint(bruteblocks,'\n', 1) 159 | 160 | #block to compare 161 | currentSignificantBlock=bruteblocks[currentSignificantBlockIndex] 162 | 163 | if verbose>=3: print(f"{symbol}:{binascii.hexlify(currentSignificantBlock)}") 164 | 165 | #found unknown character 166 | if(currentSignificantBlock==significantBlock): 167 | if verbose>=2: print(f"Match found: {symbol}{' '*(slideLength+flaglen)}") 168 | if verbose==1: 169 | blockifyColored(blockify(brutepld + (flaglen-i)*'?')) 170 | print() 171 | else: 172 | blockifyColored(blockify(brutepld + (flaglen-i)*'?')) 173 | #blockifyPrint(blockify(brutepld), ' ', 0, '\r\r') 174 | flag+=symbol 175 | break 176 | 177 | print("\033[0;37;40m ") 178 | print(f"Total requests: {request_counter}") 179 | print(f"flag: {green}{flag}{normal}") 180 | -------------------------------------------------------------------------------- /Misc/Alpha Do You Copy/Alpha Do You Copy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Misc/Alpha Do You Copy/Alpha Do You Copy.pdf -------------------------------------------------------------------------------- /Misc/Easy-Peasy/Easy-Peasy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Misc/Easy-Peasy/Easy-Peasy.pdf -------------------------------------------------------------------------------- /Osint/Coin-B/Coin-B.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Osint/Coin-B/Coin-B.pdf -------------------------------------------------------------------------------- /Osint/Wactch/Watch.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Osint/Wactch/Watch.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # stmctf20 2 | 30 - 31 Ekim 2020 tarihlerinde gerçekleştirilen STMCTF'20 yarışmasında sorulan sorulara ait çözümler. 3 | 4 | Final Result : https://ctf-scoreboard.yeni.digital/ 5 | 6 | 7 | ![Preview](https://github.com/stmctf/stmctf20/blob/main/logo.png) 8 | -------------------------------------------------------------------------------- /Reverse/Rookie/Rookie.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Reverse/Rookie/Rookie.pdf -------------------------------------------------------------------------------- /Reverse/World’s Strongest Cipher/World’s Strongest Cipher.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/Reverse/World’s Strongest Cipher/World’s Strongest Cipher.pdf -------------------------------------------------------------------------------- /WEB/Command Executor/Command Executor.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/WEB/Command Executor/Command Executor.pdf -------------------------------------------------------------------------------- /WEB/Loser Agent/Loser Agent.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/WEB/Loser Agent/Loser Agent.pdf -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stmctf/stmctf20/263ed6cb9b15580177a362799a40e997f61685d1/logo.png --------------------------------------------------------------------------------