menu Alkaid #二进制初学者 / 网络安全 / 大龄CTF退役选手
GACTF 2020 Reverse Writeup
398 浏览 | 2020-09-02 | 分类:心路历程,Reverse,CTF | 标签:CTF,Reverse

好久没写文章了,把整理好的wp发一份,水一水。

Reverse

Checkin

签到题目,使用了Ruby的打包exe工具ocra,ocra全称为:OneClick Ruby Application Builder,就是将运行ruby脚本需要的环境,包括script、rubygems、interpreter等等,全部打包进一个可执行的exe文件中,非常类似C/C++里面的编译器。使用OCRA打包好的One-Click执行文件,就不需要用户搭建复杂的运行环境了。特点是exe本身只会对脚本和ruby程序进行释放,然后调用ruby去执行脚本,对脚本没有保护作用,释放出来的脚本就是原脚本,直接拿来逆完事。

ocra安装方法非常简单:

gem install ocra

直接找到rb脚本位置:

require 'openssl'  
require 'base64'  

def aes_encrypt(key,encrypted_string)
    aes = OpenSSL::Cipher.new("AES-128-ECB")
    aes.encrypt
    aes.key = key
    cipher = aes.update(encrypted_string) << aes.final
    return Base64.encode64(cipher) 
end

print "Enter flag: "
flag = gets.chomp

key = "Welcome_To_GACTF"
cipher = "4KeC/Oj1McI4TDIM2c9Y6ahahc6uhpPbpSgPWktXFLM=\n"

text = aes_encrypt(key,flag)
if cipher == text
    puts "good!"
else
    puts "no!"
end

AES的ecb模式,有密文和密钥,直接拿去解密:

EasyRe

首先进行smc的解密代码块,这里是魔改的xxtea算法,所以自己写个解密脚本,然后把代码块进行patch,就能读取正常的加密和判断了,或者对输入的部分下硬件断点,跳过解密代码部分动态调试到关键位置。

xxtea解密脚本:

#include <stdio.h>  
#include <stdint.h>  
#define DELTA 0x4e782ff0  

void btea(uint32_t *v, int n, uint32_t const key[4])  
{  
    uint32_t y, z, sum;  
    unsigned i, rounds, e;  
    if (n > 1)            //n作为加解密的选择,正数为加密,负数为解密
    {  
        rounds = 9 + 34/n; //轮转数的选择,是个特征值:6+52/n
        sum = 0;  
        z = v[n-1]; //先取出最后一个值  
        do  
        {  
            sum += DELTA;  //开始加密
            e = (sum >> 2) & 3;  //通过sum得到e,也是个特征值
            for (i=0; i<n-1; i++)  //轮转次数
            {  
                y = v[i+1];  //得到
                v[i] += (((z>>4^y<<1) + (y>>3^z<<5) + 0x28) ^ ((sum^y^0x77) + (key[(i&3)^e] ^ z)-0xf));  
                z = v[i];
                //细细分析就会知道,首先通过v[n-1]和v[1]进行加密得到v[0],然后通过v[0]和v[2]加密得到v[1]就会发现规律了:其实就是3个数为一组,通过左右两个数加密得到中间的数这里只会运算到v[n-2]
            }  
            y = v[0];  
            v[n-1] += (((z>>4^y<<1) + (y>>3^z<<5) + 0x28) ^ ((sum^y^0x77) + (key[(i&3)^e] ^ z)-0xf));  
            z = v[n-1];//最后一个数v[n-1]的加密,拿到v[0]和v[n-2]进行加密得到,算法一样
        }  //第一轮结束,每个数都加密了一遍
        while (--rounds);   //执行rounds轮,加密完全
    }  
    else if (n < -1)   //当负数时就是解密
    {  
        n = -n;  //首先把负数转成正数
        rounds = 9 + 34/n;  //确定轮转数
        sum = rounds*DELTA;  //根据轮转数计算sum
        y = v[0];  
        do  
        {  
            e = (sum >> 2) & 3;  
            for (i=n-1; i>0; i--) //逆序倒推
            {  
                z = v[i-1];  //先解密v[n-1],需要知道v[0]和v[n-2],
                v[i] -= (((z>>4^y<<1) + (y>>3^z<<5) + 0x28) ^ ((sum^y^0x77) + (key[(i&3)^e] ^ z)-0xf));  
                y = v[i];//只会解密到v[1]
            }  
            z = v[n-1]; //对于第一个v[0]的解密,要知道v[n-1]和v[1] 
            v[0] -= (((z>>4^y<<1) + (y>>3^z<<5) + 0x28) ^ ((sum^y^0x77) + (key[(i&3)^e] ^ z)-0xf));  
            y = v[0]; 
            sum -= DELTA;//sum的减减
        }  
        while (--rounds);  
    }  
}  
void xxtea(uint32_t *v, int n, uint32_t const key[4])  
{  
    uint32_t y, z, sum;  
    unsigned i, rounds, e;  
    rounds = 9 + 34/n;  //确定轮转数
    sum = rounds*DELTA;  //根据轮转数计算sum
    y = v[0];  
    do  
    {  
        e = (sum >> 2) & 3;  
        for (i=n-1; i>0; i--) //逆序倒推
        {  
            z = v[i-1];  //先解密v[n-1],需要知道v[0]和v[n-2],
            v[i] -= (((z>>4^y<<1) + (y>>3^z<<5) + 0x28) ^ ((sum^y^0x77) + (key[(i&3)^e] ^ z)-0xf));  
            y = v[i];//只会解密到v[1]
        }  
        z = v[n-1]; //对于第一个v[0]的解密,要知道v[n-1]和v[1] 
        v[0] -= (((z>>4^y<<1) + (y>>3^z<<5) + 0x28) ^ ((sum^y^0x77) + (key[(i&3)^e] ^ z)-0xf));  
        y = v[0]; 
        sum -= DELTA;//sum的减减
    }  
    while (--rounds);  
}

