出题团队简介
赛题设计思路
输出提示:key正确则输出提示good!
算法的核心步骤是根据生成的很简单的迷宫地图和输入的迷宫路径来验证是否能走出迷宫。
其中sc1负责生成迷宫地图,如果检测到调试信息等会生成错误的伪迷宫。
如果key正确则输出提示good! 否则输出no!或者不输出任何提示。
(1)aes秘钥后部分解密:
(2)aes秘钥前四个字符枚举条件 四个字符必须为数字类型
1 0
0 1
2、通过aes秘钥尝试解密sc1,使得sc1解密后执行时不产生异常
其中vc 部分代码如下:
SetUnhandledExceptionFilter(callback);
int ScSize = 0;
string FindScDec;
string AesKeyPreffix;
if (argc > 1)
AesKeyPreffix = argv[1];
string AesKeySuffix = "AllIsNothing";
string AesKey;
string aesIV = "ABCDEF0123456789";//128 bits
AES aes;
int size = strlen(FindScEnc) / 2;
TextToHex(FindScEnc, size);
AesKey = AesKeyPreffix + AesKeySuffix;
FindScDec = (char*)aes.DecryptCBC((unsigned char*)FindScEnc, size, (unsigned char*)AesKey.c_str(), (unsigned char*)aesIV.c_str());//CBC
ScSize = FindScDec.size();
void* ptr = NULL;
ptr = VirtualAlloc(
NULL,
ScSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (ptr == NULL) {
//printf("Failed to allocate memory: error=%un", GetLastError());
return 1;
}
memcpy(ptr, FindScDec.c_str(), ScSize);
__try{
((void(*)())ptr)();
printf("success!rn");
}
__except (filterException(GetExceptionCode(), GetExceptionInformation()))
{
printf("the aes preffix %s is errorrn", AesKeyPreffix.c_str());
}
return 0;
python 枚举部分代码为:
# -*- coding: UTF8 -*-
import os
import threading
import datetime
chrs = '0123456789'
AesPreffix = ''
a=b=c=d=''
AesPreffixS =[]
starttime = datetime.datetime.now()
threads = []
class Getoutofloop(Exception):
pass
def runsc(AesPreffix):
cmd = os.popen('NoLimit.exe ' + AesPreffix)
result = cmd.read()
print("result:" + result)
if 'success' in result:
print('AesPreffix is '+ AesPreffix)
AesPreffixS.append(AesPreffix)
for a in chrs:
AesPreffix += a
for b in chrs:
AesPreffix += b
for c in chrs:
AesPreffix += c
for d in chrs:
AesPreffix += d
t = threading.Thread(target=runsc, args=(AesPreffix,))
threads.append(t)
t.start()
#os._exit(0)
AesPreffix = AesPreffix[:-1]
AesPreffix = AesPreffix[:-1]
AesPreffix = AesPreffix[:-1]
AesPreffix = AesPreffix[:-1]
for t in threads:
t.join(2)
os.system('taskkill /f /im %s' % 'NoLimit.exe')
#print(AesPreffixS)
str = ''
lastresult = []
try:
for p in AesPreffixS:
for i in range(0,4):
a = p[i]
for j in range(0,4):
if j == i :
continue
b = p[j]
for k in range(0,4):
if k == j or k == i:
continue
c = p[k]
for l in range(0,4):
if l == k or l == j or l == i:
continue
d = p[l]
str = a + b + c + d
#print(str)
num = ord(str[0]) + ord(str[1])
if num == ord(str[2]) + ord(str[3]) and num == ord(str[0]) + ord(str[2]) and num == ord(str[1]) + ord(str[3]):
if p not in lastresult:
lastresult.append(p)
break;
#raise Getoutofloop()
except Getoutofloop:
pass
print('AesPreffix:')
print(lastresult)
endtime = datetime.datetime.now()
print('time:%ds' % (endtime - starttime).seconds )
AesPreffix:
[‘1441’, ‘1010’, ‘2222’, ‘2424’, ‘3773’, ‘4646’]
time:133s
1441
test edi,ebx
jl 1C8D88FFFDD//该跳转不执行
fdiv st(0),st(1)
ret
2222
ret
2424
xor cl,byte ptr ds:[rbx+19]
ret
3773
ret
4646
adc ch,al
ret
1010
call 1D18DAF0004
接着:
1D18DAF0004:inc eax
pop rdi
mov ecx,10107B1
xor ecx,1010101
add rdi,1E
xor esi,esi
cld
mov al,byte ptr ds:[rdi]
cmp al,11
cmove eax,esi
stosb
loop 1D18DAF0019
push rbx
push rsi
push rdi
push r12
push r13
... ...
(3)解密了sc1后 sc1负责生成迷宫
01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01
00 00 00 00 01 01 01 01 01 01
01 01 01 00 01 01 01 01 01 01
01 00 00 00 00 00 00 01 01 01
01 00 01 01 01 01 00 01 01 01
01 00 00 00 00 01 00 00 00 01
01 01 01 01 00 01 00 01 01 01
01 01 01 01 00 01 01 01 01 01
路径的坐标为:
30 31 32 33 43 53 52 51 61 71 72 73 74 84 94
(4)key的组成
2、AES秘钥前4个字符
3、路径长度
4、路径坐标
1BDF5752B86533B0EF0C488375EBFE389163712709D3FEE35C7679A1AB7A8E697366227CAF168C99DD7F110100F303132334353525161717273748494
(5)最后留了一个干扰项
赛题解析
本题解析由看雪论坛专家【ThTsOd】提供:
个人主页:https://bbs.pediy.com/user-home-940451.htm
1、NoLimit
输入长度 >= 0x59,<= 0xcd
2、计算rsa
N = 0x4F62187B5F6590C6CFF0FBDBBEBDAF60AA861BD2F66F8F7FFD57A66AE50DB7D2FFFFFFFFFFFFFFFFFFFFF
E = 0x11
N可直接分解
3、AES解密code
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
def AES_Decrypt(key, data):
iv = bytearray.fromhex("41 42 43 44 45 46 30 31 32 33 34 35 36 37 38 39")
cipher = AES.new(key, AES.MODE_CBC, iv)
text_decrypted = cipher.decrypt(data)
# try:
# text_decrypted = unpad(text_decrypted, AES.block_size, "pkcs7")
# except:
# return None
if(text_decrypted[-1] != 0x00):
return None
# 去补位
return text_decrypted
data = bytearray.fromhex("94 C7 A9 05 C7 DC ... 22 6A") #密文
for i in range(10000):
key = b""
t=[]
n=i
for l in range(4):
t.append((n%10)+48)
n//=10
key = bytearray(t)
key += bytearray.fromhex("41 6C 6C 49 73 4E 6F 74 68 69 6E 67 00 CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD")
result = AES_Decrypt(key,data)
if(result != None):
print(key[0:4],(result[0:0x10]).hex())
4、走迷宫?
17 3031323343515253545556617166727374847677788694
17 3031324351525354555661717273746676777884948694
END
https://ctf.pediy.com/game-season_fight-226.htm
球分享
球点赞
球在看
原文始发于微信公众号(看雪学苑):看雪2022 KCTF 秋季赛 | 第十题设计思路及解析