• (xxxx)八:加密图片的解密


          1、 xxxx接收到图片后,不会明文存储在磁盘,因为不安全,都是加密后存储在特定目录的,截图如下(请忽略两个jpg的文件,这是我为了做测试人为添加的,xxxx原始是不会存这些图片的):

           

            可以看到图片都是以dat格式存储的。用010editor打开:全是没意义的数据,图片的头信息完全找不到!

             

             既然都是加密存储的,在xxxx软件中是怎么看到图片的了? 换句话说,xxxx软件都是怎么解密这些图片的了?

            2、正式介绍解密之前,先做个位运算知识的铺垫:异或 XOR

           (1)两个bit做XOR,如果不同那么结果为1;如果相同结果为0; 打个比方:男女在一起才能生娃,同性在一起是不行的!也就是:1^1=0, 0^0=0,  但是1^0=1;

           (2)XOR最大的作用: 对称加密!   比如明文是0xA=1010, 密钥是0xB=1011,那么密文=A^B=0x1;  解密时,用密钥^密文即可,这里便是0x1^B=A,成功得到明文;

           (3)XOR最大的特性:明文、密钥、密文三个的关系像个三角形,其中任意两个异或,都能得到第三个!比如上面用加密的算法是A^B=0x1;解密的算法是B^0x1=A; 但是用明文A^密文0x1也能得到密钥B; 这个特性有啥用了:

    •     明文、密钥、密文只能对外公布一个,一般公开密文(这不废话么?)
    •     曾经有人利用该特性找到了windwos PG保护的密钥(用IDA静态分析找到明文,windbg动态分析找到密文,两个异或就找到了密钥
    •     也有人利用这个特性做PE文件保护(原理和PG保护类似),PE文件的代码和数据都加密存储,直到执行前才在内存解密得到真正的代码
    •     密文和明文大小是一样的(后面会根据这个猜图片的加密方式)

          (4)XOR对称加密的另一大特点:计算方式简单! XOR本质是位运算,CPU内部的硬件电路是可以直接实现的,一条XOR的汇编指令就能完成计算,理论上只需要1ns的时间(这里扩展一下:其实CPU内部的加减乘除都是通过XOR实现的);只要key的长度足够,短时间内想要通过暴力穷举是不可能的。比如key的长度是1024bit,那么key就有2的1024次方个。和同为对称加密的AES算法比,效率高太多了!所以用XOR加密是非常广泛的!

     (5)XOR最后一个优点:因为是按照位计算的,所以计算的时间和复杂度只和位数相关,和数据实际数值无关!这么做的好处是啥了? 防止侧信道攻击!比如只要密码位数一定,不论是数字,还是字母,还是特殊符号,解密的时间都一样,不会因为字符不同而导致时间不同!

            3、 之前找过xxxx接受消息的call,这里继续下断点,然后再手机上通过文件助手发条消息,断下来了:

              

             这里已经能看到消息的部分内容了,但OD显示的长度有限,看不全,所以这里需要CE辅助:注意地址的配置,这里就要选Unicode了

             

              下面就是图片的数据格式:是xml的;从字段的名称看,有AES密钥、cdn的密钥、cdn的url、md5等信息;图片还有大图和midimg(从字面猜测应该是中等大小的图片,大概率是在聊天窗展示的那种);可惜的是没有找到图片保存的名字和位置;

    <?xml version="1.0"?>
    <msg>
        <img aeskey="7a40664635a1aac64816c8deff4a39b0" encryver="0" cdnthumbaeskey="7a40664635a1aac64816c8deff4a39b0" cdnthumburl="304f020100044830460201000204513ea50e02033d14ba02047851fb3a020460376bb60421777875706c6f61645f66696c6568656c7065723730375f31363134323434373838020401090a020201000400" cdnthumblength="3967" cdnthumbheight="90" cdnthumbwidth="120" cdnmidheight="0" cdnmidwidth="0" cdnhdheight="0" cdnhdwidth="0" cdnmidimgurl="304f020100044830460201000204513ea50e02033d14ba02047851fb3a020460376bb60421777875706c6f61645f66696c6568656c7065723730375f31363134323434373838020401090a020201000400" length="1" md5="5733041f60a14ce9f4d75be1bb49a213" hevc_mid_size="176859" />
    </msg>

           继续往下,终于找到了图片存放的位置和名字,如下:

             

            用同样的方法再CE里面能看到图片加密后bat文件的全称和存放路径(就是刚才说的那个目录):

           

             根据bat文件的名字和路径,把加密前后的图片都放进010editor中对比:加密后的文件已经面目全非,连图片头信息都没了,不过加密后文件有个最大的特征:大小和加密前完全一样!

            

           那么有没有可能用XOR来加密的了? 怎么验证了?

          4、这里就要用到刚才提到的XOR特点:密文、密钥、明文三者像三角形的关系其中任意两个异或,都能得到第三个!明文图片的第一个字节是FF,密文第一个字节是B3,FF^B3=4C,那么4C是不是key了? 为了逻辑严密,需要交叉验证:第二个明文是D8,这时已经知道key=4C了,D8^4C=0x94,居然刚好等于第二个密文,4C就是key看来没错了!为了谨慎,我们再用密文交叉验证试试:第三个密文是B3,那么解密算法就是B3^4C=0xFF,刚好等于第三个明文!此时,通过三次明文、密文、密钥的交叉验证,实锤了加密算法是XOR、密钥是4C

           最后解密的POC如下:

    #include <stdio.h>
    #include <string.h>  
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    const char* filename = "decryptPic\07a00a9454f983ca808cd1a6028d581c.dat";
    
    int main(int argc, char** argv) {
        std::ifstream streamReader(filename, std::ios::binary); //以二进制的形式读取文件
        streamReader.seekg(0, std::ios::end);//跳转到尾部
        unsigned filesize = streamReader.tellg();//得到文件大小
        char* _data = new char[filesize];
        char* _decrypt = new char[filesize];
        printf("length is:%d
    ", filesize);
        streamReader.seekg(0, std::ios::beg);//跳转到开始
        streamReader.read(_data, filesize);
        streamReader.close();
        for (int i=0;i< filesize;i++)
        {
            //std::cout << _data[i];
            /*
            //https://www.coder.work/article/2223646  参考这里,打印的时候必须转成(unsigned char),否则默认会以4字节、也就是unsinged int打印
            */
            //printf("%1x",(unsigned char)_data[i]);
            _decrypt[i] = _data[i] ^ 0x4c;//解密
            //printf("%1x", (unsigned char)_decrypt[i]);//从010editor看是对的
        }
    
        std::ofstream  ofs;
        ofs.open("decryptPic\decript.jpg", ios::out | ios::app | ios::binary, _SH_DENYNO);
        ofs.write(_decrypt, filesize);
        ofs.close();
        return 0;

          效果:成功解密,生成decrypt.jpg图片!

       

         以后写勒索病毒,完全可以复用这段代码对文件加密,然后让对方用比特币支持,想想都刺激.......

  • 相关阅读:
    浅谈Objeact.clone克隆(纯个人理解,如有错误请指正)
    Spring集成Swagger,Java自动生成Api文档
    Spring @Value注入值失败,错误信息提示:Could not resolve placeholder
    触发器
    存储过程
    JavaEE笔记(十四)
    JavaEE笔记(十三)
    JavaEE笔记(十二)
    JavaEE笔记(十一)
    vue相关面试知识点总结
  • 原文地址:https://www.cnblogs.com/theseventhson/p/14448537.html
Copyright © 2020-2023  润新知