int main()  
{
    // uint32_t v[365] = {0x53E58955, 0x8B24EC83, 0x408B0845, 0x00B60F20, 0x2F75713C, 0x8B08458B, 0x508D1840, 0x08458BFC, 0x8B185089, 0x408B0845, 0x08558B18, 0x8B20528B, 0x10890152, 0x8B08458B, 0x508D2040, 0x08458B05, 0x8B205089, 0x408B0845, 0x00B60F20, 0x2375413C, 0x8B08458B, 0x458B0450, 0x08408B08, 0x458BC201, 0x04508908, 0x8B08458B, 0x508D2040, 0x08458B01, 0x8B205089, 0x408B0845, 0x00B60F20, 0x2375423C, 0x8B08458B, 0x458B0450, 0x10408B08, 0x458BC229, 0x04508908, 0x8B08458B, 0x508D2040, 0x08458B01, 0x8B205089, 0x408B0845, 0x00B60F20, 0x2475433C, 0x8B08458B, 0x458B0450, 0x0C408B08, 0x8BD0AF0F, 0x50890845, 0x08458B04, 0x8D20408B, 0x458B0150, 0x20508908, 0x8B08458B, 0xB60F2040, 0x75443C00, 0x08458B2A, 0x8B04408B, 0x5A8B0855, 0x0000BA14, 0xF3F70000, 0x458BC289, 0x04508908, 0x8B08458B, 0x508D2040, 0x08458B01, 0x8B205089, 0x408B0845, 0x00B60F20, 0x3075803C, 0x6A085D8B, 0x0875FF01, 0xFFFEBDE8, 0x08C483FF, 0x8D02E0C1, 0x458B0314, 0x20408B08, 0x8902408B, 0x08458B02, 0x8D20408B, 0x458B0650, 0x20508908, 0x8B08458B, 0xB60F2040, 0x75773C00, 0x08458B23, 0x8B04508B, 0x408B0845, 0x8BC23124, 0x50890845, 0x08458B04, 0x8D20408B, 0x458B0150, 0x20508908, 0x8B08458B, 0xB60F2040, 0x75533C00, 0x08458B27, 0x0F0C408B, 0xBE0F00B6, 0x0CEC83C0, 0xFC65E850, 0xC483FFFF, 0x08458B10, 0x8D20408B, 0x458B0250, 0x20508908, 0x8B08458B, 0xB60F2040, 0x75223C00, 0x08458B25, 0x8B04508B, 0x408B0845, 0xD3C18908, 0x08458BEA, 0x8B045089, 0x408B0845, 0x01508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B257523, 0x508B0845, 0x08458B04, 0x8908408B, 0x8BE2D3C1, 0x50890845, 0x08458B04, 0x8D20408B, 0x458B0150, 0x20508908, 0x8B08458B, 0xB60F2040, 0x0F993C00, 0x00035D84, 0x08458B00, 0x0F20408B, 0x763C00B6, 0x458B3875, 0x18408B08, 0x458B108B, 0x0C508908, 0x8B08458B, 0x00C71840, 0x00000000, 0x8B08458B, 0x508D1840, 0x08458B04, 0x8B185089, 0x408B0845, 0x05508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B247554, 0x408B0845, 0xE445890C, 0xFFFB0EE8, 0x8BC289FF, 0x1088E445, 0x8B08458B, 0x508D2040, 0x08458B02, 0x8B205089, 0x408B0845, 0x00B60F20, 0x2375303C, 0x8B08458B, 0x458B0450, 0x08408B08, 0x458BC209, 0x04508908, 0x8B08458B, 0x508D2040, 0x08458B01, 0x8B205089, 0x408B0845, 0x00B60F20, 0x2375313C, 0x8B08458B, 0x458B0450, 0x08408B08, 0x458BC221, 0x04508908, 0x8B08458B, 0x508D2040, 0x08458B01, 0x8B205089, 0x408B0845, 0x00B60F20, 0x1B75093C, 0xB28C158B, 0x458B0804, 0x04508908, 0x8B08458B, 0x508D2040, 0x08458B01, 0x8B205089, 0x408B0845, 0x00B60F20, 0x1B75103C, 0x8B08458B, 0x458B0450, 0x24508908, 0x8B08458B, 0x508D2040, 0x08458B01, 0x8B205089, 0x408B0845, 0x00B60F20, 0x2675113C, 0x8B08458B, 0xEC830440, 0x2C685008, 0xE8080491, 0xFFFFFA17, 0x8B10C483, 0x408B0845, 0x01508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B2875A0, 0x408B0845, 0xD1003D04, 0x117526F8, 0x8B08458B, 0x508D2040, 0x08458B01, 0xEB205089, 0x0CEC830A, 0x20E8006A, 0x8BFFFFFA, 0x408B0845, 0x00B60F20, 0x5275A13C, 0x680CEC83, 0x08049130, 0xFFF9B6E8, 0x10C483FF, 0x6A04EC83, 0xB2E06828, 0x006A0804, 0xFFF992E8, 0x10C483FF, 0x680CEC83, 0x0804B2E0, 0xFFF9F2E8, 0x10C483FF, 0x7421F883, 0x0CEC830A, 0xD0E8006A, 0x8BFFFFF9, 0x408B0845, 0x01508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B1B75B1, 0x04B2A015, 0x08458B08, 0x8B245089, 0x408B0845, 0x01508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B1B75B2, 0x04B2A415, 0x08458B08, 0x8B245089, 0x408B0845, 0x01508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B3775A4, 0x408B0845, 0x01C08320, 0x0F00B60F, 0x4589C0B6, 0x08458BE8, 0x8904408B, 0x558BEC45, 0xE8458BEC, 0xA0851489, 0x8B0804B2, 0x408B0845, 0x04508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B1B75B3, 0x04B2A815, 0x08458B08, 0x8B245089, 0x408B0845, 0x01508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B1B75B4, 0x04B2AC15, 0x08458B08, 0x8B245089, 0x408B0845, 0x01508D20, 0x8908458B, 0x458B2050, 0x20408B08, 0x3C00B60F, 0x8B3575C1, 0x408B0845, 0x01C08320, 0x0F00B60F, 0x4589C0B6, 0xF0458BF0, 0x04B2E005, 0x00B60F08, 0x8BD0B60F, 0x50890845, 0x08458B04, 0x8D20408B, 0x458B0250, 0x20508908, 0x8B08458B, 0xB60F2040, 0x0FC23C00, 0xFFFAC285, 0x08458BFF, 0x8320408B, 0x008B01C0, 0x8BF44589, 0x508B0845, 0xF4458B04, 0x0A74C239, 0x6A0CEC83, 0xF865E800, 0x458BFFFF, 0x20408B08, 0x8B05508D, 0x50890845, 0xFA89E920, 0x9090FFFF, 0xC9FC5D8B};
    uint32_t v[365] = {0x80F5C030, 0x68EFB2F0, 0x198D1344, 0xA9F9E731, 0xC0BCB5C3, 0x1BE3015C, 0x482E940D, 0xA77F6C66, 0xC5AF359B, 0x70E5E827, 0xCF090920, 0xABC1ACD6, 0x7F7CAFD8, 0x3C8C733B, 0xDD2C00D8, 0x65F845E5, 0xF63D14CB, 0xEF03AAFB, 0x5137D0CB, 0xF5E80826, 0xDB1682B4, 0x8E86556B, 0x42AB135D, 0x3A402E99, 0x8B719AB7, 0xA623F0FD, 0x55AE7814, 0x3AF95E3B, 0x5FB0F9F9, 0x404643B5, 0x37FF9F63, 0xFA9F19DE, 0x8874911D, 0x71450508, 0xFED97F2E, 0xB5325DC5, 0x6220674A, 0x8F297C87, 0x963E563C, 0x55268913, 0xE4A6DF41, 0xA3AF3AA4, 0x64CD4DD2, 0xD6EE8961, 0x57635E35, 0xB0685FCB, 0xC4F24E2F, 0x6C8E153C, 0x9790C0A8, 0x711ABD20, 0xD1C5B277, 0x78884F46, 0xB2DDE915, 0x3AE1691A, 0x136BC9E1, 0xD7FCA2B3, 0x05BD4A70, 0x72FF32F1, 0x8FFFDF6E, 0x6017F0F2, 0x68CB5E14, 0xEF92B75E, 0x2A0C5FC5, 0xE019D738, 0x748F665D, 0xC5AE3010, 0xFBADB128, 0xAF1C1EE8, 0x459A5438, 0x7B8F87B3, 0x0BA3FC43, 0xAD46BD4F, 0x5AFDF9EE, 0x8A4465AF, 0xECCAF497, 0xEE4CE338, 0x0A620D6D, 0x70848AC2, 0x5AE64C86, 0x67177020, 0x6A16C201, 0xE6ED7ECE, 0x5B3A6F79, 0x464A4EDA, 0xD4DB9081, 0xEF73FC60, 0xC0508664, 0x64EE15FA, 0x2239B49C, 0xD44C54E5, 0x58C5D269, 0x28448242, 0x8CFDEFA8, 0x99150E4D, 0x6BD3DC27, 0x9C1537D7, 0x581FB6C2, 0x10D975D5, 0x85B9D191, 0x8A79A8FA, 0x8DB84B2C, 0xF1DFAD1D, 0xF35B0169, 0x2A6198D9, 0x197936BA, 0xB324CB12, 0x2603EB38, 0xC13116A1, 0x1D979808, 0xA310E32B, 0x8102A6F1, 0xE19DB151, 0x2760870C, 0x6F708DEC, 0xF3C5CF04, 0x2F1F1626, 0xE71B426D, 0x6AE66A30, 0x9F91AA45, 0x63CBBB35, 0x8D14ABB4, 0xAF363CCD, 0x8F077147, 0x08105552, 0x623920BB, 0xB7D650D8, 0xF88CD374, 0x4071AEC4, 0xC378B6D7, 0x40116A58, 0xE9ED5EC4, 0x61BD865C, 0x03B45681, 0xF53FCE4A, 0xDB2370EE, 0xB8CABEE8, 0xBF4363E3, 0xD4C435F0, 0x6B0A0773, 0xB3672C23, 0x3211FCF1, 0xDF0C8969, 0xB79F07BD, 0x98C1B236, 0xD5363C9A, 0x05FC6C03, 0xE1A62CEF, 0x96647EFA, 0x229E577B, 0x59DF76CE, 0x62C8DA0D, 0xF737ED41, 0xBF58244F, 0x9D75A720, 0x9C212D16, 0xE1500A43, 0x2186F6E4, 0xFDEAD95B, 0x77ECAEF6, 0x737C6205, 0x82CB0D85, 0xF3CD48D7, 0xF9A9A370, 0x71928757, 0x32437188, 0xA5942817, 0xED6C554B, 0xDE05D02C, 0xA17BD0BD, 0x96E32774, 0x184333A3, 0x7CFE2D99, 0x137BAC6D, 0x8D0533F8, 0x36D91D3B, 0x89411D09, 0x80DBEC2F, 0xC05409D9, 0x019FDA3E, 0x807D06DA, 0xD603C266, 0x39749648, 0xD30569B2, 0xB9AE6C6F, 0x9F82B069, 0x0ECE869F, 0x5DA71196, 0x156D4FD6, 0x2E40BDF7, 0xA16D7BCA, 0x563972A3, 0x67BB15C6, 0xBEEBB0E2, 0x41CAD2EB, 0xA4934A7F, 0x570F9D13, 0xB0AACBE8, 0x1C8AF56C, 0xC9C80F96, 0x297105F5, 0x59BBE2A7, 0xCA5D940A, 0xE9177734, 0x3B5EB414, 0xFC3CDD67, 0xE2662E93, 0x1512C9C0, 0xB6A5DBBB, 0x7B3EE58C, 0x41FEA77A, 0xA7CF5E3B, 0xAE787013, 0xDE17FC2A, 0x894CE4AC, 0x2E4EABEC, 0xD3A045A9, 0x80131C8A, 0x19852BFA, 0x9199EDF3, 0xB7C9D21D, 0x79FF4E2A, 0x189606B4, 0x780641BF, 0xB9FAE735, 0xB629961C, 0x6820CEE2, 0x76BAE616, 0x2C7332CE, 0x16E35283, 0xCEE0AC7C, 0xFD37D1E8, 0x765297B4, 0xD7EE7D12, 0xB2CFB5D3, 0x154B7337, 0x82FE7F53, 0x432AD9E1, 0x76B6B915, 0x05EB8A2E, 0x9325DC11, 0x01461261, 0xEC3A1290, 0x48AC76D9, 0xEED85841, 0xBEE19820, 0x55B1AE86, 0x78713530, 0x10DD5EBB, 0xF4E4266F, 0x57CC9924, 0xDAA4D742, 0x46DCE9F3, 0xB65FBA1D, 0x282402F8, 0x628423A7, 0x904D366F, 0x78DEFBAC, 0x7E0AA3A6, 0x3F59FDFC, 0x569B2203, 0x9E5C5BAB, 0x86078247, 0x101F8740, 0x45786816, 0x9C059359, 0x13F69501, 0xE6F762C3, 0xA5E3C894, 0x139F7501, 0xF177147C, 0x491EE2E6, 0x9222FC73, 0x7E3561A3, 0xBF939C67, 0x2D66EF32, 0x4425F172, 0xBD4D9B79, 0x5F92F741, 0x7B18C869, 0xC7924F51, 0x554B188F, 0xCBC2518D, 0xDFACE9F9, 0xAF28A4CD, 0x2D447AB1, 0x4B306F9E, 0x2DC2A701, 0x584A1FD3, 0xA3474083, 0x8E7FA2A4, 0x67FF24C7, 0x227CCA69, 0x936C5084, 0x56662A5A, 0x660180D6, 0x7BCC181E, 0xE06FA6D6, 0x89C58B86, 0x2A9B7C02, 0x32B585D9, 0xA4CFA5F3, 0xCEBF5E93, 0x2850B3F0, 0xAAB717BB, 0x02BF64AF, 0x929814DA, 0x4FE4E051, 0x60C422C5, 0x6B327DBD, 0x9B5AC84B, 0x8E895FC7, 0xF223511C, 0xDC407E2F, 0x8906766E, 0x168E71EC, 0xB6B7852F, 0x9C8FD604, 0xC896E2E2, 0xE9C8A3C1, 0xE43C9A51, 0xB83F0F94, 0xD69CB7FA, 0xA58132FE, 0x4E632113, 0xBC068776, 0xF061682A, 0x536187D2, 0xE3229C68, 0xAE993752, 0x72798269, 0x1920E061, 0xC04776A4, 0xA44DC6F1, 0x060794AA, 0xA0465169, 0x93DC7069, 0x0FC2BB3C, 0x46D578CB, 0x2CD1D27F, 0x713BC1C1, 0x3AF1AD80, 0xECBA6B97, 0xDE32200C, 0x3F22F672, 0x4DFD1F54, 0xF47AB4AB, 0x5BF3B23A, 0x3C7672A1, 0xFBB785BD, 0x294A1AF3, 0xC2BF96D5, 0xE4EA0AF4, 0x8F14A8E1, 0x7130F547, 0x36C6EC7C, 0x92C0CD79, 0x72309B95, 0x1AF1EE94, 0xC588E0D7, 0xF94D8DE6, 0x5C5D372D, 0x72BC90EA};
    int n = 362;
    // uint32_t v[10]= {0xf3ee2287,0x12223344,0xaabbccdd,0x31223344,0x14442233,0xa5aabbcc,0x33ff22f6,0x78899117,0x10810099};  
    uint32_t const k[4]= {0x18,0x22,0x30,0x11};  
    // int n= 8; //n的绝对值表示v的长度,取正表示加密,取负表示解密  
    // v为要加密的数据是两个32位无符号整数  
    // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位  
    // for(int i=0;i<n;i++)
    // {
    //     printf("加密前原始数据:%x\n",v[i]);
    // }
    // printf("加密前原始数据:%x %u %u %u %u %u %u %u\n",v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);  
    // btea(v, n, k);  
    // for(int i=0;i<n;i++)
    // {
    //     printf("0x%x,",v[i]);
    // }
    // printf("加密后的数据:%x %u %u %u %u %u %u %u\n",v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);
    
xxtea(v, n, k);
for(int i=0;i<n;i++)
{
    printf("0x%x,",v[i]);
}  
// printf("解密后的数据:%x %u %u %u %u %u %u %u\n",v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]);
return 0;  
}  

