1、前言

分析木马程序常常遇到很多配置信息被加密的情况,虽然现在都不直接分析而是通过Wireshark之类的直接读记录。

2017年Gh0st样本大量新增,通过对木马源码的分析还发现有利用Gh0st加密方式来传播的源码中的后门。

2、加密思路

  • 控制端:对字符串异或、移位、Base64编码

  • 服务端:对字符串Base64解码、移位、异或

3、实践代码

  • 加密编码
// Base64编码
static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int C模仿Gh0st加密上线地址Dlg::base64_encode(const void *data, int size, char **str)
{
    char *s, *p;
    int i;
    int c;
    const unsigned char *q;

    p = s = (char*)malloc(size * 4 / 3 + 4);
    if (p == NULL)
        return -1;
    q = (const unsigned char*)data;
    i = 0;
    for (i = 0; i < size;) {
        c = q[i++];
        c *= 256;
        if (i < size)
            c += q[i];
        i++;
        c *= 256;
        if (i < size)
            c += q[i];
        i++;
        p[0] = base64[(c & 0x00fc0000) >> 18];  //base64
        p[1] = base64[(c & 0x0003f000) >> 12];
        p[2] = base64[(c & 0x00000fc0) >> 6];
        p[3] = base64[(c & 0x0000003f) >> 0];
        if (i > size)
            p[3] = '=';
        if (i > size + 1)
            p[2] = '=';
        p += 4;
    }
    *p = 0;
    *str = s;
    return strlen(s);
}

// 加密函数
char * C模仿Gh0st加密上线地址Dlg::MyEncode(char *str)
{
    int     i, len;
    char    *s, *data;
    // 字符串长度
    len = strlen(str) + 1;
    // 开辟字符串相对应的内存空间
    s = (char *)malloc(len);
    // 将字符串拷贝到开辟出来的指针中
    memcpy(s, str, len);
    // 异或操作
    for (i = 0; i < len; i++)
    {
        s[i] ^= 0x19;
        s[i] += 0x86;
    }
    // Base64编码
    base64_encode(s, len, &data);
    free(s);

    return data;
}
  • 解密编码
// Base64密钥
static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

// 解码密钥
int C模仿Gh0st加密上线地址Dlg::pos(char c)
{
    char *p;
    for (p = base64; *p; p++)
        if (*p == c)
            return p - base64;
    return -1;
}

// Base64解码
int C模仿Gh0st加密上线地址Dlg::base64_decode(const char *str, char **data)
{
    const char *s, *p;
    unsigned char *q;
    int c;
    int x;
    int done = 0;
    int len;
    s = (const char *)malloc(strlen(str));
    q = (unsigned char *)s;
    for (p = str; *p && !done; p += 4) {
        x = pos(p[0]);
        if (x >= 0)
            c = x;
        else {
            done = 3;
            break;
        }
        c *= 64;

        x = pos(p[1]);
        if (x >= 0)
            c += x;
        else
            return -1;
        c *= 64;

        if (p[2] == '=')
            done++;
        else {
            x = pos(p[2]);
            if (x >= 0)
                c += x;
            else
                return -1;
        }
        c *= 64;

        if (p[3] == '=')
            done++;
        else {
            if (done)
                return -1;
            x = pos(p[3]);
            if (x >= 0)
                c += x;
            else
                return -1;
        }
        if (done < 3)
            *q++ = (c & 0x00ff0000) >> 16;

        if (done < 2)
            *q++ = (c & 0x0000ff00) >> 8;
        if (done < 1)
            *q++ = (c & 0x000000ff) >> 0;
    }

    len = q - (unsigned char*)(s);

    *data = (char*)realloc((void *)s, len);

    return len;
}

// 解密函数
char* C模仿Gh0st加密上线地址Dlg::MyDecode(char *str)
{
    int     i, len;
    char    *data = NULL;
    len = base64_decode(str, &data);

    for (i = 0; i < len; i++)
    {
        data[i] -= 0x86;
        data[i] ^= 0x19;
    }
    return data;
}

然后就是加密解密界面的内容。

函数代码:

  • 生成配置信息按钮
