新手如何Reverces(基础ctf教程篇2:如何求解flag)

35 篇文章 5 订阅
本文介绍了四种解密flag的方法,包括直接内存获取、算法逆变操作、线性变换求解(PWN相关)和约束求解。通过实例详细解析了base64编码的逆运算过程,并提供了Python解密脚本。此外,还展示了如何通过分析代码流程来理解加密逻辑。
摘要由CSDN通过智能技术生成

如何求解fla

题目下载



1,直接内存获取

对于一些比较简单的题目,可以通过直接查看内存的方式获取flag。对于这种形式,只需要在比的地方下个断点,然后通过查看内存即刻得到flag。
参考例子:
远程动态调试

2.对算法进行逆变操作

如果一个判断过程的代码如下所示,那么要分析convert的算法,然后分析结果写出对应的逆算法,通过reverse_convert(stardard)方式求得flag

main函数:
在这里插入图片描述
这像base64,因为有=补齐,打开change:
在这里插入图片描述
可以确定是变表的base64,使用python进行逆运算(需要安装pybase64库):

import base64

check = "ms4otszPhcr7tMmzGMkHyFn"
tmp = "ELF8n0BKxOCbj/WU9mwle4cG6hytqD+P3kZ7AzYsag2NufopRSIVQHMXJri51Tdv"
stdbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
check2 = ""

for i in range(len(check)):
    check2 += stdbase64[tmp.index(check[i])]
check2 += "="

print(check2)
flag = base64.b64decode(check2)

print(flag.decode())


3.线性变换求解(偏PWN,并且需要用到liunx,暂时略)

4.约束求解

使用OD打开,跟随GetWindowTextA:
在这里插入图片描述

在这里插入图片描述

f9运行,随便输入数据。栈区回溯:
在这里插入图片描述

回车
在这里插入图片描述

在IDA中找到这个函数:
在这里插入图片描述
发现是CWnd::GetWindowTextA,说明还要回溯一次:
在这里插入图片描述

IDA中找到这个函数,就是main函数了:

int __thiscall sub_4016F0(void *this)
{
  void *v1; // edi
  int v2; // eax
  const char *v3; // eax
  char *v4; // ebp
  signed int v5; // esi
  const char *v6; // esi
  unsigned int len; // ecx
  unsigned int v8; // edx
  int v9; // eax
  signed __int32 v10; // ecx
  bool v11; // zf
  bool v12; // sf
  int v13; // ecx
  BOOL v14; // eax
  signed __int32 v15; // edx
  const char *v17; // [esp+14h] [ebp-41Ch]
  void *v18; // [esp+18h] [ebp-418h]
  int v19; // [esp+1Ch] [ebp-414h]
  char v20; // [esp+20h] [ebp-410h]
  void **v21; // [esp+33Ch] [ebp-F4h]
  BOOL v22; // [esp+3B0h] [ebp-80h]
  int v23; // [esp+42Ch] [ebp-4h]

  v1 = this;
  v18 = this;
  CDialog::CDialog((CDialog *)&v21, 0x81u, 0);
  v21 = &CNotify::`vftable';
  v23 = 0;
  v2 = sub_410F13();
  if ( v2 == 0 )
    sub_401A00(-2147467259);
  v17 = (const char *)((*(int (__thiscall **)(int))(*(_DWORD *)v2 + 12))(v2) + 16);
  LOBYTE(v23) = 1;
  v19 = 0;
  memset(&v20, 0, 0x31Cu);
  CWnd::GetWindowTextA((int)v1 + 120, (int)&v17);// 获取文本
  v3 = v17;
  if ( *((_DWORD *)v17 - 3) < 40 )
  {
    if ( *((_DWORD *)v17 - 1) > 1 )
    {
      sub_401960(*((_DWORD *)v17 - 3));
      v3 = v17;
    }
    v6 = v3;
    len = strlen(v3);
    v8 = 3 * (len / 3);
    if ( len != v8 )
      len = v8 + 3;                             // 补齐
    v4 = (char *)malloc(8 * len / 6 + 1);
    if ( !v4 )
    {
      LOBYTE(v23) = 0;
      v9 = (int)(v17 - 16);
      v10 = _InterlockedDecrement((volatile signed __int32 *)v17 - 1);
      v11 = v10 == 0;
      v12 = v10 < 0;
      goto LABEL_16;
    }
    base64(v4, (int)v6, strlen(v6));
    sub_401000(v4, (int)&v19);                  // v19 = v4 - 3
    v14 = sub_401040(v13, &v19);
    v1 = v18;
    v5 = v14;
    if ( v14 )
      v5 = 1;
  }
  else
  {
    v4 = (char *)v18;
    v5 = 0;
  }
  if ( v4 )
    free(v4);
  v22 = v5 != 0;
  CDialog::DoModal((CDialog *)&v21);
  (*(void (__thiscall **)(void *))(*(_DWORD *)v1 + 344))(v1);
  LOBYTE(v23) = 0;
  v9 = (int)(v17 - 16);
  v15 = _InterlockedDecrement((volatile signed __int32 *)v17 - 1);
  v11 = v15 == 0;
  v12 = v15 < 0;
LABEL_16:                                       // 错误
  if ( v12 || v11 )
    (*(void (__stdcall **)(int))(**(_DWORD **)v9 + 4))(v9);
  v23 = -1;
  v21 = &CNotify::`vftable';
  return sub_40557C();
}

分析流程发现是base64加密,然后值全部减3,再check

解密脚本
python3

from z3 import *
import base64

check = [0x97, 0x82, 0xAF, 0xBE, 0XA3, 0XBD, 0X95, 0X84, 0XC0, 0XBC, 0X9F, 0XA2, 0X83, 0X63, 0XA8, 0XC5, 0X97, 0X97, 0XA4, 0XA4, 0X98, 0XA6, 0XCD, 0XBC, 0XA3, 0XA2, 0X92, 0XA1, 0XA2, 0X87, 0X95, 0X9C, 0XB4, 0XDA, 0XE5, 0XC0, 0X9F, 0XB9, 0XCA, 0X16, 0, 0]

s = Solver()

B = [BitVec("x%s"%i,8) for i in range(41)]  #?

for i in range(39):
    s.add(B[i] + B[i+1] == check[i])

s.add(B[9] - B[20] == 22)
s.add(B[40] == 0)

print(s.check())
print(s.model())
t = s.model()

print("[", end = "")
for ii in range(40):
    print(t[B[ii]],end = ",")
print(t[B[40]],end = "")
print("]")


re1 = [84,67,63,112,78,85,104,45,87,105,83,76,86,45,54,114,83,68,83,81,83,69,97,108,80,83,79,67,94,68,67,82,74,106,112,117,75,84,101,101,0]
re1_a = ""

for i in re1:
    re1_a += chr(i+3)


re2 = base64.b64decode(re1_a).decode()

print(re2)



'''
while ( *v3 + v3[1] == *(_DWORD *)((char *)v3 + (char *)&v5 - (char *)a2) )
  {
    ++v2;
    ++v3;
    if ( v2 >= 39 )
    {
      if ( a2[9] - a2[20] == 22 )
        return a2[40] == 0;
      return 0;
    }
  }
  '''

后续内容敬请期待,关于z3的使用主页其他文章也有涉及

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

I Am Rex

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

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

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

打赏作者

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

抵扣说明:

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

余额充值