ida的patch脚本:

#!/usr/bin/env python
a = [0x53e58955,0x8b34ec83,0x45890845,0x14a165d4,0x89000000,0xc031f445,0x8bd4458b,0xb60f2040,0x75713c00,0xd4458b2f,0x8d18408b,0x458bfc50,0x185089d4,0x8bd4458b,0x558b1840,0x20528bd4,0x8901528b,0xd4458b10,0x8d20408b,0x458b0550,0x205089d4,0x8bd4458b,0xb60f2040,0x75413c00,0xd4458b23,0x8b04508b,0x408bd445,0x8bc20108,0x5089d445,0xd4458b04,0x8d20408b,0x458b0150,0x205089d4,0x8bd4458b,0xb60f2040,0x75423c00,0xd4458b23,0x8b04508b,0x408bd445,0x8bc22910,0x5089d445,0xd4458b04,0x8d20408b,0x458b0150,0x205089d4,0x8bd4458b,0xb60f2040,0x75433c00,0xd4458b24,0x8b04508b,0x408bd445,0xd0af0f0c,0x89d4458b,0x458b0450,0x20408bd4,0x8b01508d,0x5089d445,0xd4458b20,0xf20408b,0x443c00b6,0x458b2a75,0x4408bd4,0x8bd4558b,0xba145a,0xf7000000,0x8bc289f3,0x5089d445,0xd4458b04,0x8d20408b,0x458b0150,0x205089d4,0x8bd4458b,0xb60f2040,0x75803c00,0xd45d8b33,0x6a08ec83,0xd475ff01,0xfffe7ee8,0x10c483ff,0x8d02e0c1,0x458b0314,0x20408bd4,0x8902408b,0xd4458b02,0x8d20408b,0x458b0650,0x205089d4,0x8bd4458b,0xb60f2040,0x75773c00,0xd4458b23,0x8b04508b,0x408bd445,0x8bc23124,0x5089d445,0xd4458b04,0x8d20408b,0x458b0150,0x205089d4,0x8bd4458b,0xb60f2040,0x75533c00,0xd4458b27,0xf0c408b,0xbe0f00b6,0xcec83c0,0xfc0ae850,0xc483ffff,0xd4458b10,0x8d20408b,0x458b0250,0x205089d4,0x8bd4458b,0xb60f2040,0x75223c00,0xd4458b25,0x8b04508b,0x408bd445,0xd3c18908,0xd4458bea,0x8b045089,0x408bd445,0x1508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b257523,0x508bd445,0xd4458b04,0x8908408b,0x8be2d3c1,0x5089d445,0xd4458b04,0x8d20408b,0x458b0150,0x205089d4,0x8bd4458b,0xb60f2040,0xf993c00,0x35d84,0xd4458b00,0xf20408b,0x763c00b6,0x458b3875,0x18408bd4,0x458b108b,0xc5089d4,0x8bd4458b,0xc71840,0x0,0x8bd4458b,0x508d1840,0xd4458b04,0x8b185089,0x408bd445,0x5508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b247554,0x408bd445,0xe045890c,0xfffab3e8,0x8bc289ff,0x1088e045,0x8bd4458b,0x508d2040,0xd4458b02,0x8b205089,0x408bd445,0xb60f20,0x2375303c,0x8bd4458b,0x458b0450,0x8408bd4,0x458bc209,0x45089d4,0x8bd4458b,0x508d2040,0xd4458b01,0x8b205089,0x408bd445,0xb60f20,0x2375313c,0x8bd4458b,0x458b0450,0x8408bd4,0x458bc221,0x45089d4,0x8bd4458b,0x508d2040,0xd4458b01,0x8b205089,0x408bd445,0xb60f20,0x1b75093c,0xb28c158b,0x458b0804,0x45089d4,0x8bd4458b,0x508d2040,0xd4458b01,0x8b205089,0x408bd445,0xb60f20,0x1b75103c,0x8bd4458b,0x458b0450,0x245089d4,0x8bd4458b,0x508d2040,0xd4458b01,0x8b205089,0x408bd445,0xb60f20,0x2675113c,0x8bd4458b,0xec830440,0xc685008,0xe8080492,0xfffff9bc,0x8b10c483,0x408bd445,0x1508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b2875a0,0x408bd445,0xd1003d04,0x117526f8,0x8bd4458b,0x508d2040,0xd4458b01,0xeb205089,0xcec830a,0xc5e8006a,0x8bfffff9,0x408bd445,0xb60f20,0x5275a13c,0x680cec83,0x8049210,0xfff95be8,0x10c483ff,0x6a04ec83,0xb2e06828,0x6a0804,0xfff937e8,0x10c483ff,0x680cec83,0x804b2e0,0xfff997e8,0x10c483ff,0x7421f883,0xcec830a,0x75e8006a,0x8bfffff9,0x408bd445,0x1508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b1b75b1,0x4b2a015,0xd4458b08,0x8b245089,0x408bd445,0x1508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b1b75b2,0x4b2a415,0xd4458b08,0x8b245089,0x408bd445,0x1508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b3775a4,0x408bd445,0x1c08320,0xf00b60f,0x4589c0b6,0xd4458be4,0x8904408b,0x558be845,0xe4458be8,0xa0851489,0x8b0804b2,0x408bd445,0x4508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b1b75b3,0x4b2a815,0xd4458b08,0x8b245089,0x408bd445,0x1508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b1b75b4,0x4b2ac15,0xd4458b08,0x8b245089,0x408bd445,0x1508d20,0x89d4458b,0x458b2050,0x20408bd4,0x3c00b60f,0x8b3575c1,0x408bd445,0x1c08320,0xf00b60f,0x4589c0b6,0xec458bec,0x4b2e005,0xb60f08,0x8bd0b60f,0x5089d445,0xd4458b04,0x8d20408b,0x458b0250,0x205089d4,0x8bd4458b,0xb60f2040,0xfc23c00,0xfffabf85,0xd4458bff,0x8320408b,0x8b01c0,0x8bf04589,0x508bd445,0xf0458b04,0xa74c239,0x6a0cec83,0xf80ae800,0x458bffff,0x20408bd4,0x8b05508d,0x5089d445,0xfa86e920,0x9090ffff,0x65f4458b,0x140533,0x5740000,0xfff7b3e8,0xfc5d8bff]

