diff --git a/README.md b/README.md
index 41ba8bd..b9db924 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
本文档收集整理了中国科学技术大学第七届信息安全大赛的官方与非官方题解。
-该仓库仍在活跃更新中,欢迎各位选手以 Pull Request 的形式提交自己的 write-up(players 目录下以自己的昵称创建新文件夹)。
+该仓库仍在活跃更新中,欢迎各位选手以 Pull Request 的形式提交自己的 write-up(players 目录下以自己的昵称创建新文件夹,并在本文件的「来自选手」部分增加一行)。
若大家对本题解有任何疑问或改进建议,欢迎 [提 issue](https://github.com/USTC-Hackergame/hackergame2020-writeups/issues/new)
@@ -16,7 +16,7 @@
| ------------------------------------------------------------ | ------------------------------------------------------- |
| [签到](official/签到/README.md) | 无 |
| [猫咪问答++](official/猫咪问答++/README.md) | 无 |
-| [2048](official/2048/README.md) | 暂无 |
+| [2048](official/2048/README.md) | 暂无(之后会有) |
| [一闪而过的 Flag](official/一闪而过的%20Flag/README.md) | [文件、源代码](official/一闪而过的%20Flag/src) |
| [从零开始的记账工具人](official/从零开始的记账工具人/README.md) | [文件、源代码](official/从零开始的记账工具人/src) |
| [超简单的世界模拟器](official/超简单的世界模拟器/README.md) | [文件、源代码](official/超简单的世界模拟器/src) |
@@ -38,7 +38,7 @@
| [室友的加密硬盘](official/室友的加密硬盘/README.md) | 无 |
| [超简易的网盘服务器](official/超简易的网盘服务器/README.md) | [文件、源代码](official/超简易的网盘服务器/src) |
| [超安全的代理服务器](official/超安全的代理服务器/README.md) | [文件、源代码](official/超安全的代理服务器/src) |
-| [证验码](official/证验码/README.md) | 暂无 |
+| [证验码](official/证验码/README.md) | 暂无(之后会有) |
| [动态链接库检查器](official/动态链接库检查器/README.md) | [文件、源代码](official/动态链接库检查器/src) |
| [超精准的宇宙射线模拟器](official/超精准的宇宙射线模拟器/README.md) | [文件、源代码](official/超精准的宇宙射线模拟器/src) |
| [超迷你的挖矿模拟器](official/超迷你的挖矿模拟器/README.md) | [文件、源代码](official/超迷你的挖矿模拟器/src) |
@@ -52,6 +52,11 @@
| write-up | 备注 | 包含题目 |
| - | - | - |
| mcfx [Markdown](players/mcfx/writeup.md) [PDF](players/mcfx/writeup.pdf) | 总排名第一名 | 全部题目 |
+| [ProfFan](players/ProfFan/writeup.md) | | 证验码 |
+| [NaiveTomcat](players/NaiveTomcat/) | | 超简陋的 OpenGL 小程序, 狗狗银行, 233 同学的字符串工具, 233 同学的 Docker |
+| [sparkcyf](players/sparkcyf/writeup.md) | | 从零开始的记账工具人 |
+| [A-wing](players/a-wing/writeup.md) | | 一闪而过的 Flag, 233 同学的字符串工具, 233 同学的 Docker |
+| [hsfzxjy](players/hsfzxjy) | | 超基础的数理模拟器, 从零开始的 HTTP 链接, 永不溢出的计算器 |
## 其他资源
diff --git a/official/从零开始的 HTTP 链接/README.md b/official/从零开始的 HTTP 链接/README.md
index 76df9fd..e998da1 100644
--- a/official/从零开始的 HTTP 链接/README.md
+++ b/official/从零开始的 HTTP 链接/README.md
@@ -6,7 +6,7 @@
## 简单的解法
-在 Linux 下,安装 socat,然后运行 `socat TCP-LISTEN:20000,fork,reuseaddr TCP:202.38.93.111:0`,再从浏览器访问 localhost:20000 即可。
+在 Linux 下,安装 socat,然后运行 `socat TCP-LISTEN:20000,fork,reuseaddr TCP:202.38.93.111:0`,再从浏览器访问 localhost:20000 即可。(注:这里的 20000 也可以换成其他端口号,与下文「花絮」中提到的 20000 没有关系)
要注意,如果你在用 Linux 虚拟机,很多虚拟机软件的 NAT 实现不能正确处理 0 号端口,你需要把虚拟机的网络设置从 NAT 模式改为桥接模式。
diff --git a/official/动态链接库检查器/README.md b/official/动态链接库检查器/README.md
index 1aaaaec..1b5e8e6 100644
--- a/official/动态链接库检查器/README.md
+++ b/official/动态链接库检查器/README.md
@@ -28,6 +28,6 @@ Security
在网上搜索「ldd exploit」之类的关键词可以查到 CVE-2019-1010023,在[这个链接](https://sourceware.org/bugzilla/show_bug.cgi?id=22851)中,我们可以看到 ldd 任意命令执行的示例代码,然而这个问题并没有被修复。
-所以我们把示例代码保存成文件,把 `shellcode.asm` 最后的 `cat /etc/passwd` 改成读取 flag 的命令 `cat /flag`,然后在 Linux 环境下使用 `make` 命令编译,得到的 `libevil.so` 就可以上传到题目的网页获得 flag 了。
+所以我们把示例代码保存成文件,把 `shellcode.asm` 最后的 `cat /etc/passwd` 改成读取 flag 的命令 `cat /flag`,然后在 Linux 环境下使用 `make evil` 命令编译,得到的 `libevil.so` 就可以上传到题目的网页获得 flag 了。
[解题代码](src/solution)
diff --git a/official/普通的身份认证器/src/README.md b/official/普通的身份认证器/src/README.md
new file mode 100644
index 0000000..bbea59f
--- /dev/null
+++ b/official/普通的身份认证器/src/README.md
@@ -0,0 +1 @@
+测试 token: `233333:MEUCIQDTTJu25fXbAgKcF+MDCGp1OSTd+4OwvNmTn/DhZryCiAIgDQXsmAHvLrAe2BSwaoSZO+ml6as+Aj0N51PI3e6Befs=`。
diff --git a/official/签到/README.md b/official/签到/README.md
index 3d78471..ecc0bba 100644
--- a/official/签到/README.md
+++ b/official/签到/README.md
@@ -47,8 +47,8 @@ $('#number')[0].value = 1;
## 一些统计
-下面是比赛期间服务器统计的收到的 number 值的统计:
+下面是比赛期间服务器收到的 number 值的统计:

-
\ No newline at end of file
+
diff --git a/players/NaiveTomcat/2020-11-07-dockerWP.md b/players/NaiveTomcat/2020-11-07-dockerWP.md
new file mode 100644
index 0000000..8920e94
--- /dev/null
+++ b/players/NaiveTomcat/2020-11-07-dockerWP.md
@@ -0,0 +1,6 @@
+# Docker WP
+
+## 思路
+
+`/var/lib/docker/overlay2`中有pull下来的docker镜像的文件,而这个docker的构建是先有flag.txt
+后来删除的,于是就能在这个目录中搜索到flag.txt。
diff --git a/players/NaiveTomcat/2020-11-07-字符串工具WP.md b/players/NaiveTomcat/2020-11-07-字符串工具WP.md
new file mode 100644
index 0000000..9b87938
--- /dev/null
+++ b/players/NaiveTomcat/2020-11-07-字符串工具WP.md
@@ -0,0 +1,35 @@
+# 字符串工具WP
+
+## 大小写转换
+
+### 思路
+
+本问利用Unicode连字U+FB02(fl连写),该字符被传入python的upper()方法后会被转为FL,
+进而达到绕过过滤的方法
+
+### 脚本
+
+```python
+#!/usr/bin/python
+import pwn
+token="token"
+p=pwn.remote("202.38.93.111",10233)
+p.sendline(token)
+p.recvuntil("2. Convert my UTF-7 string to UTF-8!!")
+p.sendline("1")
+p.recvuntil("Welcome to the capitalizer tool, please input your string:")
+payload="\ufb02\u0061\u0067"
+p.sendline(payload)
+p.interactive()
+```
+
+## UTF-7到UTF-8转换
+
+### 思路
+
+本问利用UTF-7编码规则,将flag中每个字母扩充为双字节(即在前面加/x00),整体base64编码
+并在最前面加上“+”以及去除末尾“=”,发送到服务,被UTF-7解码成flag进而获取flag
+
+### payload
+
+`+AGYAbABhAGc`
diff --git a/players/NaiveTomcat/2020-11-07-狗狗银行WP.md b/players/NaiveTomcat/2020-11-07-狗狗银行WP.md
new file mode 100644
index 0000000..019bf36
--- /dev/null
+++ b/players/NaiveTomcat/2020-11-07-狗狗银行WP.md
@@ -0,0 +1,18 @@
+# 狗狗银行WP
+
+## 切入点
+
+后端计算利息的近似方法为四舍五入,故构造合理余额可使得借记卡利息达到0.6%,高于信用卡的0.5%从而获取利润
+
+## 解题方法
+
+分析创建卡、转账的请求,使用burp的intruder批量发包,首先自行手动创建一张信用卡,再通过burp批量创建998张借记卡
+(为了满足题目新增要求),再通过burp从信用卡向每一张新增的信用卡转账167元
+
+吃饭后,此时,每张卡都会有理论0.501元的利息,经过后端计算舍入得1元利息,共获得998元利息,而信用卡欠款166666元,
+利息833.33元,有164元差额。除去吃饭的10元仍有利润。重复几天就可以使净资产大于2000。
+
+## 错误解题方法
+
+看到题我的第一思路是整型溢出,于是借了很多钱,用burp请求/api/eat很多次,最后返回的欠款有2^1000不止。后端应该用
+的BigDecimal,不会出现溢出。
diff --git a/players/NaiveTomcat/2020-11-07-超简陋的OpenGL小程序WP.md b/players/NaiveTomcat/2020-11-07-超简陋的OpenGL小程序WP.md
new file mode 100644
index 0000000..1ea7373
--- /dev/null
+++ b/players/NaiveTomcat/2020-11-07-超简陋的OpenGL小程序WP.md
@@ -0,0 +1,23 @@
+# 超简陋的OpenGL小程序WP
+
+## 思路
+
+着色器脚本中更改视角和光源位置,更改完后运行即可
+
+## patch
+
+basic_lighting.fs
+```diff
+19c19
+< vec3 lightDir = normalize(-0.9* lightPos + FragPos);
+---
+> vec3 lightDir = normalize(lightPos - FragPos);
+```
+
+basic_lighting.vs
+```diff
+14c14
+< FragPos = vec3(-1 *model * vec4(aPos, 1.0));
+---
+> FragPos = vec3(model * vec4(aPos, 1.0));
+```
diff --git a/players/ProfFan/solver_files/solver_5_1.png b/players/ProfFan/solver_files/solver_5_1.png
new file mode 100644
index 0000000..9b291e2
Binary files /dev/null and b/players/ProfFan/solver_files/solver_5_1.png differ
diff --git a/players/ProfFan/solver_files/solver_5_1.svg b/players/ProfFan/solver_files/solver_5_1.svg
new file mode 100644
index 0000000..186a459
--- /dev/null
+++ b/players/ProfFan/solver_files/solver_5_1.svg
@@ -0,0 +1,562 @@
+
+
+
+
diff --git a/players/ProfFan/solver_files/solver_6_0.png b/players/ProfFan/solver_files/solver_6_0.png
new file mode 100644
index 0000000..6e5ae9c
Binary files /dev/null and b/players/ProfFan/solver_files/solver_6_0.png differ
diff --git a/players/ProfFan/solver_files/solver_6_0.svg b/players/ProfFan/solver_files/solver_6_0.svg
new file mode 100644
index 0000000..f594ee7
--- /dev/null
+++ b/players/ProfFan/solver_files/solver_6_0.svg
@@ -0,0 +1,7442 @@
+
+
+
+
diff --git a/players/ProfFan/writeup.md b/players/ProfFan/writeup.md
new file mode 100644
index 0000000..b5eb195
--- /dev/null
+++ b/players/ProfFan/writeup.md
@@ -0,0 +1,210 @@
+今年肝 paper 实在太忙,只做了一题和自己研究相关的(
+
+顺便膜各位师傅 orz
+
+# 证验码
+
+注意到题目给的是 BMP 格式,显然是为了保存图片的一些统计特征。继续审代码,发现随机数均为真随机,故这个方向没有价值。众所周知字体渲染是有 Anti-aliasing 的,所以每个字都有独特的灰度分布。
+故我们可以计算每张图片的灰度分布,再加上预计算每个单独字符的灰度分布,得到直方图,在直方图上做优化即可得到验证码。
+
+注意此处应当使用 L1 而不是 L2 (最小二乘)优化,因为16个字符远少于 26*2+10,结果应当是稀疏的。本题用 L2 也可以得到解,但是如果增加干扰线条的密度,L2 应该会失败。
+
+# 代码
+
+```python
+%matplotlib inline
+
+import matplotlib.pyplot as plt
+import numpy as np
+import random, string
+```
+
+
+```python
+import shuffle
+```
+
+
+```python
+# !wget https://github.com/adobe-fonts/source-code-pro/raw/release/TTF/SourceCodePro-Light.ttf
+```
+
+
+```python
+alphabet = sorted(string.digits + string.ascii_letters)
+#code = "".join([random.choice(alphabet) for _ in range(16)])
+code = "01234567890ABcde"
+print("Code:", code)
+```
+
+ Code: 01234567890ABcde
+
+
+
+```python
+original = shuffle.generate_captcha(code, shuffle_mode=False)
+shuffled = shuffle.generate_captcha(code, shuffle_mode=True)
+```
+
+
+```python
+plt.subplot(211)
+plt.imshow(original)
+plt.subplot(212)
+plt.imshow(shuffled)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+```python
+fig, axs = plt.subplots(2, 10, figsize=(20,6))
+for i in range(10):
+ test_onealpha = np.array(shuffle.img_generate("{}".format(i)))
+ axs[0][i].imshow(test_onealpha)
+ counts = np.bincount(test_onealpha[:, :, 0].flatten(),minlength=255)
+ axs[1][i].plot(counts)
+ axs[1][i].set_yscale('log')
+```
+
+
+
+
+
+
+```python
+counts_full = []
+for k in range(3):
+ counts = np.bincount(np.array(shuffled)[:, :, 0].flatten(),minlength=256)
+ counts[255] = 0
+ counts_full.append(counts)
+counts_full = np.hstack(counts_full)
+print(counts_full.shape)
+```
+
+ (768,)
+
+
+
+```python
+# %pip install cvxpy
+```
+
+
+```python
+import cvxpy as cvx
+```
+
+
+```python
+bases = []
+
+for i in range(len(alphabet)):
+ bases_rgb = []
+ for k in range(3):
+ test_onealpha = np.array(shuffle.img_generate("{}".format(alphabet[i])))
+ counts = np.bincount(test_onealpha[:, :, k].flatten(),minlength=256)
+ counts[255] = 0
+ bases_rgb.append(counts)
+ bases.append(np.hstack(bases_rgb))
+
+A = np.vstack(bases).T
+print(A.shape)
+print(A.T)
+```
+
+ (768, 62)
+ [[224 5 2 ... 3 5 0]
+ [134 1 1 ... 0 2 0]
+ [171 2 1 ... 3 4 0]
+ ...
+ [ 94 1 2 ... 2 6 0]
+ [118 4 3 ... 2 6 0]
+ [195 2 2 ... 1 3 0]]
+ /usr/lib/python3.8/site-packages/ipykernel/ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
+ and should_run_async(code)
+
+
+
+```python
+import PIL
+shuffled = PIL.Image.open("./captcha_shuffled.bmp")
+# Solve actual problem
+counts_full = []
+for k in range(3):
+ counts = np.bincount(np.array(shuffled)[:, :, 0].flatten(),minlength=256)
+ counts[255] = 0
+ counts_full.append(counts)
+counts_full = np.hstack(counts_full)
+print(counts_full.shape)
+```
+
+ (768,)
+ /usr/lib/python3.8/site-packages/ipykernel/ipkernel.py:287: DeprecationWarning: `should_run_async` will not call `transform_cell` automatically in the future. Please pass the result to `transformed_cell` argument and any exception that happen during thetransform in `preprocessing_exc_tuple` in IPython 7.17 and above.
+ and should_run_async(code)
+
+
+
+```python
+vx = cvx.Variable(len(alphabet))
+objective = cvx.Minimize(cvx.norm(A*vx - counts_full, 1))
+constraints = [vx >= 0]
+prob = cvx.Problem(objective, constraints)
+result = prob.solve(verbose=True)
+```
+
+
+ ECOS 2.0.7 - (C) embotech GmbH, Zurich Switzerland, 2012-15. Web: www.embotech.com/ECOS
+
+ It pcost dcost gap pres dres k/t mu step sigma IR | BT
+ 0 -2.788e-13 +1.258e-12 +5e+05 8e-01 4e-01 1e+00 3e+02 --- --- 1 2 - | - -
+ 1 +4.640e+03 +4.675e+03 +2e+05 3e-01 1e-01 3e+01 1e+02 0.7401 2e-01 1 1 1 | 0 0
+ 2 +5.846e+03 +5.861e+03 +9e+04 1e-01 4e-02 1e+01 6e+01 0.6585 8e-02 1 1 1 | 0 0
+ 3 +5.968e+03 +5.970e+03 +1e+04 1e-02 3e-03 2e+00 6e+00 0.9494 6e-02 1 1 1 | 0 0
+ 4 +6.080e+03 +6.080e+03 +3e+03 4e-03 1e-03 5e-01 2e+00 0.7566 6e-02 1 1 1 | 0 0
+ 5 +6.151e+03 +6.152e+03 +2e+03 2e-03 6e-04 3e-01 1e+00 0.6536 5e-01 1 1 1 | 0 0
+ 6 +6.193e+03 +6.193e+03 +9e+02 1e-03 3e-04 1e-01 5e-01 0.6015 1e-01 1 1 1 | 0 0
+ 7 +6.198e+03 +6.198e+03 +8e+02 1e-03 3e-04 1e-01 5e-01 0.2129 7e-01 1 1 1 | 0 0
+ 8 +6.216e+03 +6.216e+03 +6e+02 9e-04 2e-04 1e-01 3e-01 0.5360 4e-01 1 1 1 | 0 0
+ 9 +6.230e+03 +6.230e+03 +3e+02 6e-04 1e-04 6e-02 2e-01 0.6585 4e-01 1 1 1 | 0 0
+ 10 +6.244e+03 +6.244e+03 +2e+02 3e-04 5e-05 3e-02 1e-01 0.6652 2e-01 1 1 1 | 0 0
+ 11 +6.249e+03 +6.249e+03 +1e+02 2e-04 3e-05 2e-02 7e-02 0.5025 4e-01 1 1 1 | 0 0
+ 12 +6.255e+03 +6.255e+03 +6e+01 1e-04 2e-05 1e-02 4e-02 0.7639 3e-01 1 1 1 | 0 0
+ 13 +6.259e+03 +6.259e+03 +3e+01 5e-05 7e-06 6e-03 2e-02 0.6280 1e-01 1 1 1 | 0 0
+ 14 +6.261e+03 +6.261e+03 +1e+01 2e-05 3e-06 2e-03 7e-03 0.7859 2e-01 1 1 1 | 0 0
+ 15 +6.262e+03 +6.262e+03 +4e+00 8e-06 1e-06 9e-04 2e-03 0.7343 1e-01 1 1 1 | 0 0
+ 16 +6.263e+03 +6.263e+03 +8e-01 2e-06 2e-07 2e-04 5e-04 0.8474 6e-02 1 1 1 | 0 0
+ 17 +6.263e+03 +6.263e+03 +3e-01 7e-07 9e-08 8e-05 2e-04 0.6258 6e-02 1 1 1 | 0 0
+ 18 +6.263e+03 +6.263e+03 +4e-02 7e-08 1e-08 8e-06 2e-05 0.9127 2e-02 1 1 1 | 0 0
+ 19 +6.263e+03 +6.263e+03 +2e-03 3e-09 4e-10 4e-07 1e-06 0.9579 2e-04 2 1 1 | 0 0
+ 20 +6.263e+03 +6.263e+03 +2e-05 3e-11 5e-12 4e-09 1e-08 0.9890 1e-04 2 1 1 | 0 0
+
+ OPTIMAL (within feastol=3.4e-11, reltol=2.7e-09, abstol=1.7e-05).
+ Runtime: 0.048064 seconds.
+
+ /home/fan/.local/lib/python3.8/site-packages/cvxpy/expressions/expression.py:550: UserWarning:
+ This use of ``*`` has resulted in matrix multiplication.
+ Using ``*`` for matrix multiplication has been deprecated since CVXPY 1.1.
+ Use ``*`` for matrix-scalar and vector-scalar multiplication.
+ Use ``@`` for matrix-matrix and matrix-vector multiplication.
+ Use ``multiply`` for elementwise multiplication.
+
+ warnings.warn(__STAR_MATMUL_WARNING__, UserWarning)
+
+
+
+```python
+print(*zip(alphabet, vx.value.round(0)))
+```
+
+ ('0', 1.0) ('1', 0.0) ('2', -0.0) ('3', 0.0) ('4', -0.0) ('5', 1.0) ('6', 0.0) ('7', -0.0) ('8', 0.0) ('9', -0.0) ('A', 0.0) ('B', -0.0) ('C', -0.0) ('D', -0.0) ('E', 1.0) ('F', 0.0) ('G', -0.0) ('H', 1.0) ('I', -0.0) ('J', -0.0) ('K', 0.0) ('L', 1.0) ('M', -0.0) ('N', -0.0) ('O', 0.0) ('P', 1.0) ('Q', -0.0) ('R', -0.0) ('S', 1.0) ('T', -0.0) ('U', 0.0) ('V', 0.0) ('W', 1.0) ('X', 1.0) ('Y', 0.0) ('Z', 1.0) ('a', -0.0) ('b', 0.0) ('c', 0.0) ('d', 0.0) ('e', -0.0) ('f', -0.0) ('g', -0.0) ('h', -0.0) ('i', -0.0) ('j', -0.0) ('k', -0.0) ('l', 2.0) ('m', -0.0) ('n', -0.0) ('o', -0.0) ('p', -0.0) ('q', 0.0) ('r', -0.0) ('s', 1.0) ('t', -0.0) ('u', 1.0) ('v', 0.0) ('w', 1.0) ('x', 1.0) ('y', -0.0) ('z', -0.0)
+
diff --git a/players/README.md b/players/README.md
new file mode 100644
index 0000000..fbd0c87
--- /dev/null
+++ b/players/README.md
@@ -0,0 +1 @@
+本文件夹收录来自选手的非官方题解。
diff --git a/players/a-wing/writeup.md b/players/a-wing/writeup.md
new file mode 100644
index 0000000..8b1be83
--- /dev/null
+++ b/players/a-wing/writeup.md
@@ -0,0 +1,107 @@
+## 一闪而过的 Flag
+
+有 windows 的话很好办(我专门借了别人的 Window 机测试,这个很容易,就是白送的)
+
+可是我没有。。。只能这样看二进制数据
+
+```sh
+hexdump -Cv Untitled01.exe
+```
+
+可以找到这样一段
+
+```sh
+00000a70 48 98 c6 44 05 90 66 8b 45 fc 8d 50 01 89 55 fc |H..D..f.E..P..U.|
+00000a80 48 98 c6 44 05 90 6c 8b 45 fc 8d 50 01 89 55 fc |H..D..l.E..P..U.|
+00000a90 48 98 c6 44 05 90 61 8b 45 fc 8d 50 01 89 55 fc |H..D..a.E..P..U.|
+00000aa0 48 98 c6 44 05 90 67 8b 45 fc 8d 50 01 89 55 fc |H..D..g.E..P..U.|
+00000ab0 48 98 c6 44 05 90 7b 8b 45 fc 8d 50 01 89 55 fc |H..D..{.E..P..U.|
+00000ac0 48 98 c6 44 05 90 41 8b 45 fc 8d 50 01 89 55 fc |H..D..A.E..P..U.|
+00000ad0 48 98 c6 44 05 90 72 8b 45 fc 8d 50 01 89 55 fc |H..D..r.E..P..U.|
+00000ae0 48 98 c6 44 05 90 65 8b 45 fc 8d 50 01 89 55 fc |H..D..e.E..P..U.|
+00000af0 48 98 c6 44 05 90 5f 8b 45 fc 8d 50 01 89 55 fc |H..D.._.E..P..U.|
+00000b00 48 98 c6 44 05 90 79 8b 45 fc 8d 50 01 89 55 fc |H..D..y.E..P..U.|
+00000b10 48 98 c6 44 05 90 6f 8b 45 fc 8d 50 01 89 55 fc |H..D..o.E..P..U.|
+00000b20 48 98 c6 44 05 90 75 8b 45 fc 8d 50 01 89 55 fc |H..D..u.E..P..U.|
+00000b30 48 98 c6 44 05 90 5f 8b 45 fc 8d 50 01 89 55 fc |H..D.._.E..P..U.|
+00000b40 48 98 c6 44 05 90 65 8b 45 fc 8d 50 01 89 55 fc |H..D..e.E..P..U.|
+00000b50 48 98 c6 44 05 90 79 8b 45 fc 8d 50 01 89 55 fc |H..D..y.E..P..U.|
+00000b60 48 98 c6 44 05 90 65 8b 45 fc 8d 50 01 89 55 fc |H..D..e.E..P..U.|
+00000b70 48 98 c6 44 05 90 73 8b 45 fc 8d 50 01 89 55 fc |H..D..s.E..P..U.|
+00000b80 48 98 c6 44 05 90 31 8b 45 fc 8d 50 01 89 55 fc |H..D..1.E..P..U.|
+00000b90 48 98 c6 44 05 90 67 8b 45 fc 8d 50 01 89 55 fc |H..D..g.E..P..U.|
+00000ba0 48 98 c6 44 05 90 68 8b 45 fc 8d 50 01 89 55 fc |H..D..h.E..P..U.|
+00000bb0 48 98 c6 44 05 90 74 8b 45 fc 8d 50 01 89 55 fc |H..D..t.E..P..U.|
+00000bc0 48 98 c6 44 05 90 5f 8b 45 fc 8d 50 01 89 55 fc |H..D.._.E..P..U.|
+00000bd0 48 98 c6 44 05 90 67 8b 45 fc 8d 50 01 89 55 fc |H..D..g.E..P..U.|
+00000be0 48 98 c6 44 05 90 30 8b 45 fc 8d 50 01 89 55 fc |H..D..0.E..P..U.|
+00000bf0 48 98 c6 44 05 90 30 8b 45 fc 8d 50 01 89 55 fc |H..D..0.E..P..U.|
+00000c00 48 98 c6 44 05 90 44 8b 45 fc 8d 50 01 89 55 fc |H..D..D.E..P..U.|
+00000c10 48 98 c6 44 05 90 3f 8b 45 fc 8d 50 01 89 55 fc |H..D..?.E..P..U.|
+00000c20 48 98 c6 44 05 90 5f 8b 45 fc 8d 50 01 89 55 fc |H..D.._.E..P..U.|
+00000c30 48 98 c6 44 05 90 63 8b 45 fc 8d 50 01 89 55 fc |H..D..c.E..P..U.|
+00000c40 48 98 c6 44 05 90 61 8b 45 fc 8d 50 01 89 55 fc |H..D..a.E..P..U.|
+00000c50 48 98 c6 44 05 90 6e 8b 45 fc 8d 50 01 89 55 fc |H..D..n.E..P..U.|
+00000c60 48 98 c6 44 05 90 5f 8b 45 fc 8d 50 01 89 55 fc |H..D.._.E..P..U.|
+00000c70 48 98 c6 44 05 90 79 8b 45 fc 8d 50 01 89 55 fc |H..D..y.E..P..U.|
+00000c80 48 98 c6 44 05 90 6f 8b 45 fc 8d 50 01 89 55 fc |H..D..o.E..P..U.|
+00000c90 48 98 c6 44 05 90 75 8b 45 fc 8d 50 01 89 55 fc |H..D..u.E..P..U.|
+00000ca0 48 98 c6 44 05 90 5f 8b 45 fc 8d 50 01 89 55 fc |H..D.._.E..P..U.|
+00000cb0 48 98 c6 44 05 90 64 8b 45 fc 8d 50 01 89 55 fc |H..D..d.E..P..U.|
+00000cc0 48 98 c6 44 05 90 49 8b 45 fc 8d 50 01 89 55 fc |H..D..I.E..P..U.|
+00000cd0 48 98 c6 44 05 90 73 8b 45 fc 8d 50 01 89 55 fc |H..D..s.E..P..U.|
+00000ce0 48 98 c6 44 05 90 74 8b 45 fc 8d 50 01 89 55 fc |H..D..t.E..P..U.|
+00000cf0 48 98 c6 44 05 90 31 8b 45 fc 8d 50 01 89 55 fc |H..D..1.E..P..U.|
+00000d00 48 98 c6 44 05 90 6e 8b 45 fc 8d 50 01 89 55 fc |H..D..n.E..P..U.|
+00000d10 48 98 c6 44 05 90 67 8b 45 fc 8d 50 01 89 55 fc |H..D..g.E..P..U.|
+00000d20 48 98 c6 44 05 90 75 8b 45 fc 8d 50 01 89 55 fc |H..D..u.E..P..U.|
+00000d30 48 98 c6 44 05 90 69 8b 45 fc 8d 50 01 89 55 fc |H..D..i.E..P..U.|
+00000d40 48 98 c6 44 05 90 73 8b 45 fc 8d 50 01 89 55 fc |H..D..s.E..P..U.|
+00000d50 48 98 c6 44 05 90 68 8b 45 fc 8d 50 01 89 55 fc |H..D..h.E..P..U.|
+00000d60 48 98 c6 44 05 90 5f 8b 45 fc 8d 50 01 89 55 fc |H..D.._.E..P..U.|
+00000d70 48 98 c6 44 05 90 31 8b 45 fc 8d 50 01 89 55 fc |H..D..1.E..P..U.|
+00000d80 48 98 c6 44 05 90 69 8b 45 fc 8d 50 01 89 55 fc |H..D..i.E..P..U.|
+00000d90 48 98 c6 44 05 90 49 8b 45 fc 8d 50 01 89 55 fc |H..D..I.E..P..U.|
+00000da0 48 98 c6 44 05 90 3f 8b 45 fc 8d 50 01 89 55 fc |H..D..?.E..P..U.|
+00000db0 48 98 c6 44 05 90 7d 8b 45 fc 8d 50 01 89 55 fc |H..D..}.E..P..U.|
+```
+
+## 233 同学的字符串工具 **(这里有坑)**
+
+这道题其实是利用漏洞
+
+1. python upper() 函数有漏洞
+
+https://www.anquanke.com/post/id/196044
+
+`fl` `U+FB02` `大写` `FL` `U+0046` `U+004C`
+
+利用这个特殊字符可以生成 `FL` 。所以只要使用 `flag` 就可以在 `upper()` 转换成符合标准的字符
+
+这个要特别注意 **(这里有坑)** ,如果用 nc 的话有些终端会自动转换。直接复制是不行的。要用那个浏览器提供的终端
+
+## Docker
+
+这个是考 Docker 的原理,docker image 就是 git 的一层一层叠加上去的
+
+这里可以看一下这个容器历史记录
+
+https://hub.docker.com/layers/8b8d3c8324c7/stringtool/latest/images/sha256-aef87a00ad7a4e240e4b475ea265d3818c694034c26ec227d8d4f445f3d93152?context=explore
+
+
+根据这份官方文档,我们可以找到如何查看 rootfs 的 diff
+
+https://docs.docker.com/storage/storagedriver/overlayfs-driver/
+
+```sh
+
+docker pull 8b8d3c8324c7/stringtool
+
+docker image inspect 8b8d3c8324c7/stringtool:latest
+```
+
+
+`cat /var/lib/docker/overlay2/781c84bb2cc44b9b4a672de1475f0f50ed11c176a5a224b90b0e19b100d79917/diff/code/flag.txt`
+
+`flag{Docker_Layers!=PS_Layers_hhh}`
+
diff --git a/players/hsfzxjy/从零开始的 HTTP 链接/README.md b/players/hsfzxjy/从零开始的 HTTP 链接/README.md
new file mode 100644
index 0000000..7c26f1f
--- /dev/null
+++ b/players/hsfzxjy/从零开始的 HTTP 链接/README.md
@@ -0,0 +1,70 @@
+# 从零开始的 HTTP 链接
+
+此处提供一个使用 socket 编程完成 TCP 桥接的解法。
+
+运行 `python3 bridge.py :8080 202.38.93.111:0`,浏览器访问 `localhost:8080` 即可。
+
+```python
+"""
+python3 bridge.py :8080 202.38.93.111:0
+"""
+
+import sys
+import socket
+import select
+import logging
+
+
+def address(addr):
+ host, port = addr.split(":", 1)
+ return host, int(port)
+
+
+def main(bind, connect, log_level):
+ logging.basicConfig(level=log_level, format="%(asctime)s:%(levelname)s:%(message)s")
+ serv = socket.create_server(bind)
+ rtol = {}
+ ltor = {}
+ try:
+ while True:
+ readers, _, _ = select.select(
+ tuple(rtol.values()) + tuple(ltor.values()) + (serv,), (), ()
+ )
+ for reader in readers:
+ if reader is serv:
+ local_client, addr = reader.accept()
+ remote_client = socket.create_connection(connect)
+ ltor[local_client.fileno()] = remote_client
+ rtol[remote_client.fileno()] = local_client
+ elif reader.fileno() in ltor:
+ data = reader.recv(2 ** 12)
+ if data:
+ logging.info("L -> R: %r", data)
+ ltor[reader.fileno()].sendall(data)
+ else:
+ remote = ltor[reader.fileno()]
+ del ltor[reader.fileno()], rtol[remote.fileno()]
+ remote.close()
+ reader.close()
+ else:
+ data = reader.recv(2 ** 12)
+ if data:
+ logging.info("R -> L: %r", data)
+ rtol[reader.fileno()].sendall(data)
+ else:
+ local = rtol[reader.fileno()]
+ del rtol[reader.fileno()], ltor[local.fileno()]
+ reader.close()
+ local.close()
+ except Exception as e:
+ raise e
+ finally:
+ for sock in tuple(rtol.values()) + tuple(ltor.values()) + (serv,):
+ sock.close()
+
+
+if __name__ == "__main__":
+ bind = address(sys.argv[1])
+ connect = address(sys.argv[2])
+ main(bind, connect, "INFO")
+```
\ No newline at end of file
diff --git a/players/hsfzxjy/永不溢出的计算器/README.md b/players/hsfzxjy/永不溢出的计算器/README.md
new file mode 100644
index 0000000..16b9f4a
--- /dev/null
+++ b/players/hsfzxjy/永不溢出的计算器/README.md
@@ -0,0 +1,56 @@
+# 永不溢出的计算器
+
+思路基本同官方。鉴于本题没有提供 TCP 接口,这里给出一个在浏览器里搜索不同二次剩余的脚本。
+
+将以下代码贴在浏览器控制台运行即可。如果脚本停了,最后输出的两个数即是所要的 x 和 y。
+
+此处的原理是利用页面暴露在全局的 WebSocket 对象 `socket` 直接收发数据。
+
+```javascript
+(() => {
+ function rand(a, b) {
+ return Math.round(Math.random() * (b - a) + a)
+ }
+
+ function selectLargeNum() {
+ const len = Math.round(rand(154, 307))
+ let ret = ''
+ for (let i = 0; i < len; i++) ret += rand(0, 9)
+ return ret.replace(/^0+/, '')
+ }
+
+ class Result {
+ constructor() {
+ this.reset()
+ }
+ reset() {
+ this.promise = new Promise(resolve => this.resolve = resolve)
+ this.text = ''
+ }
+ }
+
+ let result = new Result
+ socket.addEventListener('message', (msg) => {
+ result.text += msg.data
+ if (! /\r\n>\s+$/.test(result.text)) return
+ result.resolve(/(\d+)\r\n>\s+$/.exec(result.text)[1])
+ })
+
+
+ async function loop() {
+ let num = selectLargeNum()
+ result.reset()
+ socket.send(num + ' ^ 2\n')
+ let res = await result.promise
+ result.reset()
+ socket.send('sqrt(' + res + ')\n')
+ res = await result.promise
+ console.log(res)
+ console.log(num)
+ if (num !== res) return
+ setTimeout(loop, 100)
+ }
+
+ loop()
+})()
+```
\ No newline at end of file
diff --git a/players/hsfzxjy/超基础的数理模拟器/README.md b/players/hsfzxjy/超基础的数理模拟器/README.md
new file mode 100644
index 0000000..2473804
--- /dev/null
+++ b/players/hsfzxjy/超基础的数理模拟器/README.md
@@ -0,0 +1,72 @@
+# 超基础的数理模拟器
+
+由于学过符号计算软件,本人首先想到用 Mathematica 去算积分,绕了点弯路,但还是可做的。以下给出代码。其中有几个要点:
+
+ 1. Mathematica 的 `ToExpression` 转换后的表达式是 `Integrate[...]` 也即符号积分,此时有可能算出奇怪的答案(比如复数解)。此时应该将 `Integrate` 替换为 `NIntegrate`。
+ 2. 其他一些替换,如把自然对数底 `e` 换成 `E`;最后的 `{d x}` 换成 `dx`;`\` 换成 `\\`;被积函数要用 `{}` 括起来。
+
+偶尔会有几个积分算不出来,但概率不大。半小时左右能拿到 flag。
+
+```python
+import re
+import pexpect
+import requests
+
+
+headers = {
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
+ "Referer": "http://202.38.93.111:10190/",
+}
+
+s = requests.session()
+s.cookies.clear()
+
+address = "http://202.38.93.111:10190/"
+
+tex_pattern = re.compile(
+ r"(?P