羊城杯-RE

login

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<Windows.h>
#include <iostream>

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加密一下提交

Bytecode

手撕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"

babyre

首先是一个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 <iostream>
#include<Windows.h>
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}

EasyRe

一共三段加密,第一段是base64,第二段是将数据分为四段重新组合,第三段是将数据进行移位

第三段解密脚本

第一段解密

#include <iostream>

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解密得到结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
羊城2020是一场年度的电子竞技赛事,为广大电竞爱好者提供了一个展示技术和激发激情的舞台。今年的羊城聚集了来自全国各地的顶尖电竞选手,他们在各个游戏项目中展现了高水平的操作和战术。 在比赛的文化氛围方面,羊城2020鼓励团队协作和竞争精神,这对于参赛选手来说是一个很好的机会展现自己的技术能力和团队合作能力。此外,组委会还积极倡导公平竞赛,严禁使用任何形式的作弊或不正当手段来获取胜利,从而保证了比赛的公正性。 羊城2020不仅是一场竞技比赛,还提供了丰厚的奖金和荣誉,吸引了众多顶尖选手参与其中。参赛选手们通过紧张刺激的比赛,展现了他们的技术实力和战术策略。同时,比赛也为电竞爱好者们提供了一个观赏比赛和学习经验的机会,让他们更好地了解电竞运动,提高自己的技术水平。 此外,羊城2020还注重了普及电竞文化的意义。比赛在各个媒体平台上进行直播,使更多的观众能够通过网络或电视观看比赛,增加了电竞的曝光度。通过各种推广活动,羊城2020吸引了更多非电竞爱好者的关注,提高了电竞在社会中的认可度和影响力。 总的来说,羊城2020是一场令人期待的电竞盛事,它不仅展示了顶尖选手们的实力和技巧,也推广了电竞文化并吸引了更多人的关注。这样的比赛将继续推动电竞行业的发展和壮大,为电竞爱好者们带来更多的精彩赛事和娱乐体验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值