dasctf2021-reverse-wp
re3-Enjoyit-1
基本分析
使用dnspy 32x进行分析即可。思路是解出input值,然后动调跳过10万秒的等待得到flag(有人单纯模拟真是慢死了)。
Console.WriteLine("Welcome to my room, and please enjoy some tea by write what you want in this machine:");
string text2 = Console.ReadLine();
if (!b.b(text2))
{
Thread.Sleep(1000000);
}
if (b.c(text2) != "yQXHyBvN3g/81gv51QXG1QTBxRr/yvXK1hC=")
{
Console.WriteLine("Oops");
Thread.Sleep(1000000);
}
Console.WriteLine("And,wait a second!");
for (int i = 0; i < 100000; i++)
{
Thread.Sleep(1000);
Console.WriteLine(i + 1);
}
a_ = Encoding.Default.GetBytes(text2);
b.b(ref array3, a_);
Console.WriteLine("Here is your tea, and flag!");
text += array3[0].ToString("x2");
text += array3[1].ToString("x2");
array = Encoding.Default.GetBytes(text);
Console.Write("flag{");
for (int j = 0; j < 32; j++)
{
byte[] array4 = array2;
int num = j;
array4[num] ^= array[j % array.Length];
}
Console.Write(Encoding.Default.GetString(array2));
Console.Write("}");
期中关键是b.c(text2)
,之后的sleep就动调跳过即可。
b.c(text2)
我比赛的时候没做出来就是因为看错了以为是标准表
public string a = "abcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ=";
public string c(string A_0)
{
string text = "";
int num = A_0.Length / 3;
int i;
for (i = 0; i < num; i++)
{
byte index = Convert.ToByte((int)('?' & A_0[i * 3] >> 2));
byte index2 = Convert.ToByte((int)((int)(A_0[i * 3] & '\u0003') << 4 | A_0[1 + i * 3] >> 4));
byte index3 = Convert.ToByte((int)((int)(A_0[1 + i * 3] & '\u000f') << 2 | A_0[2 + i * 3] >> 6));
byte index4 = Convert.ToByte((int)(A_0[2 + i * 3] & '?'));
text += this.a[(int)index].ToString();
text += this.a[(int)index2].ToString();
text += this.a[(int)index3].ToString();
text += this.a[(int)index4].ToString();
}
if (i * 3 < A_0.Length)
{
byte index = Convert.ToByte((int)('?' & A_0[i * 3] >> 2));
byte index2;
byte index3;
byte index4;
if (i * 3 + 1 < A_0.Length)
{
index2 = Convert.ToByte((int)((int)(A_0[i * 3] & '\u0003') << 4 | A_0[i * 3 + 1] >> 4));
index3 = Convert.ToByte((int)((int)(A_0[i * 3 + 1] & '\u000f') << 2));
index4 = 64;
}
else
{
index2 = Convert.ToByte((int)((int)(A_0[i * 3] & '\u0003') << 4));
index3 = 64;
index4 = 64;
}
text += this.a[(int)index].ToString();
text += this.a[(int)index2].ToString();
text += this.a[(int)index3].ToString();
text += this.a[(int)index4].ToString();
}
return text;
}
本质上这个就是一个变表加密,可以使用我写的base64变表解密脚本得到input值:https://gitee.com/poilzero/debase64tc
解密后就能得到输入值:combustible_oolong_tea_plz
sleep 10w秒
有人直接模拟之后的代码,我很是不理解,直接动调修改i的值不就好了
我直接再dnspy循环中下断点然后运行到这的时候把i修改成超过10w的值就直接输出flag了
即flag{4645e180540ffa7a67cfa174cde105a2}
re2-drinkSomeTea
基本分析
使用OD跳过检测nop,我还以为是反调试,然后思雨给我指明了是文件检测,,(winapi)。
文件基本思路是读取png的图片文件,然后加密后保存为png.out文件,我们要做的就是逆推。
据思雨说涉及TEA算法,然后核心加密代码如下,有很多部分反编译错误loc需要自行更正Undefine-》analyse-》force-》P(思雨,强!),到此为止我放弃了,思雨哥有深入我就算了。
_DWORD *__cdecl sub_40109F(_DWORD *a1, _DWORD *a2)
{
int v2; // eax
bool v3; // zf
int v4; // ecx
int v5; // edx
_DWORD *result; // eax
int v7; // [esp+Ch] [ebp-14h]
signed int i; // [esp+14h] [ebp-Ch]
int v9; // [esp+18h] [ebp-8h]
int v10; // [esp+1Ch] [ebp-4h]
v9 = 0;
v10 = a1[1];
v7 = *a1;
for ( i = 0; i < 32; ++i )
{
v9 -= 1640531527;
v2 = (a2[1] + (v10 >> 5)) ^ (v9 + v10) ^ (*a2 + 16 * v10);
v3 = v2 + v7 == 0;
v7 += v2;
JUMPOUT(v3, (char *)&loc_401116 + 1);
JUMPOUT(!v3, (char *)&loc_401116 + 1);
MEMORY[0xC22C66A6]();
JUMPOUT(v4 - 1, 0, (char *)&loc_401120 + 1);
v10 += (a2[3] + (v7 >> 5)) ^ (v9 + v7) ^ (a2[2] + v5);
}
a1[1] = v10;
result = a1;
*a1 = v7;
return result;
}
注册机(未复现)
注册机来源:https://zhuanlan.zhihu.com/p/360389931
预计3.29复现
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
//加密函数
void encrypt (int32_t* v, int32_t* k) {
int32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
int32_t delta=0x9e3779b9; /* a key schedule constant */
int32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
// printf("%u %u\n", v0, v1);
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}
//解密函数
void decrypt (int32_t* v, int32_t* k) {
int32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
int32_t delta=0x9e3779b9; /* a key schedule constant */
int32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
int main()
{
char keychar[16] = "flag{fake_flag!}";
FILE* fp;
int32_t k[4];
int32_t v[60000];
int len_v = 0xE500; // 0xE500
int len_block = len_v / sizeof(int32_t);
int i;
memcpy(k, keychar, 16);
fp = fopen("tea.png.out", "rb");
fread(v, sizeof(int32_t), len_block, fp);
fclose(fp);
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
for (i = 0; i < len_block; i += 2) {
decrypt(v + i, k);
// encrypt(v + i, k);
}
fp = fopen("tea.png", "wb");
fwrite(v, sizeof(int32_t), len_block, fp);
fclose(fp);
printf("%u", k[1]);
return 0;
}