Mas0n
to be reverse engineer🐧
翻车鱼

第二届祥云杯Rev

第二届祥云杯Rev

依旧是被队友带飞…

感想:思维一定要活,说不定flag就在你脚下呢(

勒索加密

AES 128 Crypto++

bmp解密

原理可参考https://github.com/wyrover/CryptoAPI-examples

# -*- coding:utf-8 -*-
'''
@Author: Mas0n
@File: timestamp.py
@Time: 2021-08-22 0:05
@Desc: It's all about getting better.
'''

import struct

time64 = ""
for i in struct.pack("<l", 1629098245):
    time64 += hex(i)[2:].zfill(2)

print("B22FC60E4FD4544B{}21E7B18E".format(time64))

__time64获取了当前的时间戳(10位 秒级),直接看⼀下被加密⽂件的修改时间转成时间戳即可

https://www.beijing-time.org/shijianchuo/ 时间戳转换

https://cdn.shi1011.cn/2021/08/4bc8c09e0409ba67b5618d2d4abaeefa.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

Hash:B22FC60E4FD4544B05111a6121E7B18E

主要加密点

https://cdn.shi1011.cn/2021/08/076d67a680eed6e2da8855aad0dc4c90.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

主要就是进行了RSA加密和AES加密,但是RSA实质上是拿来作为校验的,且大小都是132字节,放在加密文件末尾

https://cdn.shi1011.cn/2021/08/ba13edd7058a3d32ee87fc77e5b8b683.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

这些参数通过查Windows API都能得到

下面就是撸脚本了(

/*
@Author: Mas0n
@File: CryptoApi.cpp
@Time: 2021-08-22 0:30
@Desc: It's all about getting better.
*/
#include <time.h>
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <conio.h>
#include <iosfwd>

#include <iostream>
#include <fstream>
// Link with the Advapi32.lib file.
#pragma comment (lib, "advapi32")

// AES解密
BOOL AesDecrypt(BYTE *pPassword, DWORD dwPasswordLength, BYTE *pData, DWORD &dwDataLength, DWORD dwBufferLength)
{
    BOOL bRet = TRUE;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTHASH hCryptHash = NULL;
    HCRYPTKEY hCryptKey = NULL;

    char info[] = "Microsoft Enhanced RSA and AES Cryptographic Provider";
    // 获取CSP句柄
    bRet = ::CryptAcquireContextA(&hCryptProv, NULL, info, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
    if (FALSE == bRet)
    {
        perror("CryptAcquireContext");

    }

    // 创建HASH对象
    bRet = ::CryptCreateHash(hCryptProv, CALG_SHA_256, NULL, 0, &hCryptHash);
    if (FALSE == bRet)
    {
        perror("CryptCreateHash");

    }

    // 对密钥进行HASH计算
    bRet = ::CryptHashData(hCryptHash, pPassword, dwPasswordLength, 0);
    if (FALSE == bRet)
    {
        perror("CryptHashData");

    }

    // 使用HASH来生成密钥
    bRet = ::CryptDeriveKey(hCryptProv, CALG_AES_128, hCryptHash, 0, &hCryptKey);

    if (FALSE == bRet)
    {
        perror("CryptDeriveKey");

    }

    DWORD dwMode = CRYPT_MODE_CBC;
    CryptSetKeyParam(hCryptProv, KP_MODE, (BYTE*)(dwMode), 0);
    dwMode = PKCS5_PADDING;
    CryptSetKeyParam(hCryptProv, KP_PADDING, (BYTE*)(dwMode), 0);

    bRet = ::CryptDecrypt(hCryptKey, NULL, true, 0, pData, &dwDataLength);
    if (FALSE == bRet)
    {
        perror("CryptDecrypt");

    }

    // 关闭释放
    if (hCryptKey)
    {
        ::CryptDestroyKey(hCryptKey);
    }
    if (hCryptHash)
    {
        ::CryptDestroyHash(hCryptHash);
    }
    if (hCryptProv)
    {
        ::CryptReleaseContext(hCryptProv, 0);
    }

    return bRet;
}

int _tmain(int argc, _TCHAR* argv[])
{
    using namespace std;
    BYTE* pData;
    DWORD dwDataLength = 0, dwBufferLength = 26580;
    DWORD i = 0;

    ofstream outfile("flag.bmp", ios::binary); // 解密文件
    ifstream fd;
    fd.open("flag.bmp.ctf_crypter", ios::binary); // 加密文件 去掉后132字节
    fd.seekg (0, ios::end);
    unsigned int length = fd.tellg();
    fd.seekg (0, ios::beg);
    // allocate memory:

    pData = new BYTE [length];
    // read data as a block:
    fd.read((char*) pData, length);
    fd.close();

    dwDataLength = length;
    dwBufferLength =  length;

    BYTE KEY[16] = {0};
    KEY[0] = 178;
    KEY[1] = 47;
    KEY[2] = 198;
    KEY[3] = 14;
    KEY[4] = 79;
    KEY[5] = 212;
    KEY[6] = 84;
    KEY[7] = 75;
    KEY[8] = 5;
    KEY[9] = 17;
    KEY[10] = 26;
    KEY[11] = 97;
    KEY[12] = 33;
    KEY[13] = 231;
    KEY[14] = 177;
    KEY[15] = 142; // B22FC60E4FD4544B05111a6121E7B18E

    AesDecrypt(KEY, 16, pData, dwDataLength, dwBufferLength);

    printf("AES Decrypt[%d]\n", dwDataLength);

    for (int j = 0; j < dwDataLength; ++j) {
        outfile << pData[j];
    }

    outfile.close();
    return 0;
}
https://cdn.shi1011.cn/2021/08/a944275f92eca400a95563d2d5b2e2c6.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

Rev_Dizzy

这题比较简单,队友先刚出来了

IDA F5比较慢,不过能出来就是了。

看到都是一些对输入的加减异或操作(几千行,挂个图把)

https://cdn.shi1011.cn/2021/08/abb99b04d31f875c76f616b5167e9e05.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

那就Ctrl C,V,写个脚本把加减都给对换一下,然后整体反一下

# -*- coding:utf-8 -*-
"""
@Author: Mas0n
@File: dizzy.py
@Time: 2021-08-22 16:03
@Desc: It's all about getting better.
"""
with open(r"D:\Downloads\Compressed\code.txt", "r") as f:
    code = f.read()

recode = code.splitlines()
for i, line in enumerate(recode):
    if line.find("+") != -1:
        recode[i] = line.replace("+", "-")
    elif line.find("-") != -1:
        recode[i] = line.replace("-", "+")

with open(r"D:\Downloads\Compressed\code.out.txt", "w") as f:
    f.write("\n".join(recode[::-1]))
https://cdn.shi1011.cn/2021/08/c65de5847efbb2e6430fd677f8999fc8.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

赛中就做了这两题,有空复现一下Rev_APC把

本文链接:https://blog.shi1011.cn/ctf/1551
本文采用 CC BY-NC-SA 4.0 Unported 协议进行许可

Mas0n

文章作者

发表回复

textsms
account_circle
email

翻车鱼

第二届祥云杯Rev
依旧是被队友带飞... 感想:思维一定要活,说不定flag就在你脚下呢( 勒索加密 AES 128 Crypto++ bmp解密 原理可参考https://github.com/wyrover/CryptoAPI-examples #…
扫描二维码继续阅读
2021-08-23