[buuctf][MRCTF2020]Transform

[MRCTF2020]Transform

解析

先放入工具中,发现是是64位无壳的一个可执行文件,拖入ida中进行查看,有mian函数,进入main函数中。

// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rdx
  __int64 v4; // rdx
  char v6[104]; // [rsp+20h] [rbp-70h]
  int j; // [rsp+88h] [rbp-8h]
  int i; // [rsp+8Ch] [rbp-4h]

  sub_402230(argc, argv, envp);
  sub_40E640(argc, (__int64)argv, v3, (__int64)"Give me your code:\n");
  sub_40E5F0(argc, (__int64)argv, (__int64)v6, (__int64)"%s");
  if ( strlen(*(const char **)&argc) != 33 )
  {
    sub_40E640(argc, (__int64)argv, v4, (__int64)"Wrong!\n");
    system(*(const char **)&argc);
    exit(argc);
  }
  for ( i = 0; i <= 32; ++i )
  {
    byte_414040[i] = v6[dword_40F040[i]];
    v4 = i;
    byte_414040[i] ^= LOBYTE(dword_40F040[i]);
  }
  for ( j = 0; j <= 32; ++j )
  {
    v4 = j;
    if ( aGyURsywBFbLwya[j] != byte_414040[j] )
    {
      sub_40E640(argc, (__int64)argv, j, (__int64)"Wrong!\n");
      system(*(const char **)&argc);
      exit(argc);
    }
  }
  sub_40E640(argc, (__int64)argv, v4, (__int64)"Right!Good Job!\n");
  sub_40E640(argc, (__int64)argv, (__int64)v6, (__int64)"Here is your flag: %s\n");
  system(*(const char **)&argc);
  return 0;
}

中间的主要逻辑在于for ( i = 0; i <= 32; ++i ),第二个for开始比较了,从前往后开始看。

  sub_40E640(argc, (__int64)argv, v3, (__int64)"Give me your code:\n");
  sub_40E5F0(argc, (__int64)argv, (__int64)v6, (__int64)"%s");

这两个地方很明显,就是你输入的进行一个保存,之后继续往下。

  if ( strlen(*(const char **)&argc) != 33 )
  {
    sub_40E640(argc, (__int64)argv, v4, (__int64)"Wrong!\n");
    system(*(const char **)&argc);
    exit(argc);
  }

判断你的输入的长度是否是33.

 for ( i = 0; i <= 32; ++i )
  {
    byte_414040[i] = v6[dword_40F040[i]];
    v4 = i;
    byte_414040[i] ^= LOBYTE(dword_40F040[i]);
  }

一个操作,先按照dword_40F040的方式进行排序,之后进行异或。

 for ( j = 0; j <= 32; ++j )
  {
    v4 = j;
    if ( aGyURsywBFbLwya[j] != byte_414040[j] )
    {
      sub_40E640(argc, (__int64)argv, j, (__int64)"Wrong!\n");
      system(*(const char **)&argc);
      exit(argc);
    }
  }

检查你输入的是否跟aGyURsywBFbLwya相等,要是不等输出wrong退出,那么主要问题就是在aGyURsywBFbLwya是多少,之后aGyURsywBFbLwya是。

.data:000000000040F0E0 aGyURsywBFbLwya db 'gy{',7Fh,'u+<RSyW^]B{-*fB~LWyAk~e<\EobM',0

dword_40F040是。

.data:000000000040F040 dword_40F040 dd 9, 0Ah, 0Fh, 17h, 7, 18h, 0Ch, 6, 1, 10h, 3, 11h, 20h, 1Dh, 0Bh, 1Eh
.data:000000000040F040                                         ; DATA XREF: main+79↑o
.data:000000000040F040                                         ; main+B8↑o
.data:000000000040F040 dd 1Bh, 16h, 4, 0Dh, 13h, 14h, 15h, 2, 19h, 5, 1Fh, 8, 12h, 1Ah, 1Ch, 0Eh
.data:000000000040F040 dd 0, 0, 0, 0, 0, 0, 0, 0

之后反推即可。
aGyURsywBFbLwya异或dword_40F040,之后按照dword_40F040进行排序

脚本

dword_40F040 = [0x9, 0x0A, 0x0F, 0x17, 0x7, 0x18, 0x0C, 0x6, 0x1, 0x10, 0x3, 0x11, 0x20, 0x1D, 0x0B, 0x1E, 0x1B, 0x16, 0x4, 0x0D, 0x13, 0x14, 0x15, 0x2, 0x19, 0x5, 0x1F, 0x8, 0x12, 0x1A, 0x1C, 0x0E, 0]
aGyURsywBFbLwya = [0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53,0x79,0x57,0x5E,0x5D,0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E, 0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E,0x65,0x3C,0x5C,0x45, 0x6F, 0x62, 0x4D]
flag = [0]*33

for i in range(len(dword_40F040)):
    aGyURsywBFbLwya[i] ^= dword_40F040[i]

for i in range(len(dword_40F040)):
    flag[dword_40F040[i]] = aGyURsywBFbLwya[i]
print (''.join([chr(x) for x in flag]))

运行可以获得MRCTF{Tr4nsp0sltiON_Clph3r_1s_3z}。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

逆向萌新

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

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

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

打赏作者

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

抵扣说明:

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

余额充值