吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8175|回复: 25
收起左侧

[CTF] 十月份安恒杯两道逆向题

  [复制链接]
姚小宝 发表于 2018-10-28 17:51
本帖最后由 yechen123 于 2018-11-21 20:59 编辑


这两题目不怎么难  主要看耐心

篇幅可能有点长 可能会有错误 望见谅

先上传题目
十月份安恒杯.rar (122.45 KB, 下载次数: 15)
没有cb的看这里
链接: https://pan.baidu.com/s/1vptBYyCO4Woyjk4mEvVu8A 提取码: eqmt


1.easytree
看题目就知道应该是考察树的知识

下载下来没exe后缀名  以为是linux文件  用winhex打开才发现是pe文件

加个exe后缀名能正常打开
查壳发现有upx壳  

用吾爱脱壳机脱壳
1.png
脱壳后用IDA打开
2.png
两个函数  里面的代码略乱


此时打开 软件看看
3.png


ida 搜索字符串
定位关键点
4.png

附上主要代码
[Asm] 纯文本查看 复制代码
int Good_job()
{
  const char *v0; // eax@4
  int v2; // [sp+14h] [bp-2Ch]@1
  char v3; // [sp+1Ah] [bp-26h]@4
  char Str; // [sp+29h] [bp-17h]@1
  int v5; // [sp+38h] [bp-8h]@4
  int *v6; // [sp+3Ch] [bp-4h]@1

  sub_402400();
  v2 = 0;
  v6 = &v2;
  printHello();
  gets(&Str);
  if ( strlen(&Str) != 15 )
  {
    printf("Nah... ur a fake reverser!");
    exit(0);
  }
  v5 = sub_401500((int)&Str, 15);               // 创建结构
  sub_40166E(v5, v6, (int)&v3);                 // v5是根节点的首地址
  v0 = sub_401794(&v3);                         // icnerrseaetrvee
  if ( !strncmp(v0, "aWNuZXJyc2VhZXRydmVl", 0x14u) )
    puts("well done bro!");
    printf("ur really know something about tree!");
  }
  else
  {
    printf("Nah.. ur an idiot!");
  }
  return 0;
}


sub_401500 sub_40166e sub_401794这几个函数比较可疑

先看看最后一个
5.png
显得有点复杂  在结合下面的代码
[Asm] 纯文本查看 复制代码
if ( !strncmp(v0, "aWNuZXJyc2VhZXRydmVl", 0x14u) )

大胆预测这是base64加密

aWNuZXJyc2VhZXRydmVl 这是密文  解密得到icnerrseaetrvee
再看看sub_401500  这个函数
6.png
看起来像是创建树结构的代码
还好这几天学完树和二叉树这一章了

大概看了下  这个代码会给每个节点创建12个字节的空间  前面四个字节储存自己的数据  中间四个字节储存左孩子的地址  最后四个字节是储存右孩子的地址
前面有限制我们只能输入15个字符  比如输入abcdefghijklmno
那么他的储存结构是这样子的(输入时候不小心换成大写了  望见谅)
7.png

再看看 sub_40166E这个函数  

[Asm] 纯文本查看 复制代码
int __cdecl sub_40166E(int input, _DWORD *v6, int a3)
{
  int v3; // eax@2
  int result; // eax@2

  if ( input )
  {
    v3 = (*v6)++;
    *(_BYTE *)(a3 + v3) = *(_BYTE *)input;
    sub_40166E(*(_DWORD *)(input + 4), v6, a3);
    result = sub_40166E(*(_DWORD *)(input + 8), v6, a3);
  }
  return result;
}

这个大概是遍历二叉树的代码  遍历分为前序遍历 中序遍历 后序遍历 这个应该是前序遍历

好了 上面我们得到的base64解密代码是icnerrseaetrvee
那么可以根据他创建二叉树的结构 以及根据前序遍历的规则得出树结构
8.png
那么可以得到flag  为 icanreversetree
9.png

第二题 BASE++
这道题  跟九月份的有点像  有兴趣的可以看一下我前面发的九月份安恒杯月赛的帖子

说明跟base加密有关

