REVERSE-PRACTICE-BUUCTF-22

[SCTF2019]Who is he

unity游戏,运行后输入,点击按钮检验输入
dnSpy打开Who is he\Who is he_Data\Managed\Assembly-CSharp.dll
在TestClick类中找到OnClick方法,将输入与Decrypt方法返回的字符串比较
whoishe-logic
Decrypt方法,标准的DES.CBC解密,iv=key
whoishe-decrypt
已知密钥"1234",密文"1Tsy0ZGotyMinSpxqYzVBWnfMdUcqCMLu0MA+22Jnp+MNwLHvYuFToxRQr0c+ONZc6Q7L0EAmzbycqobZHh4H23U4WDTNmmXwusW4E+SZjygsntGkO2sGA==",解DES.CBC,注意,在C#中,字符串转成字节数组,在每个字符字节后都要加一个"\x00",然而提交明文失败

from Crypto.Cipher import DES
import base64
key=''.join(['1','\x00','2','\x00','3','\x00','4','\x00'])
cipher=base64.b64decode("1Tsy0ZGotyMinSpxqYzVBWnfMdUcqCMLu0MA+22Jnp+MNwLHvYuFToxRQr0c+ONZc6Q7L0EAmzbycqobZHh4H23U4WDTNmmXwusW4E+SZjygsntGkO2sGA==")
iv=key
des=DES.new(key,DES.MODE_CBC,iv)
plaintext=des.decrypt(cipher)
print(plaintext.decode('utf-16'))
#He_P1ay_Basketball_Very_We11!Hahahahaha!

看了别的师傅的wp,使用ce,搜索字符串"Emmmmm",在内存中发现完全不同的密文和密钥
whoishe-ce
解DES.CBC得到flag,提交成功

from Crypto.Cipher import DES
import base64
key=''.join(['t','\x00','e','\x00','s','\x00','t','\x00'])
data="78 00 5A 00 57 00 44 00 5A 00 61 00 4B 00 45 00 68 00 57 00 4E 00 4D 00 43 00 62 00 69 00 47 00 59 00 50 00 42 00 49 00 6C 00 59 00 33 00 2B 00 61 00 72 00 6F 00 7A 00 4F 00 39 00 7A 00 6F 00 6E 00 77 00 72 00 59 00 4C 00 69 00 56 00 4C 00 34 00 6E 00 6A 00 53 00 65 00 7A 00 32 00 52 00 59 00 4D 00 32 00 57 00 77 00 73 00 47 00 6E 00 73 00 6E 00 6A 00 43 00 44 00 6E 00 48 00 73 00 37 00 4E 00 34 00 33 00 61 00 46 00 76 00 4E 00 45 00 35 00 34 00 6E 00 6F 00 53 00 61 00 64 00 50 00 39 00 46 00 38 00 65 00 45 00 70 00 76 00 54 00 73 00 35 00 51 00 50 00 47 00 2B 00 4B 00 4C 00 30 00 54 00 44 00 45 00 2F 00 34 00 30 00 6E 00 62 00 55 00 3D"
cipher=[]
for i in range(0,len(data),6):
    cipher.append(int('0x'+data[i:i+2],16))
iv=key
des=DES.new(key,DES.MODE_CBC,iv)
plaintext=des.decrypt(base64.b64decode(''.join(chr(i) for i in cipher)))
print(plaintext.decode('utf-16'))
#She_P1ay_Black_Hole_Very_Wel1!LOL!XD!

[FlareOn2]very_success

exe程序,运行后输入password,无壳,ida分析
sub_401000函数修改栈指针平衡栈后,F5反编译
读取输入,进入sub_401084函数进行验证,返回非0验证成功
verysuccess-logic
进入sub_401084函数,检验输入的长度是否大于等于37,输入input参与的只是8位的异或运算,v14为0xc7,v10在运算过程中始终为1,v4初始为0,每次都要加一个字节参与运算后的结果
verysuccess-sub_401084
v7可通过动调得到,只有32个字节可见,不过影响不大,写逆脚本即可得到flag,缺的5个字符按照Description文本文件提示补齐

