好久没做题了,,,手都生疏了。费半天劲也就做了两道,,,在线求大腿
第一题ViQinere解题脚本>=97写成了>97楞是找了俩小时的BUG,,,
py2题一个简单的原生tea加密,,因为字面值默认是32位导致运算的时候溢出了,又找了好几个小时的BUG,,,,,
ViQinere
看输出前的那个加密函数
里面的jiami()函数是这样的
整个加密逻辑就在那一个函数里,,写逆脚本,,,爆破也可
nc连接服务器得到加密后的密文
#include <stdio.h>
#include <string.h>
int bh(char x)
{
if (x > 96 && x <= 122)
return x - 97;
else if (x >= 65 && x <= 90)
return x - 65 - 128;
else return x;
}
char TaQini[] = "TaQini";
char abcd[] = "zyxwvutsrqponmlkjihgfedcba";
int main(void)
{
int i, n = 0, p, j, k;
char result[54] = "FQD{GfjuJ5UbLrWjZjpvErXkiAZzlvO0xTa!cwnLLAsy3B0iEvEy}";
char flag[55] = { 0 },temp;
for (i = 0; i < 54; i++)
{
if (result[i] >= 97 && result[i] <= 122)
{
temp = bh(TaQini[n++ & 5]);
p = strchr(abcd, result[i]) - abcd;
p = p - (temp & 0x7f) + 97;
while (p < 97) p += 26;
while (p > 122)p -= 26;
flag[i] = p;
}
else if (result[i] >= 65 && result[i] <= 90)
{
temp = bh(TaQini[n++ & 5]);
p = strchr(abcd, result[i]+32) - abcd;
p = p - (temp & 0x7f) + 65;
while (p < 65) p += 26;
while (p > 90) p -= 26;
flag[i] = p;
}
else flag[i] = result[i];
}
puts(flag);
}
得到flag BJD{ThisI5MyViQiNireCiPheRHaveY0uTr!edtOBRut3F0rCeIt}
再进行MD5 32位加密就可提交,得到378e148c67dbf85b15bdd0f54a7fa71d
py2
下载下来是个pyo文件,去在线pyc,pyo反编译python反编译反编译得到源代码
import ctypes
from base64 import b64encode, b64decode
def decode():
fd = open('./libc.so', 'rb')
data = fd.read()
fd.close()
fd = open('./libc.so', 'wb')
fd.write(b64decode(data))
fd.close()
def check():
if b64encode(pwd) == 'YmpkMw==':
decode()
dl = ctypes.cdll.LoadLibrary
lib = dl('./libc.so')
reply = lib.check
reply(int(flag[:length // 2], 16), int(flag[length // 2:], 16), int(pwd.encode('hex'), 16))
print 'your input is BJD{%s}' % flag.decode('hex')
else:
print 'your password is wrong!'
if __name__ == '__main__':
print 'Please input your flag:'
flag = raw_input()
flag = flag.encode('hex')
length = len(flag)
print 'Please input your password:'
pwd = raw_input()
check()
读取了flag,将其转换为十六进制字符串
读取密码pwd然后base64加密和'YmpkMw=='
比较
然后对so文件进行base64解密,可以先运行一次取出解密后的so文件进行静态分析
然后将flag的十六进制字符串分成前后两部分,解释成数值,和pwd='bjd3’解释成十六进制一起传进so文件的check方法内
so文件的check方法
code方法是原生tea,只不过将32位改成了64位。。
根据传进去的参数我们可以得到,*a2 a2[1] a2[2] a2[3]
是tea的密钥,是check函数里的v4[4]
数组
并且全部相等且等于bjd3
的十六进制字符串对应的数值也就是0x626a6433
而a1则是待加密的数据,分成了两个64位数据,即v4、v5来加密
加密完后,将v4、v5又重新赋值到a1的地址,并在check函数内进行比较,若相等则成功,不相等则失败
关于tea加密可以看re加密算法:RSA|SM4|RC4|MD5|Tea
解题脚本
脚本需要注意的地方就是tea的sum值,按照32位数的时候会溢出,而我偷懒没有计算出来粘贴上去,而是直接左移5位,,导致溢出算不出来,,,
解决方法是手动计算出SUM赋给变量,或者字面值后添加LL后缀显式表明是64位值,,,
#include <stdio.h>
#include <string.h>
int main()
{
unsigned __int64 v4, v5,v6;
v4 = 0x0AF9D869B6947017D;
v5 = 0x0D760262509C2F6D0;
int i = 32;
v6 = 0x9E3779B9LL<<5; //字面值默认为32位值,进行的是32位运算,会溢出
__int64 a2 = 0x626a6433;
while (i--)
{
v5 -= (v4 + v6) ^ ((v4 << 4) + a2) ^ ((v4 >> 5) + a2);
v4 -= (v5 + v6) ^ ((v5 << 4) + a2) ^ ((v5 >> 5) + a2);
v6 -= 0x9E3779B9;
}
printf("%.8llx %.8llx", v4, v5);
return 0;
}
得到结果 676f745f 74656121
转换为字符串得到got_tea!