呜呜呜,自闭了,SM4的侧信道攻击肝了2天,啃了几篇论文,敲了几百行代码,算出来还是错的,没打过OI,优化算法太痛苦了
ps:经过HWS群里的@JZAX大佬指点,终于复现了SM4的侧信道攻击

趁大佬们都去打强网杯了,偷偷拿个第一

硬件(Crypto侧信道)

Read&Solve

RSA侧信道,根据CTFWiki的图,直接对着波形提取二进制转hex提交

足够安全

AES侧信道,github上可以搜到一个项目(https://github.com/wlmnzf/CPA)
自己改改脚本把json的数据扔进去即可

MISC

最伟大的作品

听一下可以听出来是由不同音调组成,找个在线网站翻译下(https://bideyuanli.com/pp)
把数字前对应的字母连起来提交即可

random

random的size固定,然后按照顺序生成加密时的伪随机数,flag所在位置替换为从\x00到\x27,就可以获得打乱后flag每个字符的顺序,恢复即可

# from flag import FLAG
import random
from PIL import Image
from hashlib import md5
from Crypto.Util.number import long_to_bytes as n2b

random.seed(793211)

def pbl(bits):
    num = random.getrandbits(bits)
    bins = []
    while num:
        bins.append(num & 1)
        num >>= 1
    while len(bins) != bits:
        bins.append(0)
    return bins

cat = Image.open('1.png')
catx = Image.open('xx.png')

x, y = cat.size
bits = x * y
r1, r2 = pbl(bits), pbl(bits)
fake_flag=b''
for i in range(28):
    fake_flag+=n2b(i)
r3 = fake_flag+n2b(random.getrandbits((bits - 28) * 8))
r3 = list(r3)
random.shuffle(r3)

flag=[0 for _ in range(28)]

i=0
j=0

for i in range(x):
    for j in range(y):
        pix = cat.getpixel((i, j))
        pixx = catx.getpixel((i, j))
        if r3[i * y + j]!=(pix[2] ^ pixx[2]):
            flag[r3[i * y + j]]=pix[2] ^ pixx[2]

for i in flag:
    print(chr(i),end='')

What's this

先用uncompyle6反编译出py文件,查看py文件可知,其每次会在程序最后执行一个新的程序。把源代码改一下,把每次要执行的代码给输出到另一个文件里,套了几层娃,最后输出的文件里面有flag明文

CRYPTO

HWS-easyRSA

LCG,找个脚本解一下就行

from gmpy2 import gcd
from Crypto.Util.number import *

n = 31893593182018727625473530765941216190921866039118147474754069955393226712079257707838327486268599271803
output =  [25820280412859586557218124484272275594433027771091486422152141535682739897353623931875432576083022273940,24295465524789348024814588142969609603624462580932512051939198335014954252359986260009296537423802567677,14963686422550871447791815183480974143372785034397446416396172429864269108509521776424254168481536292904]

MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1] #逆元计算
a=(output[2]-output[1])*MMI((output[1]-output[0]),n)%n
ani=MMI(a,n)
b=(output[1]-a*output[0])%n
seed = (ani*(output[0]-b))%n
plaintext=seed
print(long_to_bytes(plaintext))

RE

re1

很明显的XXTEA加密,把密文密钥提出来,解密一下

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#define DELTA 0x9e3779b9
#define MX                                     \
    (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ \
     ((sum ^ y) + (key[(p & 3) ^ e] ^ z)))

uint32_t cipher[] = {
    0x10BD3B47, 0x6155E0F9, 0x6AF7EBC5, 0x8D23435F, 0x1A091605, 0x0D43D40EF, 0x0B4B16A67, 0x6B3578A9 ,0x0
};

uint32_t *xxtea_uint_decrypt(uint32_t *data, size_t len, uint32_t *key)
{
    uint32_t n =
        (uint32_t)len - 1;
    uint32_t z, y = data[0], p, q = 6 + 52 / (n + 1), sum = q * DELTA, e;
    if (n < 1)
        return data;

    while (sum != 0)
    {
        e = sum >> 2 & 3;
        for (p = n; p > 0; p--)
        {
            z = data[p - 1];
            y = data[p] -= MX;
        }
        z = data[n];
        y = data[0] -= MX;
        sum -= DELTA;
    }
    return data;
}
int main()
{
    uint32_t key[] = {0x1234, 0x2345, 0x4567, 0x6789};
    xxtea_uint_decrypt(cipher, 8, key);
    printf("%s", &cipher);
}

re2

可以看到有个TLSCallback函数,异或了一块数据块后将其作为代码执行,把debug_break给patch掉,然后动调可以发现是RC4加密,加密前异或了0x48
找个在线网站解密一下


一个梦想成为原画师的卑微ctfer罢了