可能改变了一下
文件给了exe和一个ida文件 直接打开ida文件
直接上代码
[Asm] 纯文本查看 复制代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  int v4; // [esp+30h] [ebp-28h]
  int v5; // [esp+34h] [ebp-24h]

  sub_401790(std::cout, "please input your flag:");
  sub_4019D0(std::cin, &input_flag);
  if ( (signed int)strlen((const char *)&input_flag) < 32 )// 小于32位
    goto LABEL_14;
  transform_1((const char *)&input_flag);
  v5 = strcmp((const char *)&input_flag, "guvf_vf_n_snxr_synt_____________");
  if ( v5 )
    v5 = -(v5 < 0) | 1;
  if ( v5 )
  {
LABEL_14:
    transform_2();
    transform_3(strlen((const char *)&input_flag), (int)&input_flag, (int)a0);
    v4 = strcmp(a0, "TRLT5amLBoLT5Z6Fa5LqN6mkTomqR66Da4LqX5mgBwkkP5wmTZ6D====");
    if ( v4 )
      v4 = -(v4 < 0) | 1;
    if ( v4 )
      sub_401790(std::cout, "soooooooooorry\n");
    else
      sub_401790(std::cout, "Congratulations!!!\n");
    system("pause");
    result = 0;
  }
  else
  {
    sub_401790(std::cout, "try harder!\n");
    result = 0;
  }
  return result;
}


要是输入的字符串小于32  直接跳到下边的if里边  

先看看if里边的东西
主要涉及函数
transform_2
transform_3

然后加密过后的字符串必须为"TRLT5amLBoLT5Z6Fa5LqN6mkTomqR66Da4LqX5mgBwkkP5wmTZ6D===="

transform_2 没啥好看的 主要生成 "NoPqRsTuVwXyZaBcDeFgHiJkLm765432"这个密码表  有兴趣对的可以看一下
看下transform_3  

[Asm] 纯文本查看 复制代码
int __usercall transform_3@<eax>(int input_len@<edx>, int input_flag@<ecx>, int a3)
{
  int v3; // esi
  _BYTE *a0_; // edi
  int input_lens; // ebx
  int v7; // [esp+4h] [ebp-8h]
  int input__len; // [esp+8h] [ebp-4h]

  v7 = input_flag;
  v3 = 0;
  input__len = input_len;
  if ( input_len > 0 )
  {
    a0_ = (_BYTE *)a3;                          // a0
    input_lens = input_len;
    do
    {
      base_tran_5(v3 + input_flag, input_lens, a0_);
      input_flag = v7;
      v3 += 5;                                  // step 5 每次进多5步
      input_lens -= 5;
      a0_ += 8;
    }
    while ( v3 < input__len );
  }
  return a3;
}

主要逻辑是  每次把字符串五个字符 和总长度 和密码表传入base_tran_5  主要由这个函数加密
每次执行完  字符串长度减5

看看这个函数内部
10.png
取每个字符 经过简单的运算得到一个数值 在用这个数值当做序号取出密码表的值当做密文
最终 到了字符串末尾 看是否是8的倍数 不是就补'='补够为止

密文已经给出

那么就可以根据密文求出序号再求出明文

在这里给一下思路  该代码每次使用五个字符
比如我输入
abcdefghijklmn
那么先取abcde
在内存中就是6162636465
eax只存62636465  edx存00000061
6162636465 换成二进制就是
0110000101100010011000110110010001100101
每五个位分成一组
01100 00101 10001 00110 00110 11001 00011 00101
每一组换成十进制后当成序号取密码表中的值换成密文

比如第一组 01100 换成10进制就是12  

换成密文就是Z
也就是每五个明文可以换成8个密文
知道具体原理就可以解密了

用python写脚本
[Asm] 纯文本查看 复制代码
asciis = ['N', 'o', 'P', 'q', 'R', 's', 'T', 'u', 'V', 'w', 'X', 'y', 'Z', 'a', 'B', 'c', 'D', 'e', 'F', 'g', 'H', 'i', 'J', 'k', 'L', 'm', '7', '6', '5', '4', '3', '2']
encrypt = ['T', 'R', 'L', 'T', '5', 'a', 'm', 'L', 'B', 'o', 'L', 'T', '5', 'Z', '6', 'F', 'a', '5', 'L', 'q', 'N', '6', 'm', 'k', 'T', 'o', 'm', 'q', 'R', '6', '6', 'D', 'a', '4', 'L', 'q', 'X', '5', 'm', 'g', 'B', 'w', 'k', 'k', 'P', '5', 'w', 'm', 'T', 'Z', '6', 'D', '=', '=', '=', '=']
 
flag = [0,0,0,0,0,0,0,0]
base = [0,0,0,0,0,0,0,0]
 

