首页
社区
课程
招聘
第六届上海市大学生网络安全大赛Re
发表于: 2020-11-15 12:49 5048

第六届上海市大学生网络安全大赛Re

2020-11-15 12:49
5048

分享一下昨天刚打的上海市大学生网络安全大赛的Re

ida开始直接搜索字符串,找到关键函数,简单修复一下栈指针,直接F5。

开始总感觉自己看到的是假的流程,把程序翻了个遍,没发现其它的流程,但是发现了几个反调试,但是调试发现程序都没有使用。。。其中二个:

然后确定这就是一个虚拟机逆向。静态分析一下后直接让程序跑起来。

这里我做的时候和复现的时候,ida识别的竟然不一样,复现分析的更简洁。记得做的时候,每次赋值操作码与数据的时候是使用一个四字节数据来保存的,其中L0BYTE,Byte1,Byte2,HIByte都是不同的含义:

做的时候的一些笔记:

然后程序中使用了的一个反调试(时钟检测):简单patch了即可。

乍一看程序流程有点复杂,感觉输入的数据会决定下一步操作码,这个其实就是一个加密操作。

总结一下程序的加密操作(对所有字符串的加密都是这个操作):首先从操作码中取出一个数据op_data ,然后temp = input[i]^op_data,再让op_data &= input[i],input[i] = temp,一直这个循环直到op_data == 0,最后取出input[i+1]进行input[i] ^= input[i+1]。一直这样对所有的input加密2遍,就是使用op_data不同。

使用ida_python导出我们要用的op_data。

按照程序的算法,逆二次即可:第一次解密过程我进行了注释。

从题目名字可知道是虚拟机逆向。在linux中运行一下,看见字符串信息。

ida中搜索一圈并没有发现任何相关字符串,那就是程序运行时解密出相关字符串。从入口点找到main函数,可以看到464行的代码,分支极其多。。

静态分析是不可能了,直接动调。

开始慢慢的调试看哪里解密字符串的,但实在是冗长,直接在while循环下断,然后F9一直跑,直到程序等待我们输入。

随便输入后,开始慢慢跟进熟悉一些函数的功能,发现开始就是在以此取我们输入的字符存入一个大数组中

继续跟踪,分析到我们输入的字符长度要是38,虽然读取了最后的回车符,但是没有使用的。

其中程序中这个内存区域类似就是vm使用的寄存器。

接下来判断我们输入最后一位是不是 ‘}‘ 字符,再把除了flag{ }中的内容复制到与程序最后做比较的字符串的下面,

