因为期中考试(寄)所以很多题目没来得及复现,汇编也没学,感觉自己又变菜了qwq
hard
直接扔进Ida64查字符串/查汇编/查代码都可以得到flag:HECTF{HElLo_RRRRe}
baby_upx
尝试用指令脱壳失败,本来打算手动脱壳,但是后来偶然发现了upx-3.9.6封装好的一个脱壳软件,居然给脱出来了。
反编译得到源代码:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
char String[26]; // [esp+1Eh] [ebp-46h] BYREF
int v6; // [esp+38h] [ebp-2Ch]
_DWORD v7[5]; // [esp+3Ch] [ebp-28h] BYREF
char *v8; // [esp+50h] [ebp-14h]
const char *v9; // [esp+54h] [ebp-10h]
char i; // [esp+5Bh] [ebp-9h]
int v11; // [esp+5Ch] [ebp-8h]
sub_401AD0();
v7[0] = 2099915543;
v7[1] = 120201498;
v7[2] = 269490557;
v7[3] = 67837461;
v7[4] = 271401;
v9 = (const char *)v7;
puts("Similarly, this is also a challenge for beginners");
*(_DWORD *)String = 0;
v6 = 0;
v3 = 0;
do
{
*(_DWORD *)&String[v3 + 2] = 0;
v3 += 4;
}
while ( v3 < ((String - &String[2] + 30) & 0xFFFFFFFC) );
printf("Now, please enter your flag: ");
scanf("%30s", String);
v11 = 0;
v8 = strtok(String, "{");
if ( strcmp(v8, "HECTF") )
goto LABEL_10;
v8 = strtok(0, "}");
if ( !v8 )
goto LABEL_10;
for ( i = v8[v11]; i; i = v8[v11] )
{
i ^= String[(v11 ^ (rand() + 10086)) % 5];
v8[v11++] = i;
}
if ( !strcmp(v8, v9) )
puts("Success!");
else
LABEL_10:
puts("Wrong!");
return 0;
}
首先查询strtok函数的用法,发现是把HECTF{}这几个字符给去掉。
发现输入语句之前的都是初始化,可以不用管,关键代码如下:
for ( i = v8[v11]; i; i = v8[v11] )
{
i ^= String[(v11 ^ (rand() + 10086)) % 5];
v8[v11++] = i;
}
我们发现v11是递增的
i ^= String[(v11 ^ (rand() + 10086)) % 5];
v8[v11++] = i;
其实就是v9[v11]=v8[v11]^string(v11^(rand()+10086))%5]
那么v8[v11]=v9[v11]^string(v11^(rand()+10086))%5]
可以发现有个rand()函数,这是一个假随机数,只要种子是一样的rand出来的数就是一样的,可以预处理出rand数组。
然后发现v8数组在通过这个循环结构后变成了v9,而v9直接copy源代码即可得到,由此得出exp:
#include<bits/stdc++.h>
#define I inline
using namespace std;
unsigned int v7[6];
const char *v9;
char *v8;
char hectf[7]="HECTF{";
char flag[30];
int random[55];
int len;
I void make_rand(){for(int i=0;i<=50;i++)random[i]=rand();}
int main()
{
v7[0]=2099915543;
v7[1]=120201498;
v7[2]=269490557;
v7[3]=67837461;
v7[4]=271401;
v9=(const char *)v7;
make_rand();
for(int i=0;i<=18;i++)
{
flag[i]=v9[i]^hectf[(i^(random[i]+10086))%5];
}
for(int i=0;i<=18;i++)cout<<flag[i];
}
得到flag:
HECTF{Thi5_iiS5_UUPX_LalA}
baby_pp
查壳发现用python打包的。
用pyinstxtractor进行解包:
得到main.pyc,用uncompyle6反编译(在线反编译出锅,比赛的时候反编译出来少了很多东西,后来用uncompyle6就可以了)
查看python源代码:
# uncompyle6 version 3.8.0
# Python bytecode 3.8.0 (3413)
# Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: main.py
import random
ens = '742641edefb6770733ab5932325106b3a5fa75222791d09e451161c46f15504402b32737362443d4df7d136145cd970b54116669c230'
def encode(s, nuum):
step = len(s) // nuum
ens = ''
for i in range(step):
ens += s[i::step]
else:
return ens
def main():
random.seed(10085)
u_input = input(': ')
t = ''
for i in u_input:
t += '%02x' % (ord(i) ^ random.randint(0, 127))
else:
eni = encode(t, 6)
if eni == ens:
print('Success!')
else:
print('Failed!')
if __name__ == '__main__':
main()
首先分析encode函数:
ens = '742641edefb6770733ab5932325106b3a5fa75222791d09e451161c46f15504402b32737362443d4df7d136145cd970b54116669c230'
def encode(s, nuum):
step = len(s) // nuum #ens长度为108,返回值得到eni=ens,同时该函数并没有对字符串长度进行改变,推出len(s)=108,nuum=6,step=18
ens = ''
for i in range(step):
ens += s[i::step] #每隔18位从s中选一个值(这里的ens和全局变量ens应该不是一个),那么也就相当于ens中的
#前0-5分别对应s中的0,0+18-1,0+2*18-1...
#前6-11分别对应s中的1,1+18-1,1+2*18-1...
else:
return ens
由此可以有ens(全局)decode出eni:
str = '742641edefb6770733ab5932325106b3a5fa75222791d09e451161c46f15504402b32737362443d4df7d136145cd970b54116669c230'
eni= ''
for i in range(0,6):
eni+= str[i::6]
print("eni="+eni)
得到eni=7e7a3b794c5b3d1c564d7b23515403643d492e055a2d16422d691c6f7915201f474f17124b330f29610347406316326a7e15273d5b60
注意到源代码中这一句:
for i in u_input:
t += '%02x' % (ord(i) ^ random.randint(0, 127))
'%02x'是把t转成两位16进制之后进行异或运算,最后得到eni,再encode得到ens。
此时我们已经得到了eni,应该是一个两位16进制数,手动转码之后异或写出exp:
import random
random.seed(10085)
ens = [0x7e,0x7a,0x3b,0x79,0x4c,0x5b,0x3d,0x1c,0x56,0x4d,0x7b,0x23,0x51,0x54,0x03,0x64,0x3d,0x49,0x2e,0x05,0x5a,0x2d,0x16,0x42,0x2d,0x69,0x1c,0x6f,0x79,0x15,0x20,0x1f,0x47,0x4f,0x17,0x12,0x4b,0x33,0x0f,0x29,0x61,0x03,0x47,0x40,0x63,0x16,0x32,0x6a,0x7e,0x15,0x27,0x3d,0x5b,0x60]
t = ''
for i in range(len(ens)):
t +=chr(ens[i] ^ random.randint(0, 127))
else:
print(t)
得到虚假的flag:HECTF{decrypt(80410840840842108808881088408084210842)}
最后是某crypto大佬一眼看出云影密码(01248密码),当场学习一波(白嫖一份解密脚本)
a="80410840840842108808881088408084210842"
a=a.split("0")
flag=''
for i in range(0,len(a)):
str = a[i]
list=[]
sum=0
for j in str:
list.append(j)
length = len(list)
for k in range(0,length):
sum+=int(list[k])
flag+=chr(sum+64)
print(flag)
运行得到flag:HELLOPYTHON