Skip to content

Commit e680a99

Browse files
authored
Merge pull request #35 from RIvance/master
Add: rbtree's writeups
2 parents ffdb73c + 422dd88 commit e680a99

File tree

10 files changed

+423
-1
lines changed

10 files changed

+423
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
| [Intary](players/Intary/README.md) | 总排名第 242 名 | 签到, 进制十六——参上, 去吧!追寻自由的电波, 猫咪问答 Pro Max, 卖瓜, 透明的文件, 图之上的信息 |
6868
| [Frankss](players/Frankss/README.md) | 总排名第11名 | 进制十六—参上 超OI的writeup模拟器 |
6969
| [B1ue1nWh1te](players/B1ue1nWh1te) | 总排名第74名 | 签到、进制十六——参上、去吧!追寻自由的电波、猫咪问答 Pro Max、卖瓜、透明的文件、旅行照片、FLAG 助力大红包、Amnesia(轻度失忆)、图之上的信息、Easy RSA、赛博厨房(Level 0、Level 1)、链上预言家(预言已知)、马赛克、minecRaft |
70-
| [poscat](players/poscat) | | p😭q, Easy RSA, 去吧!追寻自由的电波
70+
| [poscat](players/poscat) | | p😭q, Easy RSA, 去吧!追寻自由的电波|
7171
| [rvfg](players/rvfg/) | 总排名第 23 名 | Amnesia/记忆清除 |
7272
| [Kotoki1337](players/Kotoki1337/) | 总排名 #259 | 签到,进制十六——参上,去吧!追寻自由的电波,猫咪问答 Pro Max,卖瓜,透明的文件,旅行照片,FLAG 助力大红包,图之上的信息 |
7373
| [RickAstley](players/RickAstley/) | #21 图一乐 | FLAG 助力大红包 / Easy RSA / 卷王与野生的 GPA / 链上预言家 / p😭q |
@@ -81,6 +81,7 @@
8181
| [Sora](https://www.sorasky.in/hg2021.sorasky) | 总排名第 102 名 | 签到,进制十六——参上,去吧!追寻自由的电波,猫咪问答 Pro Max,卖瓜,透明的文件,旅行照片,FLAG 助力大红包,Amnesia 轻度失忆,图之上的信息,加密的U盘,Micro World,马赛克 |
8282
| [ThinkingNull](https://awsl.blog/2021/ustc-hack-2021) | | 猫咪问答 Pro Max、旅行照片 |
8383
| [風的影子](players/windshadow/) | 总排名第 32 | 签到题、去吧!追寻自由的电波、猫咪问答、卖瓜、透明的文件、旅行照片、FLAG 助力大红包、图之上的信息、Easy RSA、加密的 U 盘、Micro World、马赛克、minecRaft、p😭q|
84+
| [std::_Rb_tree](players/rbtree) | 总排名第 27 | 透明文件, FLAG 助力大红包, Amnesia, Easy RSA, 助记词, 马赛克, 灯,等灯等灯, Micro World, 阵列恢复带师, minecRaft, p😭q |
8485
| [lethal233](players/Laser丶ppl/) | 总排名第 163 | 签到题、进制十六——参上、去吧!追寻自由的电波、卖瓜、透明的文件、FLAG 助力大红包、图之上的信息、Easy RSA|
8586

8687
## 其他资源

players/rbtree/README.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Hackergame 2021 (by std::_Rb_tree)
2+
3+
<del>某Arch邪教徒 + Jvav程序猿</del>第一次打CTF, rk27挺意外的
4+
5+
一下为吐槽(主要) + 一些废话(主要) + 非正经题解(次要)
6+
7+
## 透明文件
8+
9+
<del>这玩意不就是我前几天瞎搞的[terminal播放器](https://github.com/RIvance/terminal-player)吗, tty看片指日可待了属于是</del>
10+
11+
这题难点在于他最后会把你最后一行信息给抹掉, 所以只要加sleep一点一点打印就好了, 另外就是gnome terminal在刷新的时候没法选择文本, 果断alacritty. [(源码)](src/terminal.py)
12+
13+
![terminal](assets/terminal.png)
14+
15+
16+
17+
## FLAG 助力大红包
18+
19+
20+
21+
emmm....好像已经不是我一个人这么起文件名了
22+
23+
![pdd](assets/pdd.png)
24+
25+
Post时候header里加个`X-Forwarded-For`就好了
26+
27+
28+
29+
## Amnesia
30+
31+
T1很简单, 别开静态字符串就ok. T2总计花了超过10个小时搜资料+读gcc源码也没搞出来 <del>(手动裂开)</del>.
32+
33+
34+
35+
## Easy RSA
36+
37+
先是威尔迅定理推p, 然后在求解q上卡了一下午, 最后没想到其实Google能搜到, 欧拉函数这一步确实要数感很强才能想到.
38+
39+
40+
41+
## 助记词
42+
43+
<del>我怎么觉得题干里这个室友就是当时在学Quarkus的我</del>
44+
45+
这题目的就是发送一个请求, 让后端调用Phrase这个类中的equals函数的机会尽量多. 那哪能用到equals呢??? 他那个HashSet! 这不摆明了告诉你她想让你通过哈希碰撞把她炸成链表吗? (虽然超过8个会成红黑树, 不过卡个9s还是够用了, 何况还是个LinkedHashSet) 但又一想, 不对啊, 他还有个Instance字段呢, 不过, 他同时也有个`Instant.now().truncatedTo(ChronoUnit.SECONDS)`, 点开他的hashCode函数, 会发现:
46+
47+
```java
48+
@Override
49+
public int hashCode() {
50+
return ((int) (seconds ^ (seconds >>> 32))) + 51 * nanos;
51+
}
52+
```
53+
54+
这个东西有意思的地方就在于如果这个时间是整秒的话, 他的`hashCode()`就是1970年1月1日0点到这个时间的秒数.
55+
56+
这时候我们再看:
57+
58+
```java
59+
// Objects.hash
60+
public static int hash(Object... values) {
61+
return Arrays.hashCode(values);
62+
}
63+
64+
// Arrays.hashCode
65+
public static int hashCode(Object a[]) {
66+
if (a == null)
67+
return 0;
68+
69+
int result = 1;
70+
71+
for (Object element : a)
72+
result = 31 * result + (element == null ? 0 : element.hashCode());
73+
74+
return result;
75+
}
76+
```
77+
78+
分析后不难得出, 我们只需要构造一个9个连续的Instant, 用这些Instant分别去构建Phrases, 找到所有哈希值相同并记录其是由哪个Instant构造出来的即可.
79+
80+
[撞Hash源码](src/FindHash.java) <del> Jvav题就应该写Jvav去解</del>
81+
82+
[Post请求的源码](src/fuck_hash_map.ipynb)
83+
84+
为了快点出结果开满线程撞Hash, 于是乎:
85+
86+
![findhash](assets/findhash.png)
87+
88+
89+
90+
## 马赛克
91+
92+
炼丹 -> 放弃
93+
94+
本来想用[pix2pixHD](https://github.com/NVIDIA/pix2pixHD)试一把, 结果发现这玩意在30系卡上问题具多, 直接放弃
95+
96+
<del>有炼出来能用的可以告诉我一声</del>
97+
98+
99+
100+
## 灯,等灯等灯
101+
102+
T1高斯消元, 发现是个模256的环有的元素没有乘法逆元, 于是就寄了...
103+
104+
105+
106+
## Micro World
107+
108+
Arch user表示这题及其不友好 (Linux下反编译总报错, 不管啥版本的py), 为这个和底下那个Qt的逆向题专门卸了俩游戏装Windows虚拟机
109+
110+
111+
112+
## 阵列恢复带师
113+
114+
人家用工具的一会就做出来了, 就我还搁这`hexdump`
115+
116+
Raid0 主要是先分析一开始的分区表找到第一张盘, 在通过结尾的pdf文件在`0x8c0000``0x8e0000`的数据确定磁盘顺序和chunksize.
117+
118+
Raid5 由于有纠错码的存在所以要通过有文本的区域确定纠错码的移动方式, 然后拼接的时候别忘了在后面补一段用于存metadata的区域.
119+
120+
操作部分可以参考[Archwiki](https://wiki.archlinux.org/title/RAID)
121+
122+
123+
124+
## minecRaft
125+
126+
反混淆 + 时刻想着google的存在
127+
128+
[源码](src/mc.js)
129+
130+
131+
132+
## p😭q
133+
134+
先opencv获取gif中数据转成数组, 按他给的源码反着来就行
135+
136+
[源码](src/fourier.py)
137+

players/rbtree/assets/findhash.png

1.33 MB
Loading

players/rbtree/assets/pdd.png

1.43 KB
Loading

players/rbtree/assets/terminal.png

227 KB
Loading

players/rbtree/src/FindHash.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import java.time.Instant;
2+
import java.time.temporal.ChronoUnit;
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Objects;
6+
import java.util.concurrent.ExecutorService;
7+
import java.util.concurrent.LinkedBlockingDeque;
8+
import java.util.concurrent.ThreadPoolExecutor;
9+
import java.util.concurrent.TimeUnit;
10+
11+
public class FindHash {
12+
13+
private static final String[] WORDS = new String[] {"ability", "access", "account", "action", "active", "activity", "addition", "address", "advantage", "advertising", "advice", "affect", "alternative", "amount", "analysis", "animal", "answer", "anything", "apartment", "appearance", "application", "area", "army", "article", "association", "attempt", "attention", "audience", "author", "average", "back", "balance", "ball", "bank", "base", "basis", "beautiful", "beginning", "being", "benefit", "beyond", "bird", "birth", "black", "blood", "board", "boat", "body", "book", "boss", "bottom", "boyfriend", "brain", "break", "broad", "brown", "brush", "budget", "building", "business", "button", "call", "camera", "capital", "card", "care", "career", "case", "cash", "category", "cause", "cell", "challenge", "chance", "change", "charge", "check", "chemistry", "chicken", "child", "choice", "cigarette", "city", "class", "classic", "click", "coast", "cold", "combination", "comfortable", "commercial", "common", "community", "company", "competition", "complex", "computer", "concept", "concern", "condition", "contact", "context", "control", "cook", "cost", "country", "county", "couple", "course", "cover", "craft", "creative", "credit", "culture", "current", "customer", "cycle", "damage", "dance", "data", "date", "deal", "dealer", "death", "debate", "decision", "deep", "definition", "demand", "department", "depth", "design", "desire", "development", "difference", "direction", "discipline", "discount", "discussion", "disease", "disk", "display", "distance", "drive", "driver", "earth", "economics", "economy", "education", "effect", "effective", "effort", "energy", "environment", "equipment", "estate", "event", "exam", "example", "exchange", "excuse", "exercise", "exit", "experience", "expression", "face", "fact", "fail", "failure", "fall", "familiar", "family", "feature", "feel", "feeling", "field", "figure", "file", "film", "final", "finding", "finish", "fire", "fish", "fishing", "flight", "flow", "focus", "following", "food", "foot", "force", "form", "foundation", "frame", "freedom", "friend", "front", "function", "future", "gain", "game", "garden", "general", "gift", "give", "glad", "goal", "good", "government", "grandmother", "great", "green", "ground", "group", "growth", "guard", "guide", "half", "hand", "handle", "head", "health", "heart", "heat", "heavy", "hello", "help", "high", "history", "hold", "home", "hope", "house", "housing", "human", "idea", "image", "impact", "importance", "income", "increase", "independent", "individual", "industry", "inflation", "influence", "information", "inside", "instance", "insurance", "interest", "internet", "investment", "issue", "item", "junior", "keep", "kind", "knowledge", "lack", "lake", "language", "lead", "leading", "leave", "length", "lesson", "level", "library", "life", "lift", "light", "line", "link", "list", "listen", "literature", "living", "local", "location", "long", "look", "love", "machine", "magazine", "main", "major", "make", "management", "many", "market", "marketing", "marriage", "material", "math", "matter", "maybe", "meaning", "meat", "media", "medicine", "medium", "meet", "member", "message", "metal", "method", "middle", "might", "mind", "minute", "model", "moment", "money", "month", "mood", "morning", "most", "mouse", "move", "movie", "music", "name", "nation", "national", "natural", "nature", "necessary", "negative", "network", "news", "newspaper", "night", "normal", "north", "note", "nothing", "notice", "number", "object", "objective", "offer", "office", "officer", "official", "opinion", "opportunity", "order", "original", "other", "outside", "oven", "page", "paint", "painting", "pair", "paper", "part", "particular", "past", "payment", "people", "performance", "period", "person", "personal", "perspective", "phase", "philosophy", "phone", "photo", "physical", "physics", "pick", "picture", "piece", "place", "plan", "plant", "plastic", "play", "player", "point", "policy", "politics", "population", "position", "positive", "possible", "post", "potential", "power", "practice", "present", "president", "press", "pressure", "price", "primary", "private", "problem", "process", "produce", "product", "profit", "program", "property", "public", "purchase", "purpose", "quality", "question", "radio", "rain", "range", "rate", "reach", "read", "reading", "reality", "reason", "recipe", "record", "reference", "register", "regular", "release", "remove", "rent", "report", "research", "reserve", "rest", "result", "return", "review", "rich", "ride", "rise", "risk", "road", "rock", "role", "room", "rule", "safe", "safety", "salt", "save", "savings", "scale", "scene", "school", "science", "screen", "search", "second", "secret", "section", "security", "self", "sell", "sense", "series", "serve", "service", "shape", "share", "shoot", "shopping", "shot", "show", "side", "sign", "simple", "single", "site", "situation", "size", "skill", "society", "software", "soil", "sound", "soup", "source", "space", "special", "specific", "speed", "spend", "sport", "spot", "spread", "spring", "square", "staff", "stage", "stand", "standard", "star", "start", "state", "statement", "stay", "step", "stick", "still", "stock", "stop", "store", "story", "strategy", "stress", "structure", "student", "studio", "study", "style", "subject", "success", "sugar", "summer", "support", "system", "table", "talk", "target", "task", "taste", "teach", "teacher", "teaching", "technology", "television", "tell", "temperature", "term", "test", "text", "thanks", "theme", "theory", "thing", "thought", "time", "title", "today", "tonight", "tool", "topic", "touch", "tough", "track", "trade", "training", "travel", "trouble", "truth", "turn", "type", "unique", "unit", "university", "user", "valuable", "value", "variety", "video", "view", "visit", "visual", "voice", "wait", "walk", "wall", "watch", "water", "wealth", "weather", "week", "western", "while", "white", "whole", "will", "wind", "wing", "woman", "wood", "word", "work", "working", "world", "worry", "worth", "writing", "year", "young"};
14+
private static final int LUCKY_HASH_NUMBER = -1314084409;
15+
16+
private static record Phrase(String text, Instant time, String user) {
17+
18+
@Override
19+
public boolean equals(Object o) {
20+
if (o instanceof Phrase that) {
21+
return that.text.equals(this.text) && that.time.equals(this.time) && that.user.equals(this.user);
22+
}
23+
return false;
24+
}
25+
26+
@Override
27+
public int hashCode() {
28+
return Objects.hash(this.text, this.time, this.user);
29+
}
30+
}
31+
32+
private static int hash(Object key) {
33+
int h;
34+
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
35+
}
36+
37+
public static void main(String[] args) {
38+
39+
System.err.println("started");
40+
41+
List<List<String>> phrasesHashList = new ArrayList<>();
42+
Instant[] instants = new Instant[9];
43+
44+
Instant instant = Instant.now().truncatedTo(ChronoUnit.SECONDS);
45+
for (int i = 0; i < 9; i++) {
46+
instants[i] = instant;
47+
phrasesHashList.add(new ArrayList<>());
48+
instant = instant.plusSeconds(1);
49+
System.err.println("instant " + i + ": " + instant.hashCode());
50+
}
51+
52+
int availableThreads = Runtime.getRuntime().availableProcessors();
53+
ExecutorService threadPool = new ThreadPoolExecutor(
54+
availableThreads, 128,
55+
0L, TimeUnit.MILLISECONDS,
56+
new LinkedBlockingDeque<>()
57+
);
58+
59+
for (String word1 : WORDS) {
60+
threadPool.submit(() -> {
61+
System.err.println("New thread started, id: " + Thread.currentThread().getId());
62+
for (String word2 : WORDS) for (String word3 : WORDS) for (String word4 : WORDS) {
63+
String phraseString = word1 + " " + word2 + " " + word3 + " " + word4;
64+
for (int t = 0; t < 9; t++) {
65+
Phrase phrase = new Phrase(phraseString, instants[t], "");
66+
if (hash(phrase) == LUCKY_HASH_NUMBER) {
67+
System.err.println("found: " + t + " @ `" + phrase.text() + "`");
68+
System.out.println("(" + t + ", '" + phrase.text() + "')");
69+
synchronized (phrasesHashList) {
70+
phrasesHashList.get(t).add(phrase.text());
71+
}
72+
}
73+
}
74+
75+
if (phrasesHashList.stream().allMatch(strings -> strings.size() > 20)) {
76+
for (List<String> list : phrasesHashList) {
77+
System.out.println(list);
78+
}
79+
System.exit(0);
80+
}
81+
}
82+
});
83+
}
84+
}
85+
}

players/rbtree/src/fourier.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import numpy
2+
import librosa
3+
from scipy.io import wavfile
4+
5+
freq_maps = list()
6+
freq_file = open('freq.txt', 'r')
7+
8+
for i in range(578):
9+
line_data = [float(x) * 33 - 52 for x in freq_file.readline().strip().split(' ')]
10+
freq_maps.append(numpy.array(line_data))
11+
12+
sample_rate = 22050
13+
freq_data = numpy.array(freq_maps).transpose()
14+
15+
sound = librosa.feature.inverse.mel_to_audio(librosa.db_to_power(freq_data))
16+
print(sound)
17+
wavfile.write('a.wav', 22050, sound)
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 424,
6+
"source": [
7+
"import requests\n",
8+
"import time\n",
9+
"\n",
10+
"url = \"http://202.38.93.111:10048/phrases?token=\"\n",
11+
"# url = \"http://localhost:8080/phrases\"\n",
12+
"\n",
13+
"phrases = \"\"\"\n",
14+
"[\n",
15+
" brush work demand north, care review story wait, chemistry will spend nothing, coast flight program idea, debate official plan math, equipment break research plant, following bank market click, following context analysis company, following secret change marriage, freedom film spend great, gift mouse wood literature, guard tool outside original,\n",
16+
" area future bird standard, bank direction location kind, cell boss work road, bird bank term photo, commercial title green object,\n",
17+
" account customer name today, association report simple balance,\n",
18+
" benefit review natural apartment, body help woman show, marriage income hope dealer,\n",
19+
" alternative move scale watch, anything maybe case water,\n",
20+
" account marketing situation creative, answer show love philosophy,\n",
21+
" demand site debate minute, might effect natural writing,\n",
22+
" bird film exercise wood, classic lift teach date,\n",
23+
" brain boyfriend choice house, location spread handle taste\n",
24+
"]\n",
25+
"\"\"\".replace('\\n', '')\n",
26+
"\n",
27+
"requests.delete(url)\n",
28+
"\n",
29+
"while time.time() - int(time.time()) <= 0.998:\n",
30+
" time.sleep(0.0001)\n",
31+
"\n",
32+
"start = time.time()\n",
33+
"print(requests.post(url, phrases).text)\n",
34+
"time.time() - start"
35+
],
36+
"outputs": [
37+
{
38+
"output_type": "stream",
39+
"name": "stdout",
40+
"text": [
41+
"{\n",
42+
" \"flag2\": \"flag{differen7-key5-h45h-m4p-c011i5i0n-f3448294418f7f1f}\",\n",
43+
" \"modified\": 32,\n",
44+
" \"flag1\": \"flag{h45h-m4p-c011i5i0n-0f-key-inpu75-81707c29c941e32a}\",\n",
45+
" \"user\": \"2408\"\n",
46+
"}\n"
47+
]
48+
},
49+
{
50+
"output_type": "execute_result",
51+
"data": {
52+
"text/plain": [
53+
"10.437883615493774"
54+
]
55+
},
56+
"metadata": {},
57+
"execution_count": 424
58+
}
59+
],
60+
"metadata": {}
61+
}
62+
],
63+
"metadata": {
64+
"orig_nbformat": 4,
65+
"language_info": {
66+
"name": "python",
67+
"version": "3.8.12",
68+
"mimetype": "text/x-python",
69+
"codemirror_mode": {
70+
"name": "ipython",
71+
"version": 3
72+
},
73+
"pygments_lexer": "ipython3",
74+
"nbconvert_exporter": "python",
75+
"file_extension": ".py"
76+
},
77+
"kernelspec": {
78+
"name": "python3",
79+
"display_name": "Python 3.8.12 64-bit ('hackergame': conda)"
80+
},
81+
"interpreter": {
82+
"hash": "c42898c533be1231f41f265937cddb2059f7ad207f43c329362e49d10571e0a2"
83+
}
84+
},
85+
"nbformat": 4,
86+
"nbformat_minor": 2
87+
}

0 commit comments

Comments
 (0)