flags = ""
flagq = ""
for i in range(0,55,8):
    base[0] = i
    base[1] = i + 1
    base[2] = i + 2
    base[3] = i + 3
    base[4] = i + 4
    base[5] = i + 5
    base[6] = i + 6
    base[7] = i + 7
    flag[0] = 0
    flag[1] = 0
    flag[2] = 0
    flag[3] = 0
    flag[4] = 0
    flag[5] = 0
    flag[6] = 0
    flag[7] = 0
    for q in range(0,8):
        for f in range(0,32):
            if (encrypt[base[q]]==asciis[f]):
                flag[q] = f
    flag[0] = flag[0]<<35
    flag[1] = flag[1]<<30
    flag[2] = flag[2]<<25
    flag[3] = flag[3]<<20
    flag[4] = flag[4]<<15
    flag[5] = flag[5]<<10
    flag[6] = flag[6]<<5
    temp = "%x"%(flag[0]+flag[1]+flag[2]+flag[3]+flag[4]+flag[5]+flag[6]+flag[7])
    flags += temp
for i in range(0, len(flags), 2):
	flagq += chr(int(flags[i:i+2], 16))
print flagq


得到10n78ppn3ro00o70r2opop5s3roqq937
但是 输入却不对 用od看看
1.png
经过这个函数输入的字符串被替换了  只替换小写的  

用ida看看
[Asm] 纯文本查看 复制代码
signed int __thiscall transform_1(const char *this)
{
  const char *input_; // edi
  unsigned int v2; // esi
  char v3; // cl

  input_ = this;
  v2 = 0;
  if ( strlen(this) )
  {
    do
    {
      v3 = input_[v2];
      if ( (unsigned __int8)(v3 - 97) <= 25u )  // 如果是小写
        input_[v2] = (v3 - 84) % 26 + 97;
      if ( (unsigned __int8)(v3 - 65) <= 25u )
        input_[v2] = (v3 - 52) % 26 + 65;
      ++v2;
    }
    while ( v2 < strlen(input_) );
  }
  return 1;
}

因为我们输入的是小写和数字 看第一个if就行  看起来就是整个小写字符串表以为
写个代码

果然是移位

那么 刚刚我od里面看到了经过这个函数移位之后的字符串  你可以直接输入这个字符串就可以了
或者像我一样写个脚本 反正结果都是一样的
[Asm] 纯文本查看 复制代码
key = "10n78ppn3ro00o70r2opop5s3roqq937"
asciis = []
g = [] 
for i in range(97,123):
    asciis.append(chr(((i-84)%26)+97))#生成移位之后的表
for i in range(0,32):
    if (97<=ord(key[i])<=122):#小写才用改  数字就算了
        temp = ord(key[i])-97
        g.append(asciis[temp])
        continue
    g.append(key[i])
flag = ""
for i in g:
    flag += i
print (flag) 

得到  10a78cca3eb00b70e2bcbc5f3ebdd937
2.png

免费评分

参与人数 8威望 +2 吾爱币 +18 热心值 +7 收起 理由
siuhoapdou + 1 + 1 谢谢@Thanks!
笙若 + 1 谢谢@Thanks!
zhukai055 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
coward + 1 + 1 谢谢@Thanks!
lihaohua + 1 + 1 我很赞同!
52lxw + 1 + 1 我很赞同!
KNulL0 + 1 + 1 谢谢@Thanks!
Hmily + 2 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

zhukai055 发表于 2018-10-29 20:00
100分的那题:1.输入一段字符串,在OD在看字符串 根据换位规则 反解
2.就是base64解密
200分的那题:1.一个小算法(不知道算法名)
2.base32改过算法表,如果懒得写b32,用加密或者解密后,按照位置替换字符也可以。
超大的橙子 发表于 2018-11-14 14:14
yechen123 发表于 2018-11-12 20:40
考虑进去了,这个作用是把输入字符移位相加在根据值从密码表取值

我把移位的那段直接爆出来发现就是10n78ppn3ro00o70r2opop5s3roqq937
sunxi 发表于 2018-10-28 23:10 来自手机
Sma11_Tim3 发表于 2018-10-29 01:54
太强了,我第二道题连思路都没搞懂。
sh1ner 发表于 2018-10-29 09:08
学到了学到了
dd521q 发表于 2018-10-29 10:04
技术贴 技术牛
zzzzzzzz 发表于 2018-10-29 10:36
学到了 学到了
lihaohua 发表于 2018-10-29 11:08
大········大佬
 楼主| 姚小宝 发表于 2018-10-29 11:33
lihaohua 发表于 2018-10-29 11:08
大········大佬

不不,师傅才是真正的大佬
Mr_Right_ 发表于 2018-10-29 12:17
学习一下
锦华教育 发表于 2018-10-29 14:22
学习中,不错不错,
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-26 07:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表