观察得出,将 flag 的每个字符都进行了一次 5 * m ** 2 + 6 * m - 8 的变换。
只需要用程序解出一元二次方程即可,使用 sympy 包可以直接解各种方程。
代码如下:
# def enc(flag):
# cipher = []
# for i in flag:
# m = ord(i)
# cipher.append(5 * m ** 2 + 6 * m - 8)
# return cipher
# 'y = 5*x^2 + 6x-8'
# print(enc(flag))
import sympy # 引入解方程的专业模块sympy
list = [60051, 62263, 51603, 49591, 67968, 52624, 76375, 38359, 51603, 58960, 49591, 62263, 60051, 51603, 45687, 67968, 62263, 45687, 22839, 65656, 73923, 63384, 67968, 62263, 78867]
text = ''
for num in list:
x = sympy.symbols("x")
a = sympy.solve([5 * x ** 2 + 6 * x - 8 - num],[x])
text = text + chr(a[1][0])
print(text)
moectf{Welcome_to_Crypto}
c4d038b4bed09fdb1471ef51ec3a32cd
在线md5搜索可得114514
moeflag{114514}
bW9lY3RmJTdCZXpfYjY0JTIxJTdE -> moectf%7Bez_b64%21%7D -> moectf{ez_b64!}
010 Editor 可看出在 png 后又写入了一个 zip 压缩包,更改后缀为 zip 后即可得到 txt 文本,内容为:
++++++++[>>++>++++>++++++>++++++++>++++++++++>++++++++++++>++++++++++++++>++++++++++++++++>++++++++++++++++++>++++++++++++++++++++>++++++++++++++++++++++>++++++++++++++++++++++++>++++++++++++++++++++++++++>++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++<<<<<<<<<<<<<<<<-]>>>>>>>>---.++.<+++++.--.>+++++.<+++.>>-----.--.<<-.>-.<<<<<+.>>>>>>.<<.>.<<<<<.>>>>+.+++++.------------.<+++++.>.<<<++.<.>>>>>>++++.
由在线工具即可解码得到
moectf{yes!yes!fk_U_2!}
逆向apk得到代码:
public class MainActivity extends AppCompatActivity {
String key = "dalaomenbiedale";
byte[] secret = {9, 14, 9, 2, 27, 11, 30, 55, 82, 28, 58, 15, 15, 92, 18, 59, 33, 34, 5, 29, 2, 84, 10, 61,
11, 86, 16, 21, 95, 23, 59, 53, 4, 82, 1, 50, 40, 11, 67, 20};
protected void onCreate(Bundle bundle) {
MainActivity.super.onCreate(bundle);
setContentView(0x7f0a001c);
}
public boolean checkFlag(byte[] bArr) {
if (bArr.length != 40) {
return false;
}
for (int i = 0; i < 40; i++) {
if ((bArr[i] ^ this.key.getBytes()[i % this.key.length()]) != this.secret[i]) {
return false;
}
}
return true;
}
public void getInput(View view) {
if (checkFlag(((EditText) findViewById(0x7f070054)).getText().toString().getBytes())) {
Toast.makeText(getApplicationContext(), "Your flag is correct!", 0).show();
} else {
Toast.makeText(getApplicationContext(), "Sorry, Your flag is wrong!", 0).show();
}
}
}
使用 python 编写逆向还原程序:
key = bytes("dalaomenbiedale",encoding='ASCII')
sec = bytes([9, 14, 9, 2, 27, 11, 30, 55, 82, 28, 58, 15, 15, 92, 18, 59, 33, 34, 5, 29, 2, 84, 10, 61, 11, 86, 16, 21, 95, 23, 59, 53, 4, 82, 1, 50, 40, 11, 67, 20])
print(len(sec))
line = ''
for i in range(0,40):
for t in range(0,128):
text = chr(t)
if(bytes(text,encoding="ASCII")[0] ^ key[i % len(key)] == sec[i]):
line = line + text
print(line)
moectf{Y0u_kn0w_@Ndro1d_b3tt3r_Th3n_Me!}
修改代码中的1919810为较小一点的数,直接多次点击即可获得flag.
moectf{y0U_w1n!}
按题目要求构造 payload : /?moe=flag
xdsec{26af0d0b-3876-4b2b-9ef9-f78436b114b5}
按题目要求构造 body {moe : flag}
xdsec{e3656736-4c04-424d-acb3-99396eee9a95}
修改网页 cookie 中 VIP 的值为 1 重发即可得到flag.
xdsec{3d5189a5-e8cf-4e64-aed5-c0cbb6c00182}
法1: 正经玩,突破50000分!
法2:
其实是随便玩试一把后发现会在游戏结束时提交一次数据。
构造payload : score = 999999999 即可获得flag.
xdsec{e710bed0-f3d9-476a-9b40-a8769499c0f6}
<?php
error_reporting(0);
$a=$_GET['a'];
$b=$_POST['b'];
if(isset($a)){
if($a!=$b&&md5($a)===md5($b)){
echo file_get_contents("/flag");
}else{
echo 'try again';
}
}else{
highlight_file(__FILE__);
}
需要 GET 提交一个 a 和 POST 一个 b ,并且需要在 php 中判定 a != b 和 md5(a) === md5(b).
在网上搜索后发现,构造a[]=1 b[]=2 可以绕过,但还需要同时进行 GET 和 POST 才行。
经搜索后发现,可以使用 hackbar 实现该操作。
xdsec{bc355cd3-1c31-4608-a508-b66e3a1be1ee}
将所给的 list 取 ln 在转化为 ANSII 对应后的字符即可。代码如下:
import math
list = [2.178203880729008e+47, 1.6094870669615087e+48, 7.307059979368028e+43, 9.889030319346894e+42, 2.3886906014249767e+50, 1.9862648361376436e+44,
2.6195173187490456e+53, 9.889030319346894e+42, 7.016735912097614e+20, 2.178203880729008e+47, 7.307059979368028e+43, 1.811239082889014e+41,
1.6094870669615087e+48, 5.920972027664636e+47, 214643579785915.7, 3.6379709476087856e+42, 7.307059979368028e+43, 5.399227610580139e+44,
3.989519570547194e+45, 5.920972027664636e+47, 1.811239082889014e+41, 3.5451311827611436e+52, 1.6094870669615087e+48, 6.493134255664421e+50,
3.23274119108484e+49, 1.811239082889014e+41, 1.2523631708422093e+29, 3.23274119108484e+49, 3.5451311827611436e+52, 4.375039447261315e+48,
2.3886906014249767e+50, 7.016735912097614e+20, 1.811239082889014e+41, 9.889030319346894e+42, 3.831008000716566e+22, 3.23274119108484e+49,
1.4093490824269349e+22, 1.4093490824269349e+22, 3.23274119108484e+49, 1.9355760420357097e+54]
dlist = ""
for i in list:
d = chr(int(math.log(i)))
dlist += d
print(dlist)
'''
moectf{c0me_on!begin_your_Crypt0_c4r33r}
'''
第一题应该不会太难,直接用 010 Editor 搜索 ctf 即可直接找到flag
moectf{W31C0Me_t0_m03CTF_2021_w0o0o0oooo0ooooo0o0oooo0!!!}
(要是真的顺着程序说的一个字符一个字符确认长度可能会累死吧)
npfdug{f3tz_Bv9v5u1of!} 题目也提示了移位密码,搜索找到通用的凯撒密码解密程序,m -> n 偏移量应该为1,输入程序后即可得到答案。
使用 010 Editor 翻到文件尾,找到flag.
moectf{hs_g1v3_u_fl@g}
想把隐藏的文本框拿出来发现怎么都整不出来。最后搜索到暴徒方法直接导出网页,稍微观察下即可找到 flag 的完整体。
flag{0h_U_f1nd_m3!}
尝试了隐写工具发现好像没有在通道藏东西。搜索相关内容后发现可能是图片宽高被修改了,将高度改大一些发现了个一维码。
moectf{WhY_@r3_u_s0_5K1ll3D}
要求按声音分析电话号码。
查 DTMF 表,将声音导入 Au.
一个一个标记分析即可(技术有限,做不出来自动分析程序)
moectf{忘了,也不想再来一遍}