一,给阿姨倒一杯卡布奇诺
是一道魔改TEA加密
给出了一些初始化,然后输入的flag拆分,两两一组,通过for循环放入encrypt加密函数
#include <stdio.h>
#define uint32_t unsigned int
void decrypt(uint32_t *v, uint32_t *key)
{
static uint32_t data1 = 0x5F797274;
static uint32_t data2 = 0x64726168;
int i; // [rsp+20h] [rbp-10h]
uint32_t sum; // [rsp+24h] [rbp-Ch]
uint32_t v1; // [rsp+28h] [rbp-8h]
uint32_t v0; // [rsp+2Ch] [rbp-4h]
sum = 0x6E75316C * 32;
uint32_t data1_tmp = v[0];
uint32_t data2_tmp = v[1];
v0 = v[0];
v1 = v[1];
for (i = 31; i >= 0; i--)
{
v1 -= ((v0 >> 5) + key[3]) ^ (v0 + sum) ^ (key[2] + 16 * v0) ^ (sum + i);
v0 -= ((v1 >> 5) + key[1]) ^ (v1 + sum) ^ (key[0] + 16 * v1) ^ (sum + i);
sum -= 0x6E75316C;
}
v[0] = v0 ^ data1;
v[1] = v1 ^ data2;
data1 = data1_tmp;
data2 = data2_tmp;
}
int main()
{
uint32_t key[4]; // [rsp+60h] [rbp-40h] BYREF
uint32_t array[8]; // [rsp+70h] [rbp-30h]
array[0] = 0x9B28ED45;
array[1] = 0x145EC6E9;
array[2] = 0x5B27A6C3;
array[3] = 0xE59E75D5;
array[4] = 0xE82C2500;
array[5] = 0xA4211D92;
array[6] = 0xCD8A4B62;
array[7] = 0xA668F440;
key[0] = 0x65766967;
key[1] = 0x756F795F;
key[2] = 0x7075635F;
key[3] = 0x6165745F;
for (int i = 0; i <= 7; i += 2)
{
decrypt(array + i, key);
}
for(int i=0; i<32; i++)
{
printf("%c", ((char*)array)[i]);
}
return 0;
}
// 133bffe401d223a02385d90c5f1ca377
二,ez_rand
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned __int64 v3; // rbx ,无符号64位整数型
unsigned __int16 v4; // ax , 无符号16位整数型
int v5; // edi
__int64 v6; // rsi
int v7; // eax
int v9[7]; // [rsp+20h] [rbp-50h]
char v10; // [rsp+3Ch] [rbp-34h]
__int16 v11; // [rsp+3Dh] [rbp-33h]
__int128 v12; // [rsp+40h] [rbp-30h]
__int64 v13; // [rsp+50h] [rbp-20h]
int v14; // [rsp+58h] [rbp-18h]
__int16 v15; // [rsp+5Ch] [rbp-14h]
char v16; // [rsp+5Eh] [rbp-12h]
v13 = 0i64;
v12 = 0i64;
v14 = 0;
v15 = 0;
v16 = 0;
print((char *)&Format);
scanf("%s");
v9[0] = -362017699;
v11 = 0;
v3 = -1i64;
v9[1] = 888936774;
v9[2] = 119759538;
v9[3] = -76668318;
v9[4] = -1443698508;
v9[5] = -2044652911;
v9[6] = 1139379931;
v10 = 77;
do
++v3;
while ( *((_BYTE *)&v12 + v3) );
v4 = time64(0i64);
srand(v4);
v5 = 0;
if ( v3 )
{
v6 = 0i64;
do
{
v7 = rand();
if ( (*((_BYTE *)&v12 + v6) ^ (unsigned __int8)(v7
+ ((((unsigned __int64)(2155905153i64 * v7) >> 32) & 0x80000000) != 0i64)
+ ((int)((unsigned __int64)(2155905153i64 * v7) >> 32) >> 7))) != *((_BYTE *)v9 + v6) )
{
print("Error???\n");
exit(0);
}
++v5;
++v6;
}
while ( v5 < v3 );
}
print("Right???\n");
system("pause");
return 0;
}
就是随机数v7与v9异或
随机数种子是通过time来取的,C语言中的srand(time)是伪随机,直接爆破,题目描述给出了flag头为"XYCTF",根据这个信息去爆破随机数种子,即我们将v9的前5位与生成的前五位随机数做异或,如果结果与“XYCTF”相同,则那个随机数种子就是我们需要求的结果
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
unsigned char str[5] = { 0x5D, 0x0C, 0x6C, 0xEA, 0x46 };
unsigned char random[6] = { 0 };
unsigned char flag[6] = { 'X', 'Y', 'C', 'T', 'F', '\0' };
for (int i = 0xFFFF; i >= 0; i--) {
srand(i);
for (int j = 0; j < 5; j++) {
random[j] = rand() % 0xFF;
}
bool found = true;
for (int j = 0; j < 5; j++) {
if ((random[j] ^ str[j]) != flag[j]) {
found = false;
break;
}
}
if (found) {
cout << "Found! It is: " << i << endl;
break;
}
else
cout << "Not " << i << " Nope" << endl;
}
return 0;
}
//Found! It is: 21308
爆破出随机数种子:21308
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
srand(21308);
for (int i = 0; i < 29; i++) {
int num = rand();
cout << num << ",";
}
return 0;
}
//得到随机数4085,19210,5147,22630,16830,25853,6039,15416,9400,1281,32764,16374,8177,18485,16126,29528,5590,4777,18044,26256,25694,24259,10836,5327,13701,7138,5244,22538,13308,
随机数是16位的: 可以int num = rand() % 0xFF ;
得到:16位key
v9=[ 0x5D, 0x0C, 0x6C, 0xEA, 0x46, 0x19, 0xFC, 0x34, 0xB2, 0x62,
0x23, 0x07, 0x62, 0x22, 0x6E, 0xFB, 0xB4, 0xE8, 0xF2, 0xA9,
0x91, 0x12, 0x21, 0x86, 0xDB, 0x8E, 0xE9, 0x43, 0x4D]
key=[5,85,47,190,0,98,174,116,220,6,124,54,17,125,61,203,235,187,194,246,194,34,126,227,186,253,144,98,48]
flag=''
for i in range(len(v9)):
flag+=chr(v9[i]^key[i])
print(flag)
#XYCTF{R@nd_1s_S0_S0_S0_easy!}
为什么就是v12^v7!=v9(?)
三,ez_cube
__int64 sub_140012930()
{
int i; // [rsp+44h] [rbp+24h]
char v2; // [rsp+64h] [rbp+44h]
int v3; // [rsp+84h] [rbp+64h]
sub_140011384(&unk_1400240A2);
for ( i = 0; i < 9; ++i )
{
top[i] = &unk_14001CC24; // red
under[i] = "Blue";
right[i] = "Green";
left[i] = "Orange";
advance[i] = "Yellow";
below[i] = "White";
}
under[1] = &unk_14001CC24;
top[1] = "Green";
right[1] = "Blue";
while ( 1 )
{
do
v2 = getchar();
while ( v2 == 10 );
switch ( v2 )
{
case 'R':
sub_140011375();
break;
case 'U':
sub_1400113BB();
break;
case 'r':
sub_140011366();
break;
case 'u':
sub_14001115E();
break;
}
++dword_14001F1C0;
v3 = j_check();
if ( v3 == 1 )
break;
if ( v3 == 2 )
goto LABEL_19;
}
print(aGreatYouAreAGo);
LABEL_19:
system("pause");
return 0i64;
}
'R' 'U' 'r' 'u'操作每一步
_QWORD *sub_1400117F0()
{
_QWORD *result; // rax
__int64 v1; // [rsp+28h] [rbp+8h]
__int64 v2; // [rsp+48h] [rbp+28h]
__int64 v3; // [rsp+68h] [rbp+48h]
__int64 v4; // [rsp+88h] [rbp+68h]
__int64 v5; // [rsp+A8h] [rbp+88h]
sub_140011384(&unk_1400240A2);
v1 = top[2];
v2 = top[5];
v3 = top[8];
top[2] = below[2];
top[5] = below[5];
top[8] = below[8];
below[2] = left[6];
below[5] = left[3];
below[8] = left[0];
left[0] = advance[8];
left[3] = advance[5];
left[6] = advance[2];
advance[2] = v1;
advance[5] = v2;
advance[8] = v3;
v4 = right[1];
right[1] = right[3];
right[3] = right[7];
right[7] = right[5];
right[5] = v4;
v5 = right[0];
right[0] = right[6];
right[6] = right[8];
right[8] = right[2];
result = right;
right[2] = v5;
return result;
}
嗯,自己玩分析可能有点麻烦,想想应该可以直接写脚本。(自己用c++写了一下,不知道怎么搞四个字符操作那里,有点麻烦)先借一下别人的脚本吧
爆破的脚本还是需要再学一下。
四,What's this
Lua bytecode
可以找一个lua在线反编译网站。Lua 工具箱 (luatool.cn)
应该先变字符然后base64解密 ,发现不对,前面应该还有一些操作
function Xor(num1, num2)
local tmp1 = num1
local tmp2 = num2
local str = ""
repeat
local s1 = tmp1 % 2
local s2 = tmp2 % 2
if s1 == s2 then
str = "0" .. str
else
str = "1" .. str
end
tmp1 = math.modf(tmp1 / 2)
tmp2 = math.modf(tmp2 / 2)
until tmp1 == 0 and tmp2 == 0
return tonumber(str, 2)
end
value = ""
output = ""
i = 1
while true do
local temp = string.byte(flag, i)
temp = string.char(Xor(temp, 8) % 256)
value = value .. temp
i = i + 1
if i > string.len(flag) then
break
end
end
for _ = 1, 1000 do
x = 3
y = x * 3
z = y / 4
w = z - 5
if w == 0 then
print("This line will never be executed")
end
end
for i = 1, string.len(flag) do
temp = string.byte(value, i)
temp = string.char(temp + 3)
output = output .. temp
end
result = output:rep(10)
invalid_list = {
1,
2,
3
}
for _ = 1, 20 do
table.insert(invalid_list, 4)
end
for _ = 1, 50 do
result = result .. "A"
table.insert(invalid_list, 4)
end
for i = 1, string.len(output) do
temp = string.byte(output, i)
temp = string.char(temp - 1)
end
for _ = 1, 30 do
result = result .. string.lower(output)
end
for _ = 1, 950 do
x = 3
y = x * 3
z = y / 4
w = z - 5
if w == 0 then
print("This line will never be executed")
end
end
for _ = 1, 50 do
x = -1
y = x * 4
z = y / 2
w = z - 3
if w == 0 then
print("This line will also never be executed")
end
end
require("base64")
obfuscated_output = to_base64(output)
obfuscated_output = string.reverse(obfuscated_output)
obfuscated_output = string.gsub(obfuscated_output, "g", "3")
obfuscated_output = string.gsub(obfuscated_output, "H", "4")
obfuscated_output = string.gsub(obfuscated_output, "W", "6")
invalid_variable = obfuscated_output:rep(5)
if obfuscated_output == "==AeuFEcwxGPuJ0PBNzbC16ctFnPB5DPzI0bwx6bu9GQ2F1XOR1U" then
print("You get the flag.")
else
print("F**k!")
end
先异或8后+3
import base64
enc='==AeuFEcwxGPuJ0PBNzbC16ctFnPB5DPzI0bwx6bu9GQ2F1XOR1U'
print(enc[::-1])
str=list(enc[::-1])
for i in range(len(str)):
if str[i]=='3':
str[i]='g'
elif str[i]=='4':
str[i]='H'
elif str[i]=='6':
str[i]="W"
print(''.join(str))
ant='U1ROX1F2QG9ubWxwb0IzPD5BPnFtcW1CbzNBP0JuPGxwcEFueA=='
date=base64.b64decode(ant)
flag = ""
for i in date:
flag += chr((i - 3) ^ 8)
print(flag)
#XYCTF{5dcbaed781363fbfb7d8647c1aee6c}