k = 0
for i in range(len(a)):
    PatchDword(0x08048838+k, a[i])
    k += 4

接下来会发现是个vm虚拟机逆向,按照套路手撕代码即可,首先是对输入的key的加密,这里进行的是移位和线性操作,然后取key里的值对明文进行异或加密,使用的key的顺序不同。最后解出来flag。

# -*- coding: utf-8 -*-
def re(number):
    num = number
    a = num >> 13
    b = num >> 19
    c = num & 0x1fff
    d = b ^c
    res = (a << 13) + d
    a = res & 0x1ffff
    p = 0x85d40000
    b = (p & 0xfffe0000)>>17
    c = (res & 0xfffe0000)>>17
    d = (a & b) ^ c
    ans = (d << 17) + a
    p = 0x78f39600
    a = ans & 0x1ff
    b = (p >> 9) & 0x1ff 
    c = (ans >> 9) & 0x1ff
    d = (a & b) ^ c 
    e = (p >> 18) & 0x1ff
    f = (ans >> 18) & 0x1ff
    h = (d & e) ^ f
    i = h & 0x1f
    j = p >> 27
    k = ans >> 27
    l = (i & j) ^ k
    res = (l << 27) + (h << 18) + (d << 9) + a
    a = res >> 19
    b = (res >> 6) & 0x1fff 
    c = a ^ b
    d = c >> 7
    e = res & 0x3f
    f = d ^ e
    ans = (a << 19) + (c << 6) + f
    return ans

