pyinstaller打包,用工具解一下,得到login.pyc修复一下文件头,反编译解方程组。
from z3 import *
s=Solver()
code=[BitVec(('x%d'%i),32) for i in range(14)]
a1 = code[2]
a2 = code[1]
a3 = code[0]
a4 = code[3]
a5 = code[4]
a6 = code[5]
a7 = code[6]
a8 = code[7]
a9 = code[9]
a10 = code[8]
a11 = code[10]
a12 = code[11]
a13 = code[12]
a14 = code[13]
s.add((((a1 * 88 + a2 * 67 + a3 * 65 - a4 * 5) + a5 * 43 + a6 * 89 + a7 * 25 + a8 * 13 - a9 * 36) + a10 * 15 + a11 * 11 + a12 * 47 - a13 * 60) + a14 * 29 == 22748)
s.add((((a1 * 89 + a2 * 7 + a3 * 12 - a4 * 25) + a5 * 41 + a6 * 23 + a7 * 20 - a8 * 66) + a9 * 31 + a10 * 8 + a11 * 2 - a12 * 41 - a13 * 39) + a14 * 17 == 7258)
s.add((((a1 * 28 + a2 * 35 + a3 * 16 - a4 * 65) + a5 * 53 + a6 * 39 + a7 * 27 + a8 * 15 - a9 * 33) + a10 * 13 + a11 * 101 + a12 * 90 - a13 * 34) + a14 * 23 == 26190)
s.add((((a1 * 23 + a2 * 34 + a3 * 35 - a4 * 59) + a5 * 49 + a6 * 81 + a7 * 25 + (a8 << 7) - a9 * 32) + a10 * 75 + a11 * 81 + a12 * 47 - a13 * 60) + a14 * 29 == 37136)
s.add(((a1 * 38 + a2 * 97 + a3 * 35 - a4 * 52) + a5 * 42 + a6 * 79 + a7 * 90 + a8 * 23 - a9 * 36) + a10 * 57 + a11 * 81 + a12 * 42 - a13 * 62 - a14 * 11 == 27915)
s.add((((a1 * 22 + a2 * 27 + a3 * 35 - a4 * 45) + a5 * 47 + a6 * 49 + a7 * 29 + a8 * 18 - a9 * 26) + a10 * 35 + a11 * 41 + a12 * 40 - a13 * 61) + a14 * 28 == 17298)
s.add((((a1 * 12 + a2 * 45 + a3 * 35 - a4 * 9 - a5 * 42) + a6 * 86 + a7 * 23 + a8 * 85 - a9 * 47) + a10 * 34 + a11 * 76 + a12 * 43 - a13 * 44) + a14 * 65 == 19875)
s.add(((a1 * 79 + a2 * 62 + a3 * 35 - a4 * 85) + a5 * 33 + a6 * 79 + a7 * 86 + a8 * 14 - a9 * 30) + a10 * 25 + a11 * 11 + a12 * 57 - a13 * 50 - a14 * 9 == 22784)
s.add((((a1 * 8 + a2 * 6 + a3 * 64 - a4 * 85) + a5 * 73 + a6 * 29 + a7 * 2 + a8 * 23 - a9 * 36) + a10 * 5 + a11 * 2 + a12 * 47 - a13 * 64) + a14 * 27 == 9710)
s.add(((((a1 * 67 - a2 * 68) + a3 * 68 - a4 * 51 - a5 * 43) + a6 * 81 + a7 * 22 - a8 * 12 - a9 * 38) + a10 * 75 + a11 * 41 + a12 * 27 - a13 * 52) + a14 * 31 == 13376)
s.add((((a1 * 85 + a2 * 63 + a3 * 5 - a4 * 51) + a5 * 44 + a6 * 36 + a7 * 28 + a8 * 15 - a9 * 6) + a10 * 45 + a11 * 31 + a12 * 7 - a13 * 67) + a14 * 78 == 24065)
s.add((((a1 * 47 + a2 * 64 + a3 * 66 - a4 * 5) + a5 * 43 + a6 * 112 + a7 * 25 + a8 * 13 - a9 * 35) + a10 * 95 + a11 * 21 + a12 * 43 - a13 * 61) + a14 * 20 == 27687)
s.add(((a1 * 89 + a2 * 67 + a3 * 85 - a4 * 25) + a5 * 49 + a6 * 89 + a7 * 23 + a8 * 56 - a9 * 92) + a10 * 14 + a11 * 89 + a12 * 47 - a13 * 61 - a14 * 29 == 29250)
s.add(((a1 * 95 + a2 * 34 + a3 * 62 - a4 * 9 - a5 * 43) + a6 * 83 + a7 * 25 + a8 * 12 - a9 * 36) + a10 * 16 + a11 * 51 + a12 * 47 - a13 * 60 - a14 * 24 == 15317)
if s.check()==sat:
print "sat"
print s.model()
else:
print "un"
方程组解完再异或运算一下
#include
#include
int main()
{
char szpassword[14] = {
10,0x18,0x77,7,104,43,28,91,108,0x34,0x58,0x4a,0x58,33 };
//char szpassword[14] = {10,24,119,7,104,43,28,91,52,108,88,74,88,33 };
char a[16] ;
for (int i = 13; i >=0; i--)
{
szpassword[i - 1] ^= szpassword[i];
}
for (int i = 0; i < 14; i++)
{
printf("%c", szpassword[i]);
}
printf("\n");
getchar();
}
得到flag,再md5加密一下提交
手撕py机器码,得到正向算法类似如下
mport dis
def hello():
x=[]
en=[3,37,72,9,6,132]
flag="1234567890123456"
a=ord(flag[0])*2020+ord(flag[1])*2020
k=5
for i in range(13):
b= ord(flag[k])
c=ord(flag[k+1])
a11=en[i%6]^c
a22=en[i%6]^b
x.append(a22)
x.append(a11)
k=k+2
l=len(flag)
a1=ord(flag[l-7])
a2=ord(flag[l-6])
a3=ord(flag[l-5])
a4=ord(flag[l-4])
a5=ord(flag[l-3])
a6=ord(flag[l-2])
if a1*3+a2*2+a3*5==1003:
print 1
if a1*4+a2*7+a3*9==2013:
print 1
if a2*8+a1+2*a3==1109:
print 1
if a4*3+a5*2+a6*5==671:
print 1
if a4*4+a5*7+a6*9==1252:
print 1
if a5*8+a4+a6*2==644:
print 1
dis.dis(hello)
其中前5位不是很好算不过可以猜到是GWHT{
后面是一段异或解密如下
int main()
{
int en[6] = {
3, 37, 72, 9, 6, 132};
int output[26] = {
101, 96, 23, 68, 112, 42, 107, 62, 96, 53, 176, 179, 98, 53, 67, 29, 41, 120, 60, 106, 51, 101, 178, 189, 101, 48 };
int k = 0;
for (int i = 0; i < 13; i++)
{
printf("%c", output[k+1] ^ en[i % 6]);
printf("%c", output[k] ^ en[i % 6]);
k = k + 2;
}
getchar();
}
最后6位解方程组
from z3 import *
s=Solver()
a1=Int('a1')
a2=Int('a2')
a3=Int('a3')
a4=Int('a4')
a5=Int('a5')
a6=Int('a6')
s.add(a1*3+a2*2+a3*5==1003)
s.add(a1*4+a2*7+a3*9==2013)
s.add(a2*8+a1+2*a3==1109)
s.add(a4*3+a5*2+a6*5==671)
s.add(a4*4+a5*7+a6*9==1252)
s.add(a5*8+a4+a6*2==644)
if s.check()==sat:
print "sat"
print s.model()
else:
print "un"
首先是一个Des解密,这里用gdb调试将解密数据作为输入数据,DES_ncbc_encryp最后一个参数改为0,即可得到key:th1s1sth3n1c3k3y
之后将内存dUmp下来再修复一下自解码
a=[0x55, 0x48, 0x89, 0xE5, 0x48, 0x81, 0xEC, 0x40, 0x01, 0x00, 0x00, 0x48, 0x89, 0xBD, 0xC8, 0xFE, 0xFF, 0xFF, 0x64, 0x48, 0x8B, 0x04, 0x25, 0x28, 0x00, 0x00, 0x00, 0x48, 0x89, 0x45, 0xF8, 0x31, 0xC0, 0x48, 0x8D, 0x45, 0xB0, 0x48, 0x89, 0xC6, 0xBF, 0xE0, 0x2F, 0x40, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x2C, 0xE1, 0xFF, 0xFF, 0x48, 0x8D, 0x45, 0xB0, 0x48, 0x89, 0xC7, 0xE8, 0x00, 0xE1, 0xFF, 0xFF, 0x89, 0x85, 0xEC, 0xFE, 0xFF, 0xFF, 0x83, 0xBD, 0xEC, 0xFE, 0xFF, 0xFF, 0x20, 0x74, 0x14, 0xBF, 0xE5, 0x2F, 0x40, 0x00, 0xE8, 0x97, 0xE0, 0xFF, 0xFF, 0xBF, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x9D, 0xE0, 0xFF, 0xFF, 0x48, 0x8B, 0x95, 0xC8, 0xFE, 0xFF, 0xFF, 0x48, 0x8D, 0x85, 0xF0, 0xFE, 0xFF, 0xFF, 0x48, 0x89, 0xD6, 0x48, 0x89, 0xC7, 0xE8, 0xE5, 0xE4, 0xFF, 0xFF, 0x48, 0x8D, 0x55, 0xB0, 0x48, 0x8D, 0x85, 0xF0, 0xFE, 0xFF, 0xFF, 0x48, 0x89, 0xD6, 0x48, 0x89, 0xC7, 0xE8, 0xCC, 0xF3, 0xFF, 0xFF, 0x48, 0x8D, 0x45, 0xB0, 0x48, 0x83, 0xC0, 0x10, 0x48, 0x8D, 0x95, 0xF0, 0xFE, 0xFF, 0xFF, 0x48, 0x89, 0xC6, 0x48, 0x89, 0xD7, 0xE8, 0xB2, 0xF3, 0xFF, 0xFF, 0xC7, 0x85, 0xD8, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x5B, 0xC7, 0x85, 0xDC, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x2F, 0x8B, 0x85, 0xD8, 0xFE, 0xFF, 0xFF, 0x48, 0x98, 0x0F, 0xB6, 0x54, 0x05, 0xB0, 0x8B, 0x85, 0xDC, 0xFE, 0xFF, 0xFF, 0x48, 0x98, 0x0F, 0xB6, 0x44, 0x05, 0xB0, 0x31, 0xC2, 0x8B, 0x85, 0xD8, 0xFE, 0xFF, 0xFF, 0x48, 0x98, 0x88, 0x54, 0x05, 0xB0, 0x83, 0x85, 0xDC, 0xFE, 0xFF, 0xFF, 0x01, 0x8B, 0x85, 0xD8, 0xFE, 0xFF, 0xFF, 0x8D, 0x50, 0x03, 0x85, 0xC0, 0x0F, 0x48, 0xC2, 0xC1, 0xF8, 0x02, 0x3B, 0x85, 0xDC, 0xFE, 0xFF, 0xFF, 0x7F, 0xB8, 0x83, 0x85, 0xD8, 0xFE, 0xFF, 0xFF, 0x01, 0x83, 0xBD, 0xD8, 0xFE, 0xFF, 0xFF, 0x1F, 0x7E, 0x9C, 0xC7, 0x85, 0xE0, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xC7, 0x85, 0xE4, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xE9, 0x8C, 0x00, 0x00, 0x00, 0xC6, 0x85, 0xD7, 0xFE, 0xFF, 0xFF, 0x00, 0x8B, 0x85, 0xE4, 0xFE, 0xFF, 0xFF, 0x83, 0xE8, 0x01, 0x48, 0x98, 0x0F, 0xB6, 0x44, 0x05, 0xB0, 0x83, 0xF0, 0x13, 0x01, 0xC0, 0x83, 0xC0, 0x07, 0x89, 0xC6, 0x8B, 0x85, 0xE4, 0xFE, 0xFF, 0xFF, 0x83, 0xE8, 0x01, 0x48, 0x98, 0x0F, 0xB6, 0x4C, 0x05, 0xB0, 0x0F, 0xB6, 0xD1, 0x89, 0xD0, 0xC1, 0xE0, 0x03, 0x29, 0xD0, 0xC1, 0xE0, 0x03, 0x01, 0xD0, 0x66, 0xC1, 0xE8, 0x08, 0x89, 0xC2, 0xD0, 0xEA, 0x89, 0xD0, 0xC1, 0xE0, 0x03, 0x01, 0xD0, 0x29, 0xC1, 0x89, 0xCA, 0x8B, 0x85, 0xE4, 0xFE, 0xFF, 0xFF, 0x48, 0x98, 0x0F, 0xB6, 0x44, 0x05, 0xB0, 0x01, 0xD0, 0x83, 0xC0, 0x02, 0x31, 0xF0, 0x88, 0x85, 0xD7, 0xFE, 0xFF, 0xFF, 0x8B, 0x85, 0xE4, 0xFE, 0xFF, 0xFF, 0x83, 0xE8, 0x01, 0x48, 0x98, 0x0F, 0xB6, 0x95, 0xD7, 0xFE, 0xFF, 0xFF, 0x88, 0x90, 0xD0, 0x40, 0x60, 0x00, 0x83, 0x85, 0xE4, 0xFE, 0xFF, 0xFF, 0x01, 0x83, 0xBD, 0xE4, 0xFE, 0xFF, 0xFF, 0x1F, 0x0F, 0x8E, 0x67, 0xFF, 0xFF, 0xFF, 0x0F, 0xB6, 0x45, 0xCF, 0x3C, 0xC4, 0x75, 0x48, 0xC7, 0x85, 0xE8, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x33, 0x8B, 0x85, 0xE8, 0xFE, 0xFF, 0xFF, 0x48, 0x98, 0x0F, 0xB6, 0x90, 0xD0, 0x40, 0x60, 0x00, 0x8B, 0x85, 0xE8, 0xFE, 0xFF, 0xFF, 0x48, 0x98, 0x0F, 0xB6, 0x80, 0x00, 0x41, 0x60, 0x00, 0x38, 0xC2, 0x74, 0x0A, 0xC7, 0x85, 0xE0, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0xE8, 0xFE, 0xFF, 0xFF, 0x01, 0x83, 0xBD, 0xE8, 0xFE, 0xFF, 0xFF, 0x1E, 0x7E, 0xC4, 0x8B, 0x85, 0xE0, 0xFE, 0xFF, 0xFF, 0x48, 0x8B, 0x4D, 0xF8, 0x64, 0x48, 0x33, 0x0C, 0x25, 0x28, 0x00, 0x00, 0x00, 0x74, 0x05, 0xE8, 0x18, 0xDF, 0xFF, 0xFF, 0xC9, 0xC3, 0x55, 0x48, 0x89, 0xE5, 0x48, 0x81, 0xEC, 0x40, 0x01, 0x00, 0x00, 0x64, 0x48, 0x8B, 0x04, 0x25, 0x28, 0x00, 0x00, 0x00, 0x48, 0x89, 0x45, 0xF8, 0x31, 0xC0, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xD5, 0xFB, 0xFF, 0xFF, 0x48, 0x8D, 0x85, 0x70, 0xFF, 0xFF, 0xFF, 0x48, 0x89, 0xC6, 0xBF, 0xEC, 0x2F, 0x40, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0xE9, 0xDE, 0xFF, 0xFF, 0x48, 0x8D, 0x85, 0x70, 0xFF, 0xFF, 0xFF, 0x48, 0x89, 0xC7, 0xE8, 0xBA, 0xDE, 0xFF, 0xFF, 0x89, 0x85, 0xC4, 0xFE, 0xFF, 0xFF, 0x83, 0xBD, 0xC4, 0xFE, 0xFF, 0xFF, 0x10, 0x74, 0x14, 0xBF, 0xE5, 0x2F, 0x40, 0x00, 0xE8, 0x51, 0xDE, 0xFF, 0xFF, 0xBF, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x57, 0xDE, 0xFF, 0xFF, 0x48, 0xC7, 0x85, 0xC8, 0xFE, 0xFF, 0xFF, 0xF1, 0x2F, 0x40, 0x00, 0x48, 0x8D, 0x95, 0x50, 0xFF, 0xFF, 0xFF, 0x48, 0x8B, 0x85, 0xC8]
length=0x23c
f=open("babyre",mode="rb+")
for i in range(0x23c):
f.seek(0x272d+i,0)
new_byte=chr(a[i])
f.write(new_byte)
最后一段算法有多解,利用回溯搜索算法解出全部可能后
#include
#include
unsigned char key[17] = "th1s1sth3n1c3k3y";
unsigned char input[32] = "";
unsigned char byte_604100[31] = {
0xBD, 0xAD, 0xB4, 0x84, 0x10, 0x63, 0xB3, 0xE1, 0xC6, 0x84, 0x2D, 0x6F, 0xBA, 0x88, 0x74, 0xC4,
0x90, 0x32, 0xEA, 0x2E, 0xC6, 0x28, 0x65, 0x70, 0xC9, 0x75, 0x78, 0xA0, 0x0B, 0x9F, 0xA6
};
void back_tracking(int row)
{
if (row == 31)
{
for(int i=0;i<32;i++)
printf("0x%02x,", input[i]);
system("pause");
}
for (int k = 31 - row; k >= 1;)
{
for (unsigned char a = 0; a < 0xff; a++)
{
input[k - 1] = a;
//printf("%x\n", a);
unsigned char result = (2 * (input[k - 1] ^ 0x13) + 7) ^ ((unsigned __int8)input[k - 1] % 9u + input[k] + 2);
if (result == byte_604100[k - 1])
{
//printf("input%d:%x\n", k - 1, a);
back_tracking(row + 1);
}
}
//back_tracking(row - 1);
return;
}
}
int main()
{
input[31] = 0xc4;
back_tracking(0);
getchar();
}
//4d775e0ffe00d4ebb0c06e897af2f51873ee935b86b962ec897c11d00734b2c8
一组一组带到如下脚本里,去AES解密
int main()
{
unsigned char key[17] = "th1s1sth3n1c3k3y";
unsigned char input[32] = {
0x4d,0x77,0x5e,0x0f,0xb3,0x4d,0x99,0xa6,0x8a,0xfa,0x54,0xb3,0x1e,0x96,0x91,0x7c,0x18,0x85,0xf8,0x30,0x5e,0x61,0xba,0x34,0x1c,0xe9,0x84,0x45,0x0b,0x38,0xbe,0xc4 };
printf("\n");
for (int i = 31; i >= 0; i--)
{
for (int j = 0; i / 4 > j; ++j)
{
input[i] ^= input[j];
}
}
for (int i = 0; i < 32; i++)
{
printf("%02x", input[i]);
}
printf("\n");
for (int i = 0; i < 16; i++)
{
printf("%02x", key[i]);
}
getchar();
}
最后解到flag
GWHT{th1s_gam3_1s_s0_c00l_and_d}
一共三段加密,第一段是base64,第二段是将数据分为四段重新组合,第三段是将数据进行移位
第三段解密脚本
第一段解密
#include
int main()
{
char v5;
char a[100] = {
0,};
char b[100] = {
0,};
char *v7 = a;
char *v8 = b;
char result[] = "EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG";
for (int j = 0; j < sizeof(result); j++)
{
for (char i = 0x20; i <= 0x7b; i++)
{
*v8 = i;
v5 = *v8;
if (*v8 <= 0x40 || v5 > 0x5A)
{
if (v5 <= 0x60 || v5 > 0x7A)
{
if (v5 <= 0x2F || v5 > 0x39)
*v7 = v5;
else
*v7 = (v5 - 0x30 + 3) % 10 + 0x30;
}
else
{
*v7 = (v5 - 0x61 + 3) % 26 + 0x61;
}
}
else
{
*v7 = (v5 - 0x41 + 3) % 26 + 0x41;
}
if (*v7 == result[j])
{
++v7;
++v8;
printf("%c", v5);
break;
}
}
}
将结果分为四组重新拼接
R1dIVHs2NzJjYzQ3NzhhMzhlODBjYjM2Mjk4NzM0MTEzM2VhMn0=
再base64解密得到结果