AIS3 pre-exam Writeup(2021)
===
排名:152
Scoreboard:https://drive.google.com/file/d/1v-5ag_sQdVHTxWPLj-7hM-akwcJ-prdq/view?usp=sharing
Welcome
---
#### Cat Slayer ᶠᵃᵏᵉ | Nekogoroshi
手動爆破
pwd = 2025830455298
flag:AIS3{H1n4m1z4w4_Sh0k0gun}
Misc
---
#### Microcheese
(這題是結束後解出來的)
```python=
if choice == '0':
pile = int(input('which pile do you choose? '))
count = int(input('how many stones do you remove? '))
if not game.make_move(pile, count):
print_error('that is not a valid move!')
continue
elif choice == '1':
game_str = game.save()
digest = hash.hexdigest(game_str.encode())
print('you game has been saved! here is your saved game:')
print(game_str + ':' + digest)
return
elif choice == '2':
break
```
可以發現選擇0,1,2以外的選項就可以只讓電腦拿走石頭
等到最後我們再把最後一顆石頭拿走就可以拿到flag了
不知道為什麼,我在賽中進到遊戲時第一步選3會出現
```
oops i died
```
然後程式就停止了
賽後發現要先正常的走一步(選0) 之後選3就可以正常跳過了

可以發現 程式印出了
```
you removed 1 stones from pile 0
```
但pile 0的石頭數量卻沒有減少
反覆操作 當只剩一堆有石頭時 出手把石頭拿完就贏了