k = re(0x26f8d100)
#k = 0xFFE8BC9A
key = [0,0,0,0]
key[0] = 0x9a*2+0x18
key[1] = 0xbc/7+0x21
key[2] = 0xe8^0xbb+0xff
key[3] = 0xff-0xa0+0x77
# key = [332, 59, 338, 214]
enc = [0x10b,0x7a,0x95,0x106 ,0x7d ,0xad ,0x12f, 0x165, 0x12d ,0x12f, 0x139, 0x10d, 0xbb ,0x8 ,0x10d ,0x13f, 0x13a ,0x161 ,0x57 ,0x120, 0x10d, 0x13f ,0x13f, 0xb5, 0x113, 0xa0 ,0x121 ,0x10d, 0xb, 0x139, 0x173, 0x46]
#0132
#1302
#0022
#3120
#2210
#2023
#0302
#1201
flag = ""
flag += chr(enc[0]^key[0])
flag += chr(enc[1]^key[1])
flag += chr(enc[2]^key[3])
flag += chr(enc[3]^key[2])
flag += chr(enc[4]^key[1])
flag += chr(enc[5]^key[3])
flag += chr(enc[6]^key[0])
flag += chr(enc[7]^key[2])
flag += chr(enc[8]^key[0])
flag += chr(enc[9]^key[0])
flag += chr(enc[10]^key[2])
flag += chr(enc[11]^key[2])
flag += chr(enc[12]^key[3])
flag += chr(enc[13]^key[1])
flag += chr(enc[14]^key[2])
flag += chr(enc[15]^key[0])
flag += chr(enc[16]^key[2])
flag += chr(enc[17]^key[2])
flag += chr(enc[18]^key[1])
flag += chr(enc[19]^key[0])
flag += chr(enc[20]^key[2])
flag += chr(enc[21]^key[0])
flag += chr(enc[22]^key[2])
flag += chr(enc[23]^key[3])
flag += chr(enc[24]^key[0])
flag += chr(enc[25]^key[3])
flag += chr(enc[26]^key[0])
flag += chr(enc[27]^key[2])
flag += chr(enc[28]^key[1])
flag += chr(enc[29]^key[2])
flag += chr(enc[30]^key[0])
flag += chr(enc[31]^key[1])
print flag
#GACTF{c7ack_m3_sh3ll_smc_vm_0k?}

