主頁 >  其他 > 逆向中常見的Hash演算法和對稱加密演算法的分析

逆向中常見的Hash演算法和對稱加密演算法的分析

2021-09-08 07:39:36 其他

逆向中常常出現一些加密演算法,如果我們能對這些加密演算法進行快速識別則會大大減少我們逆向的難度,雖然IDA已有密碼分析神器Findcrypt,但掌握手動分析方法能幫助我們應對更多的情況,這篇文章將介紹逆向中常見的單項散列演算法和對稱加密演算法的識別方法,

0xFF. 前言

在很長一段時間里我經常發現自己面對復雜的加密演算法無從下手,可能是因為還沒有系統學過密碼學吧orz,總之這個問題困擾了我很久,于是最近我花了一些時間來解決自己在密碼學這塊的薄弱點,寫下這篇文章的目的之一也是為了鞏固所學知識,
加密演算法的部分沒有涉及公鑰加密演算法(因為我不會hh),每個演算法都有一個例子,這些例子出自《加密與解密(第4版)》第6章的隨書附帶檔案和各大比賽中的題目,

0x00. 目錄

單向散列演算法:

  1. MD5
  2. SHA

對稱加密演算法:

  1. RC4
  2. TEA
  3. DES
  4. AES
  5. SM4
  6. ChaCha20

0X01. MD5

MD5(Message Digest Algorithm)訊息摘要演算法對輸入的任意長度的訊息進行運算,產生一個128位的訊息摘要,
MD5的特征是會出現下圖中 A,B,C,D 這四個常量,

這里我們直接用《加密與解密(第4版)》隨書檔案MD5KeyGenMe.exe來分析,

在匯入表中找到GetDlgItemTextA函式定位關鍵代碼,兩次GetDlgItemTextA函式讀取的應該分別是Name和Serial Number:

sub_4012B0函式我們點進去看看發現了MD5的幾個特征常量:

還原一下符號,需要注意的一點是連續呼叫兩次MD5_Update相當于把兩次的輸入拼接后呼叫一次MD5_Update的結果:

寫出注冊機:

from hashlib import md5
 
name = b'pediy'
digest = md5(name + b'www.pediy.com').digest()
a2345 = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'
serial_number = ''
for b in digest:
    serial_number += a2345[b % 32]
print(f'Serial Number('{name}')={serial_number[0:4]}-{serial_number[4:8]}-{serial_number[8:12]}-{serial_number[12:16]}')

Findcrypt插件能幫助我們快速找到這些常量,不過這里還是著重講手動分析的方法,

0x02. SHA

安全散列演算法(Secure Hash Algorithm,SHA)包括SHA-1、SHA-256、SHA-384和SHA-512,分別產生160位、256位、384位和512位的散列值,
類似于MD5,SHA演算法使用了一系列的常數:

還是用隨書檔案SHA1KeyGenMe.exe來分析,
還是先通過匯入表定位關鍵代碼:

發現sub_401000函式中出現了SHA1演算法用到的常量:

還原下符號:

寫出注冊機:

from hashlib import sha1
 
name = b'pediy'
digest = sha1(name).digest()
aPEDIY = b'PEDIY Forum'
apediy = b'pediy.com'
key = bytearray(digest)
for i in range(11):
    key[i] ^= aPEDIY[i]
for i in range(12,17):
    key[i] ^= key[i - 12]
for i in range(17,20):
    key[i] ^= apediy[i - 17]
serial_number = ''
for i in range(10):
    serial_number += hex(key[i] ^ key[i + 10])[2:].zfill(2).upper()
print(serial_number)

0x03. RC4

RC4是一種比較簡單的流密碼,該演算法雖然沒有用到特征常量,但是特征也比較容易識別,

分析RC4 Sample.exe檔案,
還是通過匯入表找到關鍵代碼:

sub_401000函式明顯具有RC4密鑰調度演算法(KSA)的特征:

sub_401070函式是RC4演算法的第二步:

0x04. TEA

TEA演算法是分組密碼,分組長度為64位,密鑰長度為128位,采用Feistel網路,
其加密程序也非常簡單,下面的代碼摘自Wikipedia:

#include <stdint.h>
 