void C模仿Gh0st加密上线地址Dlg::OnBnBuild()
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateData(TRUE);
    m_remote_host.Replace(L" ", L"");
    m_remote_port.Replace(L" ", L"");

    CString str = m_remote_host + ":" + m_remote_port;
    str.MakeLower();
    TCHAR * pWStrKey;         // 合并后的内容

    // 开辟数组
    pWStrKey = new TCHAR[str.GetLength() + 1];
    pWStrKey = str.GetBuffer(0);

    // 第一次 调用确认转换后单字节字符串的长度,用于开辟空间
    int pSize = WideCharToMultiByte(CP_OEMCP, 0, pWStrKey, wcslen(pWStrKey), NULL, 0, NULL, NULL);
    // 单字符
    char* pCStrKey = new char[pSize + 1];
    // 第二次 调用将双字节字符串转换成单字节字符串
    WideCharToMultiByte(CP_OEMCP, 0, pWStrKey, wcslen(pWStrKey), pCStrKey, pSize, NULL, NULL);
    pCStrKey[pSize] = '\0';

    // 接收char*
    m_encode = MyEncode(pCStrKey);

    m_encode.Insert(0, L"AAAA");
    m_encode += "AAAA";

    UpdateData(FALSE);
}
  • 解密配置信息按钮

void C模仿Gh0st加密上线地址Dlg::OnBnGetLoginInfo()
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateData(TRUE);

    // 1 获取加密编辑控件里的字符串
    int pSize = m_encode.GetLength() + 1;
    wchar_t * pStart, *pEnd;
    wchar_t strKey[] = L"AAAA";
    wchar_t strEncode[1024];

    // 拿到最开始的字符串,如果前面是AAAA就赋值到pStart
    pStart = wcsstr(m_encode.GetBuffer(0), strKey);
    // 前移动4个字节,也就是跳过AAAA
    pStart += 4;
    // 如果AAAA匹配不到把strKey,也就是AAAA赋值给pEnd
    pEnd = wcsstr(pStart, strKey);
    // 清空原先AAAA字符串
    wmemset(strEncode, 0, wcslen(pStart) + 1);
    // 取key值之间的内容,配置字符串 - 字符串长度,取前面的真实加密字符串
    wmemcpy(strEncode, pStart, pEnd - pStart);
    // 单字符
    char* pCStrKey = new char[wcslen(strEncode) + 1];
    // 调用将双字节字符串转换成单字节字符串
    WideCharToMultiByte(CP_OEMCP, 0, strEncode, wcslen(strEncode) + 1, pCStrKey, wcslen(strEncode) + 1, NULL, NULL);
    pCStrKey[pSize] = '\0';

    // 解密代码
    m_decode = MyDecode(pCStrKey);

    UpdateData(FALSE);
}

4、实际效果

5、参考

gh0st3.6源码分析(1)——木马的生成

http://blog.csdn.net/hjxyshell/article/details/19094609

最新文章

  1. 简单Java类与XML之间的转换
  2. 求解区间最值 - RMQ - ST 算法介绍
  3. ✡ leetcode 158. Read N Characters Given Read4 II - Call multiple times 对一个文件多次调用read(157题的延伸题) --------- java
  4. 8.springMVC中的RESTful架构风格
  5. 问题解决——XP线程池找不到QueueUserWorkItem
  6. 哈夫曼树-Fence Repair 分类: 树 POJ 2015-08-05 21:25 2人阅读 评论(0) 收藏
  7. RMAN备份数据库与恢复数据库(整库)
  8. jquery 事件绑定以及解绑定
  9. 桥接模式(Bridge Pattern)
  10. iOS 第三方库冲突的处理
  11. http学习笔记一
  12. ucos 创建 空闲任务的目的
  13. 开源微信管家平台——JeeWx 捷微4.0 微服务版本发布,全新架构,全新UI,提供强大的图文编辑器
  14. Android Studio 删除多余的虚拟设备(Virtual Device)
  15. equals的使用
  16. 【BZOJ3193】[JLOI2013]地形生成(动态规划)
  17. iscroll 4 下拉 上拉 加载
  18. CS229 笔记06
  19. How to create a custom action type with a custom control (BarCheckItem), associated with it
  20. Intellij IDEA创建maven项目无java文件问题

热门文章

  1. JAVAScript对象及初始面向对象
  2. QProcess 进程调用
  3. python爬虫实战之bilibili弹幕生成云图
  4. Candies CodeForces - 991C(二分水题)
  5. BZOJ4919 [Lydsy1706月赛]大根堆 【dp + 启发式合并】
  6. 多项式 Wannafly挑战赛22
  7. config配置中心之自动刷新
  8. etcd基本操作
  9. git 使用 gitignore
  10. NATS_09:NATS常见问题说明