【CTF Reverse】CTFShow 逆向4 Writeup(反编译+XOR+代换加密)

逆向4

20
感谢@神说要有光 提供的题目


解法

导入 DIE 分析。是一个 PE64 程序。

导入 IDA,反编译 main 函数。

int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{
  qword_140004618 = (__int64)malloc(0x10ui64);
  qword_140004620 = qword_140004618;
  *(_QWORD *)(qword_140004618 + 8) = 0i64;
  sub_140001020("请输入正确的数字:\n");
  sub_140001080("%lld");
  ((void (__fastcall __noreturn *)())sub_1400010E0)();
}

sub_1400010E0 函数应该是用来对输入的数字进行加密。

void __fastcall __noreturn sub_1400010E0(__int64 a1, __int64 a2)
{
  int v2; // r9d
  __int64 v3; // r8
  char *v4; // r10
  char v5; // al
  __int64 v6; // rbx
  unsigned __int8 v7; // cl
  char v8; // [rsp+1Fh] [rbp-3F9h]
  char v9; // [rsp+20h] [rbp-3F8h] BYREF

  v2 = 0;
  v3 = a1;
  if ( a1 )
  {
    v4 = &v9;
    do
    {
      ++v4;
      ++v2;
      v5 = a4890572163qwe[v3 + -26 * (v3 / 26)];
      v3 /= 26i64;
      a2 = v3;
      *(v4 - 1) = v5;
    }
    while ( v3 );
  }
  v6 = v2;
  while ( v6 )
  {
    v7 = *(&v8 + v6--);
    sub_1400011E0(v7 ^ 7u, a2, v3);
  }
  sub_140001220();
}

这里将 v3 转换为 a4890572163qwe 中的值。

v5 = a4890572163qwe[v3 + -26 * (v3 / 26)];

数组 a4890572163qwe 刚好有26个字符,值为:

')(*&^%489$!057@#><:2163qwe'

sub_1400011E0 函数,用于分配内存空间。在调用 sub_1400011E0 时,v7 与 7u 异或。

_QWORD *__fastcall sub_1400011E0(char a1)
{
  _QWORD *result; // rax
  __int64 v3; // rdx

  result = malloc(0x10ui64);
  v3 = qword_140004618;
  qword_140004618 = (__int64)result;
  *(_QWORD *)(v3 + 8) = result;
  *(_BYTE *)v3 = a1;
  result[1] = 0i64;
  return result;
}

sub_140001220 函数,应该是对加密结果进行校验。

void __noreturn sub_140001220()
{
  __int64 v0; // r9
  int v1; // ecx
  __int64 v2; // rdx
  char v3; // al
  int v4; // r8d
  __int64 v5; // r9
  char v6; // cl
  int v7; // eax

  v0 = qword_140004620;
  v1 = 0;
  v2 = 0i64;
  while ( 1 )
  {
    v3 = *(_BYTE *)v0;
    v4 = v1 + 1;
    v5 = *(_QWORD *)(v0 + 8);
    if ( v3 != aV4pY59[v2 - 1] )
      v4 = v1;
    qword_140004620 = v5;
    if ( !v5 )
      break;
    v6 = *(_BYTE *)v5;
    v7 = v4 + 1;
    v0 = *(_QWORD *)(v5 + 8);
    if ( v6 != aV4pY59[v2] )
      v7 = v4;
    qword_140004620 = v0;
    if ( v0 )
    {
      v2 += 2i64;
      v1 = v7;
      if ( v2 < 14 )
        continue;
    }
    goto LABEL_11;
  }
  v7 = v4;
LABEL_11:
  if ( v7 == 14 )
    sub_1400012E0();
  sub_1400012B0();
}

aV4pY59 数组有14个字符,值为:

'/..v4p$$!>Y59-'

sub_1400012E0 函数用来弹出消息框,显示flag认证成功。说明在 sub_140001220 函数中,当 flag 正确时,v7 == 14。

void __noreturn sub_1400012E0()
{
  MessageBoxW(0i64, L"flag认证成功!", "m`淯\b^匬!", 0);
  exit(0);
}

用 C++ 写个解码程序。

#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;

const string S1 = "/..v4p$$!>Y59-";
const string S2 = ")(*&^%489$!057@#><:2163qwe";

int main() {
	long long flag = 0;
	for (auto const i : S1) {
		char c = i ^ 7u;
		int pos = S2.find(c, 0);
		// cout << c << " " << pos << endl;
		flag *= 26;
		flag += pos;
	}
	cout << flag;
	return 0;
}

输出:

2484524302484524302

Flag

flag{2484524302484524302}

声明

本博客上发布的所有关于网络攻防技术的文章,仅用于教育和研究目的。所有涉及到的实验操作都在虚拟机或者专门设计的靶机上进行,并且严格遵守了相关法律法规

博主坚决反对任何形式的非法黑客行为,包括但不限于未经授权的访问、攻击或破坏他人的计算机系统。博主强烈建议每位读者在学习网络攻防技术时,必须遵守法律法规不得用于任何非法目的。对于因使用这些技术而导致的任何后果,博主不承担任何责任

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值