WannaFlag

算法的关键比较在sub_402280处,逻辑比较容易分析:

解题脚本:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <intrin.h>

using namespace std;

char key[0x50] = "\x4E\xAE\x61\xBA\xE4\x2B\x55\xAA\x59\xFC\x4D\x02\x17\x6B\x13\xA1\x41\xFE\x35\x0B\xB4\x0B\x52\x2F\x46\xCC\x35\x82\xE5\x88\x50";
char passwordtable[0x50] = "ANNAWGALFYBKVIAHMXTFCAACLAAAAYK";

int len;

int main() {
    len = strlen(key);
    for (int i = 0; i < len; i++) {
        key[i] = _rotr8(key[i], i);
        key[i] ^= passwordtable[i];
    }
    //接下来,枚举所有可能
    for (int c_5 = 32; c_5 < 128; c_5++) {
        int mod = c_5 % 0x7;
        int fac = 1;
        for (int i = 2; i < mod; i++) {
            fac *= i;
        }
        if (c_5 ^ fac == key[4]) {
            cout << "c_5==" << (char)c_5 << endl;
            for (int i = 0; i < len; i++) {
                cout << (char)(key[i] ^ fac);
            }
            cout << endl;
        }
    }
}

Simulator

虚拟机题,代码框架为LC3, 可以用LC3 Simulate进行加载运行