void encrypt (uint32_t v[2], const uint32_t k[4]) {
    uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */
    uint32_t delta=0x9E3779B9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<32; i++) {                         /* basic cycle start */
        sum += delta;
        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}

其中特征常量delta是由黃金分割點得來的,delta = 0x9E377989,TEA的變體XTEA和XXTEA都用到了這個常量,但是加密程序不同,在識別演算法時需要注意,
在加密輪數方面,作者推薦的加密輪數是64輪,即回圈32次,也可以采用其他加密輪數,比如32輪或者128輪,在分析的時候也需要注意,
補充Wikipedia上的一些資料:

  • Tiny Encryption Algorithm
  • XTEA
  • XXTEA

分析TEAKeyGenMe.exe

sub_401380函式中出現了MD5特征常量:

sub_401000函式中出現了TEA特征常量,明顯為TEA演算法:

整個加密程序是先取MD5(name)的前8個位元組作為密鑰對序列號進行TEA加密,加密的結果再與與MD5(name)的前8個位元組異或,異或的結果與MD5的后8個位元組比較,
寫出注冊機:

from hashlib import md5
from binascii import b2a_hex
from pytea import TEA
 
name = b'pediy'
md5_digest = md5(name).digest()
buf = bytearray(md5_digest[0:8])
for i in range(8):
    buf[i] ^= md5_digest[i + 8]
tea = TEA(md5_digest)
print(f'Serial Number("{name.decode()}"): {b2a_hex(tea.Decrypt(buf)).decode().upper()}')

我在網上找了半天也沒找到個好用的TEA的Python實作,干脆自己寫了個:已上傳GitHub

0x05. DES

DES全稱為Data Encryption Standard,即資料加密標準,是一種使用密鑰加密的分組演算法,
DES同前面的TEA一樣,都采用了Feistel網路,其加密程序可以用以下兩個圖表示:
Figure 1— The overall Feistel structure of DES

Figure 2—The Feistel function (F-function) of DES

圖一中的IPFP分別代表初始置換(Initial Permutation)和末尾置換(Final Permutation),圖二中的S1S8是8個置換盒(Substitution-Box),這些都可以作為識別DES演算法的特征,
隨便在GitHub上扒一份原始碼,就能找到這些常量:

int S1[] = {14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
             0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
             4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
            15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13};
 
int S2[] = {15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
             3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
             0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
            13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9};
 
int S3[] = {10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
            13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
            13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
             1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12};
 
int S4[] = { 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
            13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
            10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
             3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14};
 
int S5[] = { 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
            14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
             4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
            11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3};
 
int S6[] = {12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
            10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
             9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
             4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13};
 
int S7[] = { 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
            13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
             1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
             6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12};
 
int S8[] = {13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
             1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
             7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
             2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11};

在2020祥云杯的某道APK逆向里,Findcrypt插件失效(可能是Findcrypt分析不了ARM框架下的檔案),所以我們只能靠手動分析找到DES的特征(以下是S1到S8):

還有一些別的特征,都可以幫助我們快速識別DES演算法:

0x06. AES

AES(Advanced Encryption Standard,高級加密標準)是用于代替DES的新一代加密標準,AES具有128位元的分組長度,支持128位元、192位元和256位元的密鑰長度,
AES的加密程序:

SubBytes函式:

我們識別AES的方法就是找到AES的SubBytes函式中使用的這個S-box,
在GitHub上扒一份原始碼:

/*
 * S-box transformation table
 */
static uint8_t s_box[256] = {
    // 0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f
    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, // 0
    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, // 1
    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, // 2
    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, // 3
    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, // 4
    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, // 5
    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, // 6
    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, // 7
    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, // 8
    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, // 9
    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, // a
    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, // b
    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, // c
    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, // d
    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, // e
    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};// f
 
/*
 * Inverse S-box transformation table
 */
static uint8_t inv_s_box[256] = {
    // 0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f
    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, // 0
    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, // 1
    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, // 2
    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, // 3
    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, // 4
    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, // 5
    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, // 6
    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, // 7
    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, // 8
    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, // 9
    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, // a
    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, // b
    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, // c
    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, // d
    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, // e
    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};// f

下面分析AESKeyGenMe.exe檔案,
初步分析關鍵代碼:

在sub_401EC0函式中找到AES的S_box和S_box的逆,基本確定是AES加密,沒有找到iv,推測是ECB模式:

密鑰:

寫出注冊機:

from hashlib import md5
from Crypto.Cipher import AES
from binascii import b2a_hex
 
name = b'pediy'
md5_digest = md5(name).digest()
aes = AES.new(key=b'\x2B\x7E\x15\x16\x28\xAE\xD2\xA6\xAB\xF7\x15\x88\x09\xCF\x4F\x3C',mode=AES.MODE_ECB)
dec = aes.decrypt(md5_digest)
print(f'Serial Number("{name.decode()}")={b2a_hex(dec).decode().upper()}')

0x07. SM4

SM4是國密演算法,由國家密碼局發布,SM4是一個分組演算法,分組長度為128位元,密鑰長度為128位元,其結構是Fesitel網路的一個變體,
我們識別SM4演算法的方法同樣是找到SM4的S-box(在GitHub上找的原始碼):

static const unsigned char SboxTable[16][16] =
{
    {0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05},
    {0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99},
    {0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62},
    {0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6},
    {0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8},
    {0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35},
    {0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87},
    {0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e},
    {0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1},
    {0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3},
    {0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f},
    {0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51},
    {0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8},
    {0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0},
    {0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84},
    {0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48}
};

拿2020縱橫杯的第一道逆向題friendlyRE舉例,
我們直接找到關鍵代碼,這里是比較了Str1和Str2,通過交叉參考可以確定Str2加密程序,Str2為"2NI5JKCBI5Hyva+8AZa3mq!!":

再去找Str1的加密程序,發現有個地方用到了Base64表:

并且表是變換過的,第一次是大小寫互換,第二次相當于是把表的前32位和后32位互換:

繼續找找到了SM4的S-box:

找到key:

整個程序大概就是把輸入經過SM4加密之后再經過一個變表的BASE64再與"2NI5JKCBI5Hyva+8AZa3mq!!"比較,寫出exp:

import base64
from binascii import b2a_hex, a2b_hex
from gmssl.sm4 import CryptSM4, SM4_DECRYPT
 
BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
BASE64_change = (BASE64[32:] + BASE64[:32]).swapcase()
table = str.maketrans(BASE64_change,BASE64)
Str2 = 'N25IKJBC5IyHav8+ZA3aqm!!'
target = ''
for i in range(0,len(Str2),2):
    target += Str2[i + 1]
    target += Str2[i]
target = target.translate(table).replace('!','=')
base64_decode = base64.b64decode(target)
print(b2a_hex(base64_decode))
crypt_sm4 = CryptSM4()
crypt_sm4.set_key(b'Thisisinsteresth',SM4_DECRYPT)
flag = crypt_sm4.crypt_ecb(base64_decode)
print(b2a_hex(flag))

理論上是可以這么寫,但是gmssl庫的SM4的padding方式跟題目里SM4的padding方式不一致,導致無法解密,
所以換工具解密:

Hex2Str,得到最后的flag為:DoyouKnowVEHSEH!

0x08. ChaCha20

ChaCha系列流密碼,作為Salsa密碼的改良版,具有更強的抵抗密碼分析攻擊的特性,“20”表示該演算法有20輪的加密計算,
ChaCha20有一個初始矩陣,矩陣的輸入為一個256位的密鑰、64位亂數、64位計數器值以及4×32位的常數,它們均填充在32位整型陣列中作為初始矩陣,排列方式如下:

四個常數0x61707865 0x3320646e 0x79622d32 0x6b206574按小端存盤轉為ASCII字符是"expand 32-byte k",這是我們用來識別ChaCha20演算法的主要特征,
分析今年年初*CTF的一道題Favourite Architecure flag0,riscv架構的檔案只能用Ghirda分析,由于未知原因main函式的反匯編失效了,只能手擼匯編,

我們直接從列印錯誤的代碼開始分析,有兩個大跳轉跳到了這里,往回看能找到能找到兩個地方呼叫的是同一個函式,估計是對加密結果進行比較:

從第一次比較分析,先把用來比較的資料dump下來:

enc1 = b'\x88\xE7\x03\xB4\x36\xCD\x97\xAB\x5A\xA5\xA6\x0B\xDF\xCE\x08\x3B\x9D\x90\x32\x3C\x4E\x15\x14\xBD\x8D\x38\x38\xB0\xEE\x2A\xBC\x4B\xF9\xAA\x24\x26\x76\xA3\xA5\x75\x5E'

從比較函式往前找,找到了這個很詭異的地方:

圖片描述

百度搜索關鍵詞expand 32-byte k找到了GitHub上的一處代碼:

圖片描述

一比對發現是幾乎一模一樣(實際上并不一樣),鎖定第一個加密演算法是ChaCha20:

圖片描述

順藤摸瓜找到密鑰:

圖片描述

然而用了各種Python庫和在線網站都解密不了,一度懷疑人生...
后來分析發現了題目里用到的ChaCha20演算法貌似跟正常的ChaCha20演算法不太一樣,一般來說ChaCha20演算法輸入的Nonce(亂數)是8位元組,題目中的ChaCha20演算法卻給了12個位元組的Nonce,于是改變思路去GitHub上翻了幾個ChaCha20的C語言實作,找到了題目用到的原始碼:

圖片描述

圖片描述

圖片描述

圖片描述

比對下來發現是完全一樣,依葫蘆畫瓢寫出exp的第一部分:

#include "chacha20.h"
#include <stdio.h>
#include <stdlib.h>
 
int main(){
    char enc[100] = "\x88\xE7\x03\xB4\x36\xCD\x97\xAB\x5A\xA5\xA6\x0B\xDF\xCE\x08\x3B\x9D\x90\x32\x3C\x4E\x15\x14\xBD\x8D\x38\x38\xB0\xEE\x2A\xBC\x4B\xF9\xAA\x24\x26\x76\xA3\xA5\x75\x5E";
    char key[100] = "tzgkwukglbslrmfjsrwimtwyyrkejqzo";
    char nonce[100] = "oaeqjfhclrqk";
    struct chacha20_context *ctx = (struct chacha20_context*)malloc(sizeof(struct chacha20_context));
    chacha20_init_context(ctx,(uint8_t*)key,(uint8_t*)nonce,0x80);
    chacha20_xor(ctx,(uint8_t*)enc,41);
    printf(enc);
}

flag{have_you_tried_ghidra9.2_decompiler_

其實更好的方法是直接動態除錯dump密鑰流異或,無奈riscv的動態除錯環境沒搭起來,
然而這種ChaCha20實作到底是變體還是翻車就不知道了...
第二部分則是一個很明顯的TEA:

寫出第二部分的exp:

from pytea import TEA
 
key = b'\xBB\xA0\x68\x13\x1E\xCE\x0A\x19\x57\xA3\xD8\x35\x61\x2C\xBF\x26'
enc = b'\xF9\x87\x50\xC4\xB2\xF2\x03\x07\x3C\xF4\x74\x69\x59\xBB\xB4\xED\x2A\xB0\xF0\x0F\xF2\x20\x85\x00\xDD\x23\xCD\xFD\x75\x48\x02\x35\xD3\xB6\xD7\xF1\xE1\x1B\xF2\x74\x12\xBF\x2D\xCB\xF6\x53\xB4\xA4'
cipher = TEA(key)
print(cipher.Decrypt(enc,16).decode())

if_you_have_hexriscv_plz_share_it_with_me_thx:P}

完整的flag:

flag{have_you_tried_ghidra9.2_decompiler_if_you_have_hexriscv_plz_share_it_with_me_thx:P}

0x09. 總結

最后再總結一下識別單向散列演算法和對稱加密演算法的方法:

  1. 直接用IDA的插件Findcrpyt
  2. RC4、TEA這些流程比較簡單的演算法可以直接通過加密程序識別
  3. 一些用到了常量的演算法,可以通過它的特征常量識別,比如TEA的delta、ChaCha20的sigma、DES和AES以及SM4的S-Box等等
  4. 善用GitHub,作為老程式員,這種復雜的加密演算法一般都是在GitHub上抄的(至少我不會自己寫hh)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298292.html

標籤:AI

上一篇:Python大一學習感想

下一篇:TensorFlow 洗掉 YAML 支持,建議 JSON 作為替補方案!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more