接着判断我们开始的5位是不是 flag{。

最后就是以依次出我们flag{}中每一位,(0xFB*input[i])&0xff,然后以此与上面的比较字符串比较。解密:

 
 
 
 
 
//测试flag。
flag{0123456789012345678901234567890}
 
//最后比较的数据。
unsigned char ida_chars[] =
{
   312415, 250, 18499, 100, 13724, 104,
  124252045, 12588,   03084, 106,
   656054628619,   4594675,
  12167, 1223469, 11058, 11738, 200,
  192, 142
};
 
 
LOBYTE:%64 index
BYTE2: 开始与LOBYTE值相同,做运算完的赋值index
BYTE1: xor input[]  opcode: 2
 
3:BYTE1 &= LOBYTE;
//测试flag。
flag{0123456789012345678901234567890}
 
//最后比较的数据。
unsigned char ida_chars[] =
{
   312415, 250, 18499, 100, 13724, 104,
  124252045, 12588,   03084, 106,
   656054628619,   4594675,
  12167, 1223469, 11058, 11738, 200,
  192, 142
};
 
 
LOBYTE:%64 index
BYTE2: 开始与LOBYTE值相同,做运算完的赋值index
BYTE1: xor input[]  opcode: 2
 
3:BYTE1 &= LOBYTE;
 
 
 
 
 
#include <stdio.h>
 
unsigned char ida_chars[] =
{
   312415, 250, 18499, 100, 13724, 104,
  124252045, 12588,   03084, 106,
   656054628619,   4594675,
  12167, 1223469, 11058, 11738, 200,
  192, 142
};
 
unsigned char a1[] = {9, 2, 7, 8, 6, 9, 11, 10, 4, 11, 12, 4, 7, 7, 10,
         4, 3, 9, 4, 6, 3, 12, 11, 13, 4, 10, 7, 7, 2, 6, 6, 12, 9,
          14, 7, 8, 11, 13, 14, 12, 4, 7};
unsigned char b[] = {13, 8, 12, 10, 3, 9, 5, 12,
           13, 11, 12, 7, 6, 10, 8, 9, 13, 8, 5, 10, 7,
         13, 4, 13, 2, 12, 10, 12, 9, 7, 14, 5, 11, 7, 13, 7, 13, 11, 5, 14, 6, 10};
 
unsigned char c[] = {3, 15, 15, 20, 228, 95, 11, 116, 9, 14, 113, 1, 17, 3, 32, 85, 6, 19, 5, 94, 2, 72, 105, 91, 86, 14, 9, 23, 24, 15, 93, 18, 84, 37, 14, 94, 11, 34, 88, 123, 65, 135};
 
int main(void)
{
 
/*    int i = 0, j = 0;
 
    ida_chars[41] = 135;
    for(j = 40; j >= 0; j--)
    {
        ida_chars[j] ^= ida_chars[j+1];
 
        for(i = 0; i < 255; i++)
        {
            unsigned char temp = i, temp1 = i;
            unsigned char a = b[j];
            while(1)
            {
                temp1 ^= a;
                a &= temp;
                a *= 2;
                temp = temp1;
 
                if(a == 0)
                    break;
            }
            if(temp == ida_chars[j])
            {
                ida_chars[j] = i;
                break;
            }
        }
    }
 
    for(i = 0; i < 42; i++)
        printf("%d, ", ida_chars[i]);*/
 
    int i = 0, j = 0;
 
    c[41] = 125;
    for(j = 40; j >= 0; j--)
    {
        c[j] ^= c[j+1];
 
        for(i = 0; i < 255; i++)
        {
            unsigned char temp = i, temp1 = i;
            unsigned char a = a1[j];
            while(1)
            {
                temp1 ^= a;
                a &= temp;
                a *= 2;
                temp = temp1;
 
                if(a == 0)
                    break;
            }
            if(temp == c[j])
            {
                c[j] = i;
                break;
            }
        }
    }
 
    for(i = 0; i < 42; i++)
        printf("%c", c[i]);
}
//flag{e1750505-7a05-4de9-a333-72ec8cd26a78}
#include <stdio.h>
 
unsigned char ida_chars[] =
{
   312415, 250, 18499, 100, 13724, 104,
  124252045, 12588,   03084, 106,
   656054628619,   4594675,
  12167, 1223469, 11058, 11738, 200,
  192, 142
};
 
unsigned char a1[] = {9, 2, 7, 8, 6, 9, 11, 10, 4, 11, 12, 4, 7, 7, 10,
         4, 3, 9, 4, 6, 3, 12, 11, 13, 4, 10, 7, 7, 2, 6, 6, 12, 9,
          14, 7, 8, 11, 13, 14, 12, 4, 7};
unsigned char b[] = {13, 8, 12, 10, 3, 9, 5, 12,
           13, 11, 12, 7, 6, 10, 8, 9, 13, 8, 5, 10, 7,
         13, 4, 13, 2, 12, 10, 12, 9, 7, 14, 5, 11, 7, 13, 7, 13, 11, 5, 14, 6, 10};
 
unsigned char c[] = {3, 15, 15, 20, 228, 95, 11, 116, 9, 14, 113, 1, 17, 3, 32, 85, 6, 19, 5, 94, 2, 72, 105, 91, 86, 14, 9, 23, 24, 15, 93, 18, 84, 37, 14, 94, 11, 34, 88, 123, 65, 135};
 
int main(void)
{
 
/*    int i = 0, j = 0;
 
    ida_chars[41] = 135;
    for(j = 40; j >= 0; j--)
    {
        ida_chars[j] ^= ida_chars[j+1];
 
        for(i = 0; i < 255; i++)
        {
            unsigned char temp = i, temp1 = i;
            unsigned char a = b[j];

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2020-11-15 21:35 被Bxb0编辑 ,原因:
上传的附件:
收藏
免费 2
支持
分享
最新回复 (4)
雪    币: 242
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
请问一下师傅,这里看到输入会决定下一步操作码时是怎么分析的?需要进入产生操作码的函数分析还是trace操作码找规律?
2020-11-15 15:53
0
雪    币: 5496
活跃值: (2346)
能力值: ( LV7,RANK:108 )
在线值:
发帖
回帖
粉丝
3
mb_rtshsaxv 请问一下师傅,这里看到输入会决定下一步操作码时是怎么分析的?需要进入产生操作码的函数分析还是trace操作码找规律?
噢那个我可能说的不怎么正确,其实就是不断对input进行xor操作。直到 & 操作的结果为 0 
2020-11-15 16:50
0
雪    币: 642
活跃值: (996)
能力值: ( LV5,RANK:72 )
在线值:
发帖
回帖
粉丝
4
super brain的题目有不 方便发出来不
2020-11-15 20:27
0
雪    币: 5496
活跃值: (2346)
能力值: ( LV7,RANK:108 )
在线值:
发帖
回帖
粉丝
5
yeyeyesO super brain的题目有不 方便发出来不
ok
2020-11-15 21:34
0
游客
登录 | 注册 方可回帖
返回
//