调试后可以知道以下信息

  • R0 保留,用于各种操作,以及函数返回值
  • R1 保留,用于各种操作
  • R2 与R4配合获得OPCODE
  • R3 计数器
  • R4 OPCODE的地址
  • R5 保留,用于各种操作
  • R6 传参(从右向左第二个参数)
  • R7 传参 (从右向左第一个参数)

程序对所有标识都进行了混淆

根据逆向可以知道如下对应关系

LOOP_INPUT: O
START_VM: OO
LOOP_VM: OOO
myADD: OOOO
FUN_ADD_RETURN: OOOOO
FUN_ADD: OOOOOO
myXOR: OOOOOOO
FUN_XOR_RETURN: OOOOOOOO
FUN_XOR: OOOOOOOOO
myCHECK: OOOOOOOOOO
FUN_CHECK_RETURN: OOOOOOOOOOO
FUN_CHECK: OOOOOOOOOOOO
ADD_FLAG: OOOOOOOOOOOOO
XOR_FLAG: OOOOOOOOOOOOOO
CHECK_FLAG: OOOOOOOOOOOOOOO
CHECK_NUM: OOOOOOOOOOOOOOOO
OPCODE: OOOOOOOOOOOOOOOOO

其中:

ADD_FLAG 为 17

XOR_FLAG 为 19

CHECK_FLAG 为 20

flag长度为25