v7=[0xAA, 0xEC, 0xA4, 0xBA, 0xAF, 0xAE, 0xAA, 0x8A, 0xC0, 0xA7,
  0xB0, 0xBC, 0x9A, 0xBA, 0xA5, 0xA5, 0xBA, 0xAF, 0xB8, 0x9D,
  0xB8, 0xF9, 0xAE, 0x9D, 0xAB, 0xB4, 0xBC, 0xB6, 0xB3, 0x90,
  0x9A, 0xA8]
v7=v7[::-1]
flag=""
v4=0
for i in range(len(v7)):
    tmp=(1<<(v4&0x3))
    flag+=chr((v7[i]-tmp-1)^0xc7)
    v4+=v7[i]
print(flag)
#a_Little_b1t_harder_plez@flare-o(n.com})

[NPUCTF2020]Baby Obfuscation

exe程序,运行后输入,无壳,ida分析
main函数,输入后紧接的for循环,有4个if语句,其中第1和第3个if语句永真,第2和第4个if语句永假,于是,与输入相关的运算有两处,"v33[j]=input[j-1]-v39[(j-1)%len(v39)]"给v33赋值,"v33[j]^=v39[(j-1)%len(v39)]"是v33的变换,v33的元素乘10后再与已知比较

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  int v4; // ebx
  int v5; // esi
  int v6; // ebx
  int v7; // ebx
  int v8; // esi
  int v9; // edi
  int v10; // ebx
  int v11; // ebx
  int v12; // ebx
  int v13; // esi
  int v14; // eax
  int v15; // ebx
  int v16; // esi
  int v17; // ebx
  int v18; // eax
  bool v19; // bl
  int v20; // eax
  int v21; // esi
  int v22; // ebx
  int v23; // ebx
  int v24; // eax
  int v25; // eax
  int v26; // eax
  int v27; // eax
  int v28; // ebx
  int a[64]; // [rsp+20h] [rbp-60h]
  int v31; // [rsp+120h] [rbp+A0h]
  char input[1008]; // [rsp+130h] [rbp+B0h]
  int v33[1000]; // [rsp+520h] [rbp+4A0h]
  int v34; // [rsp+14C0h] [rbp+1440h]
  int v35; // [rsp+14D0h] [rbp+1450h]
  int v36; // [rsp+14D4h] [rbp+1454h]
  int v37; // [rsp+14D8h] [rbp+1458h]
  int v38; // [rsp+14DCh] [rbp+145Ch]
  int v39; // [rsp+14E0h] [rbp+1460h]
  int v40; // [rsp+14E4h] [rbp+1464h]
  int v41; // [rsp+14E8h] [rbp+1468h]
  int v42; // [rsp+14ECh] [rbp+146Ch]
  int input_len; // [rsp+14F0h] [rbp+1470h]
  int k; // [rsp+14F4h] [rbp+1474h]
  int j; // [rsp+14F8h] [rbp+1478h]
  int i; // [rsp+14FCh] [rbp+147Ch]

  _main();
  memset(v33, 0, sizeof(v33));
  v34 = 0;
  memset(a, 0, sizeof(a));
  v31 = 0;
  for ( i = 0; i <= 64; ++i )                   // a的元素都是固定的值,a[0]==1,a[1]==2
    a[i] = i + 1;
  v39 = 2;
  v40 = 3;
  v41 = 4;
  v42 = 5;
  v35 = 2;
  v36 = 3;
  v37 = 4;
  v38 = 5;
  puts("WHERE IS MY KEY!?");
  scanf("%32s", input);
  input_len = strlen(input);
  v3 = gcd(a[j], a[j]);                         // v3==a[0]==1
  for ( j = v3 / a[j]; j <= input_len; ++j )    // j从1开始,到input_len,双闭合
  {
    v4 = (a[j] + a[j + 1]) * (a[j] + a[j + 1]); // v4==(a[j]+a[j+1])**2
    if ( v4 >= axxb(2, 2) * a[j] * a[j + 1] )   // axxb函数指a**b,a的b次方,(a+b)**2>=4ab,永真
    {
      v5 = ~input[a_sub_b(j, 1)];
      v6 = a_sub_b(j, 1);
      v33[j] = ~(v5 + *(&v39 + v6 % axxb(2, 2)));// v33[j]=input[j-1]-v39[(j-1)%len(v39)]
    }
    v7 = gcd(a[j], a[j + 1]);                   // 永为1
    if ( v7 > gcd(a[j + 1], ~(~a[j + 1] + a[j])) )// gcd(a[j+1],a[j+1]-a[j])==1,永假
    {
      v8 = v33[j];
      v9 = ~v33[j];
      v10 = a_sub_b(j, 1);
      v33[j] = ~(v9 + a[v10 % axxb(2, 2)]) * v8;
    }
    v11 = a[j + 1];
    v12 = axxb(2, 1) * v11;                     // 2*a[j+1]
    v13 = a[j];
    v14 = axxb(2, 1);
    v15 = gcd(v13 * v14, v12);                  // gcd(2*a[j],2*a[j+1])
    v16 = axxb(2, 1);
    if ( v15 == v16 * gcd(a[j], a[j + 1]) )     // 永真
    {
      v17 = a_sub_b(j, 1);                      // j-1
      v33[j] ^= *(&v39 + v17 % axxb(2, 2));     // v33[j]^=v39[(j-1)%len(v39)]
    }
    v18 = axxb(V0X3, a[j]);
    v19 = v18 < a[j] + 1;                       // 3**a[j]<a[j]+1
    v20 = axxb(2, 4);                           // 16
    if ( aeqbeq1(v20 >= j, v19) )               // 永假
    {
      v21 = ~input[a_sub_b(j, 1)];
      v22 = a_sub_b(j, 1);
      v33[j] ^= ~(v21 + *(&v39 + v22 % axxb(2, 2)));
    }
    v23 = axxb(2, 3);                           // 8
    v24 = gcd(a[j], a[j]);                      // a[j]
    v33[j] *= v23 + axxb(2, v24 / a[j]);        // v33[j]*=10
  }
  v25 = axxb(2, 4);                             // 16
  v26 = a_sub_b(v25, 1);                        // 15
  if ( v26 == input_len )                       // input_len==15
  {
    v27 = gcd(a[k], a[k]);                      // 1
    for ( k = v27 / a[k]; k <= input_len; ++k ) // k从1开始,到input_len,双闭合
    {
      v28 = v33[k];                             // 从v33取值
      if ( v28 == a_sub_b(A0X6[k], 1) / 10 )    // 比较
        ++V0X2;
    }
    if ( V0X2 == input_len )
      puts("\nPASS");
    else
      puts("\nDENIED");
  }
  else
  {
    puts("\nDENIED");
  }
  return 0;
}

写逆运算脚本即可得到flag

A0X6=[0,7801,7801,8501, 5901, 8001, 6401, 11501,4601, 9801,  9601,
      11701, 5301,  9701,  10801,  12501]
v39=[2,3,4,5]
for i in range(1,len(A0X6)):
    A0X6[i]=(A0X6[i]-1)//10//10
    A0X6[i]^=v39[(i-1)%len(v39)]
    A0X6[i]+=v39[(i-1)%len(v39)]
print(''.join(chr(i) for i in A0X6))
# NPUCTF{0bfu5er}

[HDCTF2019]MFC

MFC程序,加了vmp壳,用xspy扫一下
发现一个没有系统库名的OnMsg:0464
MFC-xspy
写C代码发送一条有关0x0464的信息

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
int main()
{
	HWND handler = ::FindWindowA(NULL, "Flag就在控件里");
	if (handler)
	{
		SendMessage(handler, 0x0464, NULL, NULL);
	}
	else {
		printf("no window");
	}

	system("pause");
	return 0;
}

看到一个DES的密钥
MFC-deskey
在这个地方看到密文
MFC-cipher
用一个飘云阁的加解密工具解des即可得到flag
MFC-flag

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

P1umH0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值