Final Score#
Sat Nov 7 09:59:22 AM CST 2020
Current Score: 1500, Overall Ranking: 225 / 2415
binary: 0, general: 850, math: 300, web: 350
Ah, I really am too weak (
I only solved a little bit of the problems.
Check-in#
Thanks for the invitation, I have a vested interest: I am an old check-in question setter.
This year's question group requirement is "Many of the students participating in our competition are beginners, our check-in questions should be clear and straightforward, allowing students to check in easily."
I completely understand, the check-in question is just giving a flag, if giving, then give, I am the best at giving.jpg
First, write a good question introduction: "You need to click the blue 'Open/Download Question' button below, obtain a flag in the form of flag{...} on the opened webpage, return to this page, fill it completely in the text box below, and click the gray 'Submit' button to complete this question."
Then write a flag extractor, how many flags the contestants need, I will give how many flags, green background, red bold, eye-catching position, standard format, this is not called giving, then what is called giving.
Click the 'Open/Download Question' button, open the flag extractor, and get the first flag!
Hint: Having trouble completing the question? You can refer to the 2018 check-in question solution and the 2019 check-in question solution.
Press F12 to locate the slider, change the maximum value to 1 and then drag the slider to the maximum to get the flag.
<input type="range" id="number" name="number" class="form-control" value="0" min="0" max="1" step="0.00001">
Cat Q&A++#
Next to the graduate cafeteria in the west district of the university, there is a cement slab that produces fat cats. Every sunny noon, there will be lazy cats basking in the sun on it. Many students who have finished lunch can take this opportunity to pet the cats.
But suddenly, from a certain day, an animal with a cat's head and body appeared on the cement slab, blocking the students who came to pet the cats, testing them with riddles it had carefully prepared. Only by answering all correctly could they pet the cats; if they accidentally answered incorrectly, it would show its displeasure.
To restore the daily cat petting activity, enthusiastic LUG association students put these riddles here. If you can answer all the riddles correctly, you will receive a flag as a reward.
Hint: Just as you don't need to be on-site to pet the cats, you don't need to be a student at the university to solve the riddles. Having trouble solving? You can refer to the 2018 cat Q&A solution.
A
typical MTU is 256 milligrams. Some datagram padding may be needed.
-
https://ftp.lug.ustc.edu.cn/events/2019.09.21_SFD/slides/lightning-talks/Teeworlds/ --> Teeworlds answer 9
-
Manually counted using Baidu Maps street view answer 9
-
https://news.ustclug.org/2019/12/hackergame-2019/ --> answer 17098
2048#
The road ahead is long and FLXG never gives up!
To achieve FLXG, you need exceptional wisdom, strong will, and the favor of fate. Only by proving that you possess these valuable qualities in the world of 2048 and achieving "great success" can you qualify to carry the banner of FLXG.
It's really 2048, looking at the js file, I found a game_manager.js
, roughly browsing the logic, I found this sentence
if (merged.value === 16384) self.won = true;
Set a breakpoint, manually modify the variable value, and succeeded.
Fleeting Flag#
On a clear autumn morning, by the West Lake. A poor student curled up on a bench by the road, tapping on an old notebook with rough fingers, repeatedly trying to open a program on the desktop. Each time the program runs, a flag briefly appears on the black console.
At his feet lies a sign made from discarded cardboard, reading "I am cute, please give me a flag." People walk hurriedly by, and the lunchbox used to hold the flag remains empty.
A poet student passed by, saw this scene, and changed the sign to: "The flag has arrived, but I see nothing!"
As a new student, you couldn't help but feel pity. Looking at the poet's carefree silhouette as he walked away, can you help this poor person fill his lunchbox with flags before the poet returns in the afternoon?
Ah, I feel like this flag is given for free, after the program runs, I can just take a screenshot to get the flag, I previously thought I had to record and analyze frame by frame...
Starting from Scratch: The Accounting Tool#
As usual, your npy suddenly throws you a shopping bill: "I bought a few little things today, can you help me calculate how much I spent in total?"
You think: Here we go again, time to eat dirt. Isn't this very simple? Just drag it in a spreadsheet and it will calculate it.
However, after receiving the bill, you notice that in order to feel more secure while shopping, all the amounts on this bill are written in Chinese numerals.
Note: Please keep the total amount of the bill to two decimal places and submit it in flag{}, for example, if the total amount is 123.45 yuan, you need to submit flag{123.45}
First, save it as csv, use python to convert the csv to json for easier processing.
Source code for statistics:
import json
def cover(i):
for j in range(0, len(text)):
if text[j] == i:
return j
yuan = 0
jiao = 0
fen = 0
text = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾"]
with open('bills.json', 'r') as f:
a = json.load(f)
for i in a:
y = i["mon"].split("元")
num = int(i["num"])
for j in y:
if "角" in j:
jj = j.split("角")
jiao += cover(jj[0])*num
if len(jj) > 1 and "分" in jj[1]:
fen += cover(jj[1].split("分")[0])*num
continue
if "分" in j:
fen += cover(j.split("分")[0].replace("零", ""))*num
continue
for i in range(0, len(j)):
if j[i] == "整":
continue
if j[i] == "佰":
continue
if i+1 < len(j):
if j[i+1] == "拾":
yuan += cover(j[i])*10*num
elif j[i+1] == "佰":
yuan += cover(j[i])*100*num
else:
if j[i] != "拾" and j[i] != "佰":
yuan += cover(j[i])*num
if i-1 < 0 and j[i] == "拾":
yuan += 10*num
jiao += int(fen/10)
fen = fen % 10*0.01
yuan += int(jiao/10)
jiao = jiao % 10*0.1
print(yuan+jiao+fen)
print("y", yuan)
print("j", jiao)
print("f", fen)
Answer 20262.53
Image from the First Teaching Building#
Little P discovered this image while doing a Fourier optics experiment in the lab computer's simulation program:
With a shaky foundation in mathematics, Little P didn't know what could produce such an image: or perhaps nothing at all, after all, this is just a simulation... But it can be certain that these seemingly strange patterns indeed hide some information, perhaps even a treasure map to an underground gold mine.
It's simple, the problem gives enough hints, just perform an inverse Fourier transform to get it.
Super Simple World Simulator#
Do you know the Game of Life (Conway's Game of Life)?
Your task is to recreate the effect of a butterfly flapping its wings, causing a storm across the ocean in the world of the Game of Life.
By changing the upper left 15x15 area, after 200 generations of evolution in the game, if the cells within the specially marked square are "cleared," you will receive the corresponding flag:
"Clear" any one square, and you will receive the first flag. Clear two squares, and you will receive the second flag.
Note: Your input is 15 lines of text, each line consisting of 15 zeros or ones, representing the content of that area.
Butterfly Effect#
My solution:
000000000000000
000000000000000
000000000000000
000000000000000
000000110000000
000001111000000
000001101100000
000000011000000
000000000000000
000000000000000
000000110000000
000001111000000
000001101100000
000000011000000
000000000000000
Referred to Zhihu: What patterns are there in the Game of Life?
Classmate 233's Docker#
Classmate 233 learned about Docker in software engineering class, so he wrote a Dockerfile for his string tool project.
But Classmate 233 suddenly realized that he accidentally packaged a private file (flag.txt) into it, so he wrote a command to delete this file.
"Since it's already deleted, it shouldn't be found, right?" Classmate 233 thought.
Docker Hub address: 8b8d3c8324c7/stringtool
From the commands in the Dockerfile:
/bin/sh -c rm /code/flag.txt
The flag is stored in /code
.
It seems that I just need to extract the contents from the docker layers, the problem is I don't know how I found Is there a way to tag a previous layer in a docker image or revert a commit?
docker save imagename $(sudo docker history -q imagename | tail -n +2 | grep -v \<missing\> | tr '\n' ' ') > image-caching.tar
Using this command extracts all layers, then I just need to check each layer.
flag{Docker_Layers!=PS_Layers_hhh}
Starting from Scratch: Martian Language Life#
The annual Hackergame is approaching, and Classmate L plans to invite Classmate Q to participate, but hasn't seen Classmate Q for several days. However, the night before the competition starts, he receives an email from Classmate Q:
Subject: Confidential! Do not share!!!
Body: See attachment
From: Q
Classmate L opened the attachment and was stunned, it was all meaningless Chinese characters. Clever Classmate L thought that Classmate Q usually likes to use GBK encoding, maybe the opening method was wrong. As a result, opening it with GBK revealed a bunch of mixed Japanese and numbers in Martian language...
Classmate L was completely confused, after several twists and turns, they found the most famous Martian language expert at the university (you). With years of experience in character encoding and decoding, can you decipher what Classmate Q's Martian language means?
Note: The correct flag consists entirely of ASCII characters!
File content:
脦脪鹿楼脝脝脕脣 拢脠拢谩拢茫拢毛拢氓拢貌拢莽拢谩拢铆拢氓 碌脛路镁脦帽脝梅拢卢脥碌碌陆脕脣脣眉脙脟碌脛 拢忙拢矛拢谩拢莽拢卢脧脰脭脷脦脪掳脩 拢忙拢矛拢谩拢莽 路垄赂酶脛茫拢潞 拢忙拢矛拢谩拢莽拢没拢脠拢麓拢枚拢鲁拢脽拢脝拢玫拢脦拢脽拢梅拢卤拢脭拢猫拢脽拢鲁拢卯拢茫拢掳拢盲拢卤拢卯拢莽拢脽拢麓拢脦拢盲拢脽拢盲拢鲁拢茫拢掳拢脛拢卤拢卯拢脟拢脽拢鹿拢帽拢脛拢虏拢脪拢赂拢猫拢贸拢媒 驴矛脠楼卤脠脠眉脝陆脤篓脤谩陆禄掳脡拢隆 虏禄脪陋脭脵掳脩脮芒路脻脨脜脧垄脳陋路垄赂酶脝盲脣没脠脣脕脣拢卢脪陋脢脟卤禄路垄脧脰戮脥脭茫赂芒脕脣拢隆
Uh... for this problem, I searched 拢 utf8
and happened to find The Chinese characters in the code are all garbled, asking for help with encoding issues! and looked at the answer.
alcarl 2018-01-09 01:25:21 +08:00 via Android ❤️ 3
First save this text as a file with GB2312 encoding, then convert it to UTF-8 encoding, save it, and then convert it to 8859-1 and open it as GBK, and it will work. =͟͟͞͞(꒪ᗜ꒪ ‧̣̥̇) The text will be like this
Then following this process... it worked...
I hacked into the Hackergame server and stole their flag, now I am sending the flag to you:
flag{H4v3_FuN_w1Th_3nc0d1ng_4Nd_d3c0D1nG_9qD2R8hs}
Go submit it on the competition platform!
Do not forward this information to others, or it will be terrible if discovered!
Starting from Scratch: HTTP Link#
As we all know, array indices should start from 0.
Similarly, TCP ports should also start from 0. To practice this, we set up a website on the server's port 0.
Can you successfully connect to port 0 and get the flag?
Clicking the button below to open the question will not open the webpage, as ordinary browsers will consider this an invalid address.
Address: http://202.38.93.111:0/
From the question, it can be seen that I should construct an HTTP request myself to get the flag.
My solution:
I found a C implementation of http get (Source)
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define IPSTR "202.38.93.111" // Server IP address;
#define PORT 0
#define BUFSIZE 1024
int main(int argc, char **argv)
{
int sockfd, ret, i, h;
struct sockaddr_in servaddr;
char str1[4096], str2[4096], buf[BUFSIZE], *str;
socklen_t len;
fd_set t_set1;
struct timeval tv;
// Create socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
printf("Failed to create network connection, this thread will terminate---socket error!\n");
exit(0);
};
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
if (inet_pton(AF_INET, IPSTR, &servaddr.sin_addr) <= 0 ){
printf("Failed to create network connection, this thread will terminate--inet_pton error!\n");
exit(0);
};
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
printf("Failed to connect to server, connect error!\n");
exit(0);
}
printf("Connected to the remote server\n");
memset(str2, 0, 4096);
str=(char *)malloc(128);
len = strlen(str2);
sprintf(str, "%d", len);
memset(str1, 0, 4096);
strcat(str1, "GET / HTTP/1.1\n");
strcat(str1, "Host: 202.38.93.111\n");
strcat(str1, "\n\n");
// strcat(str1, str2);
strcat(str1, "\r\n\r\n");
printf("%s\n",str1);
ret = write(sockfd,str1,strlen(str1));
if (ret < 0) {
printf("Send failed! Error code is %d, error message is '%s'\n",errno, strerror(errno));
exit(0);
}else{
printf("Message sent successfully, a total of %d bytes sent!\n\n", ret);
}
FD_ZERO(&t_set1);
FD_SET(sockfd, &t_set1);
while(1){
sleep(2);
tv.tv_sec= 0;
tv.tv_usec= 0;
h= 0;
// printf("--------------->1\n");
h= select(sockfd +1, &t_set1, NULL, NULL, &tv);
// printf("--------------->2\n");
//if (h == 0) continue;
if (h < 0) {
close(sockfd);
printf("An exception was detected during data packet reading, this exception caused the thread to terminate!\n");
return -1;
};
if (h > 0){
memset(buf, 0, 4096);
i= read(sockfd, buf, 4095);
if (i==0){
close(sockfd);
printf("Detected remote closure while reading data packets, this thread will terminate!\n");
return -1;
}
printf("%s\n", buf);
break;
}
}
close(sockfd);
return 0;
}
Obtained the index.html
file to learn key information.
<script>
const term = new Terminal();
const fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(document.getElementById("terminal"));
fitAddon.fit();
window.addEventListener('resize', function(event) {
fitAddon.fit();
});
var firstmsg = true;
const socket = new WebSocket(
"ws://202.38.93.111:0/shell"
);
const attachAddon = new AttachAddon.AttachAddon(socket);
term.loadAddon(attachAddon);
socket.onclose = event => {
term.write("\nConnection closed");
};
socket.onmessage = event => {
if (firstmsg) {
firstmsg = false;
let token = new URLSearchParams(window.location.search).get("token");
window.history.replaceState({}, null, '/');
if (token) {
localStorage.setItem('token', token);
} else {
token = localStorage.getItem('token');
}
if (token) socket.send(token + "\n");
}
};
term.focus();
</script>
Then I also made one in C++ for websocket, connected to their server, sent the token, and got the flag.
easywsclient: connecting: host=202.38.93.111 port=0 path=/shell
Connected to: ws://202.38.93.111:0/shell
>>> 2533:MEUCIQCz8PiKvLdy1K7+TZJTwqM581W17UdJRfk3Q6hxPtr6sQIgb+Cy14NALA4ETpFQfXyfDhIxz10fyy0+t7GDEhEpS3c=
>>> Please input your token:
>>> flag{TCP_P0RT_0_1s_re5erved_BUT_w0rks_e7e56860a1}
Unintentional Transfer#
Decrypting Messages#
A certain student saw a magical cryptographic protocol called "Oblivious Transfer" on an unknown encyclopedia website.
So he implemented one side of the protocol according to the description on the website "1–2 oblivious transfer," and you can interact with him as the other side.
There shouldn't be any problems with the protocol implemented exactly according to the encyclopedia website's algorithm, right?
Click to download the source code.
In addition to the web terminal, you can also connect via nc 202.38.93.111 10031.
Searching for the term "1–2 oblivious transfer" led me to this.
Then I opened the python file and followed the steps to obtain the decrypted message.
flag{U_R_0n_Th3_ha1f_way_0f_succe55_w0rk_h4rder!_163a930598}
Super Secure Proxy Server#
Finding the Secret#
In 2039, an unprecedented pandemic broke out. To facilitate students in various places to access the well-known university "Pants University" website for "daily health check-ins," Classmate C provided such a proxy service. Once a student with a background in information security, Classmate C decided to design this proxy to be the most secure.
Hint: The browser may prompt that the TLS certificate is invalid, which is unrelated to the solution of this problem, just trust it.
Announcement: The link to the "Management Center" on the help page of the problem (https://146.56.228.227/help) is incorrect, it should be the same as the homepage, pointing to http://127.0.0.1:8080/
Address: https://146.56.228.227/
First, let's check the page~
Notice: We have pushed (PUSH) the latest Secret to you, but you may not be able to see it directly.
I googled and found How to Test HTTP/2 Push using Google Chrome and followed the instructions to install the HTTP/2 and SPDY indicator extension. After opening it, I saw
The net-internals events viewer and related functionality has been removed. Please use chrome://net-export to save netlogs and the external netlog_viewer to view them.
I exported the log and searched for this HTTP/2 session in the netlog viewer, and it was easy to find.
t=1410 [st=281729] HTTP2_SESSION_SEND_RST_STREAM
--> description = "Duplicate pushed stream with url: https://146.56.228.227/e3b2a173-d763-409e-807c-584d13a10c92"
--> error_code = "7 (REFUSED_STREAM)"
--> stream_id = 6
Accessing the URL mentioned above, I obtained the flag flag{d0_n0t_push_me}
.
Reference Links#
- Wikipedia: Internet Protocol Over Birds
- USTC LUG FTP
- Baidu Maps - Street View
- USTC LUG NEWS
- stackoverflow: How to convert CSV file to multiline JSON?
- Zhihu: What patterns are there in the Game of Life?
- stackoverflow: Is there a way to tag a previous layer in a docker image or revert a commit?
- v2ex: The Chinese characters in the code are all garbled, asking for help with encoding issues!
- CSDN: C language implementation of HTTP GET and POST requests - Running Fast 94
- github: core1011/websocket
- wikipedia: Oblivious_transfer
- How to Test HTTP/2 Push using Google Chrome