根据动态调试可以理解流程:

  • 首先获取输入, 且整个输入存储为倒序存储,例如输入123, 在内存中0x40000x4002存储为321
  • 从第0位开始到第23位数字执行如下操作

    • 与前一位进行异或
    • 然后跟CHECK_NUM进行校验,校验失败跳转TRY_AGAIN,然后结束。如果成功则判断是否已经判断到第0位,是则跳转SUCCESS, 否则继续执行
  • 然后对最后一位直接执行校验

用python表示如下:

input = ""[::-1]

check_num = [108, 15, 80, 108, 110, 66, 44, 44, 30, 12, 13, 0, 51, 61, 23, 1, 43, 60, 12, 2, 29, 28, 9, 17, 17]

def check(i, j):
    return input[i] == check_num[j]

for i in range(0, 24):
    input[i] ^= input[i + 1]
    if check(i, 24 - i) == False:
        print("Try again!")
        break
if check(24, 0) == False:
    print("Try again!")

解密脚本:

check_num = [108, 15, 80, 108, 110, 66, 44, 44, 30, 12, 13, 0, 51, 61, 23, 1, 43, 60, 12, 2, 29, 28, 9, 17, 17]

for i in range(1, 25):
    check_num[i] ^= check_num[i - 1]

print('xmctf{' +  ''.join(list(map(chr,check_num))) + '}')

得到flag:xmctf{lc3_1s_small_but_complete}

PicCompress

前段时间读到一篇文章讲了压缩算法,然后就照着用了一下,发现挺有意思的,这道题使用的是LZSS算法,是LZ77压缩算法的一个衍生算法,使用数据的重复信息来进行压缩。

像被LZSS,LZ77这种压缩算法压缩后的文件有一个特征,就是开头的几个不同字节由于第一次出现所以不会被压缩,对比下bmp图片的文件头和题目给定的压缩后文件,可以确定这是一张bmp图片,然后在调试中可知,将每部分作为表放入二叉树进行最大长度的遍历。

然后详细的关于算法的原理,可以看下:
https://blog.csdn.net/dl0914791011/article/details/41319245
可以直接拿4/6/1989 Haruhiko Okumura的LZSS来解压缩
https://opensource.apple.com/source/boot/boot-132/i386/boot2/lzss.c

void Decode(void)    /* Just the reverse of Encode(). */
{
    int  i, j, k, r, c;
    unsigned int  flags;
for (i = 0; i < N - F; i++) text_buf[i] = ' ';
r = N - F;  flags = 0;
for (; ; ) {
    if (((flags >>= 1) & 256) == 0) {
        if ((c = getc(infile)) == EOF) break;
        flags = c | 0xff00;        /* uses higher byte cleverly */
    }                            /* to count eight */
    if (flags & 1) {
        if ((c = getc(infile)) == EOF) break;
        putc(c, outfile);  text_buf[r++] = c;  r &= (N - 1);
    }
    else {
        if ((i = getc(infile)) == EOF) break;
        if ((j = getc(infile)) == EOF) break;
        i |= ((j & 0xf0) << 4);  j = (j & 0x0f) + THRESHOLD;
        for (k = 0; k <= j; k++) {
            c = text_buf[(i + k) & (N - 1)];
            putc(c, outfile);  text_buf[r++] = c;  r &= (N - 1);
        }
    }
}
}

InfaintRe

简单的椭圆曲线,a=1,b=0,p=20619522630365746025487407
然后已知点p1(2426060508202830279419664, 5517895499364845267563628)
Secert * p1 = (0x47d881b4d15078dd1fb5f, 0xf14fdbe413b467cf64d8f)
使用mov attack求出secret,第一部分flag:99ca867c

这里用下vidar-team师傅的脚本:

P = E(0x47d881b4d15078dd1fb5f, 0xf14fdbe413b467cf64d8f)
n = G.order()

canwemove = False
for k in range(1,10):
    if (p^k-1) % n == 0:
        canwemove = True
        break
assert canwemove

Fp2.<z> = GF(p^k)
Ex = E.change_ring(Fp2)
G2 = Ex(G)
P2 = Ex(P)

while True:
Q = Ex.random_element()
Q = Q.order()//n*Q
if Q.order() == n and G2.weil_pairing(Q, n) != 1:
    break
g = G2.weil_pairing(Q, n)
h = P2.weil_pairing(Q, n)
key = discrete_log(h, g)
print(key)
#2580186748

第二部分使用3way加密:

key[0] = 0xdeadbeef;
key[1] = 0xddbbccdd;
key[2] = 0x7865addb;
part_two_aim[0] = 0x5e531f7c;
part_two_aim[1] = 0x99080122;
part_two_aim[2] = 0xc938e326;

脚本参考:
https://raw.githubusercontent.com/stamparm/cryptospecs/master/symmetrical/sources/3-way.c

即可求出flag第二部分:s1mp13_g4m3!

PS:我是GACTF负责整理逆向wp的工具人,我就整理到这了,可能有些地方不完整,可以参考下网上师傅们的wp进行复现。

温柔正确的人总是难以生存,因为这世界既不温柔,也不正确

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!