由於印出flag的函數是作者寫的 因此在本機無法印出flag
#### blind
(結束後看writeup解出)
```c=
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/syscall.h>
int syscall_black_list[] = {};
void make_a_syscall()
{
unsigned long long rax, rdi, rsi, rdx;
scanf("%llu %llu %llu %llu", &rax, &rdi, &rsi, &rdx);
syscall(rax, rdi, rsi, rdx);
}
int main()
{
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
puts("You can call a system call, then I will open the flag for you.");
puts("Input: [rax] [rdi] [rsi] [rdx]");
close(1);
make_a_syscall();
int fd = open("flag", O_RDONLY);
char flag[0x100];
size_t flag_len = read(fd, flag, 0xff);
write(1, flag, flag_len);
return 0;
}
```
可以看到他用close(1); 把stdout關掉 導致flag印不出來
只要想辦法把stdout改成1就可以拿到flag
可以透過dup2(2,1)把stderr的fd(File Descriptor)複製給stdout
讓它的值變成1就可以拿到flag
對照syscall table可知輸入33 2 1 0可以拿到flag
參考資料
https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md
https://stackoverflow.com/a/58890557
Crypto
---
#### microchip
明文和密文的長度一樣
每4個字一組 彼此互不影響
又知key[i]<96
flag前四位是AIS3
所以可以算key
然後逆著解回去就好了
程式碼如下
```python=
cipher = "&sJ=`A*;HZdoD>'i&sJ=D-i#U>fYuy'yuyfyuG)<"
key = [ 69 , 42 , 87, 10 ]
token=0
idx=0
flag=""
for i in cipher:
token=int(token)
idx=int(idx)
token = idx % 4
i = ord( i ) - 32
i=int(i)
if( i - key[token] < 0 ):
i+=96
i-=key[token]
i += 32
flag = flag + chr(i)
idx += 1
print(flag)
```
flag: AIS3{w31c0me_t0_AIS3_cryptoO0O0o0Ooo0}
Reverse
---
#### piano
反組譯piano.dll後拿到(出來的程式碼大約200多行 這邊只列出關鍵的部分)
```
private bool isValid()
{
List<int> list = new List<int>
{
14, 17, 20, 21, 22, 21, 19, 18, 12, 6,
11, 16, 15, 14
};
List<int> list2 = new List<int>
{
0, -3, 0, -1, 0, 1, 1, 0, 6, 0,
-5, 0, 1, 0
};
for (int i = 0; i < 14; i++)
{
if (notes[i] + notes[(i + 1) % 14] != list[i])
{
return false;
}
if (notes[i] - notes[(i + 1) % 14] != list2[i])
{
return false;
}
}
return true;
}
```
解個方程式後會拿到幾個數字 打開piano.exe後用正確的順序彈就過了
flag: AIS3{7wink1e_tw1nkl3_l1ttl3_574r_1n_C_5h4rp}
#### 🐰 Peekora 🥒
結束後看writeup解出
用
```
python3 -m pickletools -a flag_checker.pkl
```
可以disassemble題目給的.pkl檔案
MARK 做標記
GET 把東西push到stack上
REDUCE 很像是搞成一個function
PUT 從stack上拿東西 但不會pop
然後硬讀
```
MARK Push markobject onto the stack.
708: g GET 1 Read an object from the memo and push it on the stack.
711: ( MARK Push markobject onto the stack.
712: g GET 4 Read an object from the memo and push it on the stack.
715: S STRING '__eq__' Push a Python string object.
725: t TUPLE (MARK at 711) Build a tuple out of the topmost stack slice, after markobject.
726: R REDUCE Push an object built from a callable and an argument tuple.
727: ( MARK Push markobject onto the stack.
728: g GET 1 Read an object from the memo and push it on the stack.
731: ( MARK Push markobject onto the stack.
732: g GET 0 Read an object from the memo and push it on the stack.
735: S STRING '__getitem__' Push a Python string object.
750: t TUPLE (MARK at 731) Build a tuple out of the topmost stack slice, after markobject.
751: R REDUCE Push an object built from a callable and an argument tuple.
752: ( MARK Push markobject onto the stack.
753: I INT 13 Push an integer or bool.
757: t TUPLE (MARK at 752) Build a tuple out of the topmost stack slice, after markobject.
758: R REDUCE Push an object built from a callable and an argument tuple.
759: t TUPLE (MARK at 727) Build a tuple out of the topmost stack slice, after markobject.
760: R REDUCE Push an object built from a callable and an argument tuple.
761: t TUPLE (MARK at 707) Build a tuple out of the topmost stack slice, after markobject.
762: R REDUCE
//memo4 == imput[1] == input[13]
```
```
MARK Push markobject onto the stack.
523: g GET 1 Read an object from the memo and push it on the stack.
526: ( MARK Push markobject onto the stack.
527: g GET 1 Read an object from the memo and push it on the stack.
530: ( MARK Push markobject onto the stack.
531: g GET 0 Read an object from the memo and push it on the stack.
534: S STRING '__getitem__' Push a Python string object.
549: t TUPLE (MARK at 530) Build a tuple out of the topmost stack slice, after markobject.
550: R REDUCE Push an object built from a callable and an argument tuple.
551: ( MARK Push markobject onto the stack.
552: I INT 5 Push an integer or bool.
555: t TUPLE (MARK at 551) Build a tuple out of the topmost stack slice, after markobject.
556: R REDUCE Push an object built from a callable and an argument tuple.
557: S STRING '__eq__' Push a Python string object.
567: t TUPLE (MARK at 526) Build a tuple out of the topmost stack slice, after markobject.
568: R REDUCE Push an object built from a callable and an argument tuple.
569: ( MARK Push markobject onto the stack.
570: V UNICODE 'd' Push a Python Unicode string object.
573: t TUPLE (MARK at 569) Build a tuple out of the topmost stack slice, after markobject.
574: R REDUCE Push an object built from a callable and an argument tuple.
575: t TUPLE (MARK at 522) Build a tuple out of the topmost stack slice, after markobject.
576: R REDUCE Push an object built from a callable and an argument tuple.
577: ( MARK Push markobject onto the stack.
578: t TUPLE (MARK at 577) Build a tuple out of the topmost stack slice, after markobject.
579: R REDUCE
//input[5] == 'd'
```
讀完得到flag
AIS3{dAmwjzphIj}