31.[WUSTCTF2020]level1
得到的 flag 请包上 flag{} 提交。
感谢 Iven Huang 师傅供题。
比赛平台:https://ctfgame.w-ais.cn/
给了一个ELF和一个txt,txt是一串数字,共有19个,ELF无壳,IDA打开找到main函数,F5大法
简单分析,打开flag.txt,进入循环,单数进入if,双数进入else,最后得到的数字输出并保存为output.txt,反过来即可
enc = [198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782,65536000]
flag = ''
for i in range(1,len(enc)+1):
if(i%2==1):
flag += chr(enc[i-1]>>i)
else:
flag += chr(enc[i-1]//i)
print(flag)
flag{d9-dE6-20c}
32.[GWCTF 2019]xxor
得到的 flag 请包上 flag{} 提交。
IDA打开,main函数F5
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
signed int i; // [rsp+8h] [rbp-68h]
signed int j; // [rsp+Ch] [rbp-64h]
__int64 v6; // [rsp+10h] [rbp-60h]
__int64 v7; // [rsp+18h] [rbp-58h]
__int64 v8; // [rsp+20h] [rbp-50h]
__int64 v9; // [rsp+28h] [rbp-48h]
__int64 v10; // [rsp+30h] [rbp-40h]
__int64 v11; // [rsp+40h] [rbp-30h]
__int64 v12; // [rsp+48h] [rbp-28h]
__int64 v13; // [rsp+50h] [rbp-20h]
__int64 v14; // [rsp+58h] [rbp-18h]
__int64 v15; // [rsp+60h] [rbp-10h]
unsigned __int64 v16; // [rsp+68h] [rbp-8h]
v16 = __readfsqword(0x28u);
puts("Let us play a game?");
puts("you have six chances to input");
puts("Come on!");
v6 = 0LL;
v7 = 0LL;
v8 = 0LL;
v9 = 0LL;
v10 = 0LL;
for ( i = 0; i <= 5; ++i )
{
printf("%s", "input: ", (unsigned int)i);
a2 = (char **)((char *)&v6 + 4 * i);
__isoc99_scanf("%d", a2);
}
v11 = 0LL;
v12 = 0LL;
v13 = 0LL;
v14 = 0LL;
v15 = 0LL;
for ( j = 0; j <= 4; j += 2 )
{
dword_601078 = *((_DWORD *)&v6 + j);
dword_60107C = *((_DWORD *)&v6 + j + 1);
a2 = (char **)&unk_601060;
sub_400686(&dword_601078, &unk_601060);
*((_DWORD *)&v11 + j) = dword_601078;
*((_DWORD *)&v11 + j + 1) = dword_60107C;
}
if ( (unsigned int)sub_400770(&v11, a2) != 1 )
{
puts("NO NO NO~ ");
exit(0);
}
puts("Congratulation!\n");
puts("You seccess half\n");
puts("Do not forget to change input to hex and combine~\n");
puts("ByeBye");
return 0LL;
}
分段分析
要输入6个数字em
输入的数字赋值到a2,来到关键部分
是将v6-v9部分进行变换然后赋值给v11-v15,然后进入sub_400770函数进行判断,先查看判断的函数
啊这,相当于已经给了三个,只需要算出剩下三个,正好三个方程,解方程
a1[0]=0xDF48EF7E
a1[1]=550153460
a1[5]=0x84F30420
a[2]=3774025685
a[3]=1548802262
a[4]=2652626477
因为在函数sub_400770中是有符号整数,而在加密函数中是无符号整数,所以需要把a1[0]和a1[5]转成无符号整数,即
a1[0]=3746099070
a1[5]=2230518816
然后现在返过去看看sub_400686函数,其中要求输入的unk_601060已给出,为2 2 3 4
是将输入的数进行异或然后得到之前的数,所以只需要反过来即可,写脚本
(写了python之后怎么运行都不对,看了WP别人用的C我用的python,但是方法都是一样的…也不知道为啥,只好写C了…)
(两天后的补充:貌似是因为python的是signed int,而之前说了要用unsigned int…,只能写C了(dbq,人麻了,这次直接搬别人的脚本了))
#include <stdio.h>
int main()
{
unsigned int xorm[6];
xorm[0] = 3746099070;
xorm[1] = 550153460;
xorm[2] = 3774025685;
xorm[3] = 1548802262;
xorm[4] = 2652626477;
xorm[5] = 2230518816;
int i = 0,j=0,sum;
unsigned int temp[2] = {0};
unsigned int data[4] = { 2,2,3,4 };
for (i = 0; i < 5; i += 2)
{
temp[0] = xorm[i];
temp[1] = xorm[i + 1];
sum = 0x458BCD42 * 64;
for (j = 0; j < 64; j++)
{
temp[1] -= (temp[0] + sum + 20) ^ ((temp[0] << 6) + 3) ^ ((temp[0] >> 9) + 4) ^ 0x10;
temp[0] -= (temp[1] + sum + 11) ^ ((temp[1] << 6) + 2) ^ ((temp[1] >> 9) + 2) ^ 0x20;
sum -= 0x458BCD42;
}
xorm[i] = temp[0];
xorm[i + 1] = temp[1];
}
for (i = 0; i < 6; i++)
printf("%x",xorm[i]);
}
flag{re_is_great!}