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了
image.png

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;
}
Last modification:June 29, 2021
如果觉得我的文章对你有用,请随意赞赏。咖啡(12RMB)进度+100%,一块巧克力(1RMB)进度+6%。
(赞赏请备注你的名称哦!后台记录中来自理工小菜狗)