2021年强网杯 逆向部分WP

本文探讨了一道涉及调和级数缩放的数学问题,并揭示了隐藏在代码中的字符串操作、RSA加密和Base64换表谜题,展示了从逆向工程到密码学的步步解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今年的逆向很🐶

ezmath

一道数学题,关键在于函数式的缩放化简。

第15行的公式是整个程序的关键

f(n) = e - nf(n)

是一个调和级数的缩放题目

最后当n较大时易知:n = e / f(n)

脚本:

#include<stdio.h>

#include<math.h>

double dbl_4020[19] =

{

   0.00009794904266317233,

   0.00010270456917442,

   0.00009194256152777895,

   0.0001090322021913372,

   0.0001112636336217534,

   0.0001007442677411854,

   0.0001112636336217534,

   0.0001047063607908828,

   0.0001112818534005219,

   0.0001046861985862495,

   0.0001112818534005219,

   0.000108992856167966,

   0.0001112636336217534,

   0.0001090234561758122,

   0.0001113183108652088,

   0.0001006882924839248,

   0.0001112590796092291,

   0.0001089841164633298,

   0.00008468431512187874

};





int main()

{

double e = 2.718281828459045;

int n;



for (int i = 0; i < 20; i++)

{

n = (int)(e / dbl_4020[i]);

double tmp1 = n * i;

double watch = tmp1 - e;

double tmp2 = (n - 1) * i;

double watch2 = tmp2 - e;

if (fabs(watch) >= fabs(watch2))

n -= 1;

printf("%s", &n);

}

return 0;

}

 

得到flag

 

 

StandOnGiants

Ida打开源文件查看,发现有.so字样,改后缀为zip

提出libnative.so进行分析

 

分析主要的检查函数

逆序字符串+rsa+换表base64

其中base64表有多个+ -, 所以需要爆破

 

 

 

代码如下

from base64 import *

from Crypto.Util.number import *



n = 0x1321D2FDDDE8BD9DFF379AFF030DE205B846EB5CECC40FA8AA9C2A85CE3E992193E873B2BC667DABE2AC3EE9DD23B3A9ED9EC0C3C7445663F5455469B727DD6FBC03B1BF95D03A13C0368645767630C7EABF5E7AB5FA27B94ADE7E1E23BCC65D2A7DED1C5B364B51

p = 33372027594978156556226010605355114227940760344767554666784520987023841729210037080257448673296881877565718986258036932062711

q = 64135289477071580278790190170577389084825014742943447208116859632024532344630238623598752668347708737661925585694639798853367

e = 65537



def replace(r, k, Csource, T1, T2):

    Count = 0

    r = "0"*(k.count(Csource)-r.bit_length())+bin(r)[2:]

    list4k = list(k)

    for i in range(len(list4k)):

        if list4k[i] == Csource:

            if r[Count] == '1':

                list4k[i] = T1

            else:

                list4k[i] = T2

            Count += 1

    return ''.join(list4k)



a ="bborOT+ohG*,U:;@/gVIAZ-,t++LaZkOrk?UcSOKJ?p-J+vuSN?:e,Kc/?h-oH?:tthoqYYSPp-ZC+Yw:*jrxPymGYO/PvDOIivNYtvJ?Mi*GG+/lmqEysrTdSD+eP+moP+l?+Np/oK="

#10个加号和4个减号  总共2^14种可能

table1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*+,-./:;?@+-"

table2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

def change(a):

    tmp = ""

    for i in range(len(a)):

        if a[i]=="-" or a[i]=="+":

            tmp += a[i]

            continue

        for j in range(len(table1)):

            if a[i] == table1[j]:

                tmp += table2[j]

                break

    return tmp



def db64(s):

    try:

        return bytes_to_long(b64decode(s.encode()))

    except:

        try:

            return bytes_to_long(b64decode((s+"=").encode()))

        except:

            print("wrong!")

            return 0



f = open("data", "w")

ans = ''

for i in range(2**10):

    for j in range(2**4):

        if i%50 == 0 and j == 0:

            print(i/(2**10)*100)

        b64ans = change(a)

        b64ans = replace(i, b64ans, '+', '+', '1')

        b64ans = replace(j, b64ans, '-', '3', '/')

        c = db64(b64ans)

        if c == 0:

            continue;

        m = pow(c, inverse(e, (p-1)*(q-1)), n)

        flag = long_to_bytes(m)

        if flag[0] < 'f':

            f.writelines(str(flag))

f.close()

 

 

得到flag

 

LongTimeAgo

前面做了一个操作,将64位字符,转换成了32个字节。

每四个字节倒序,然后经过四个函数生成了四个key。

继续调试,发现了xtea加密算法的痕迹,但是魔数和sum被改了,然后发现前4个4字节经过xtea加密,后4个4字节经过tea加密,最后密文也被修改了。

直接dump或者计算

 

脚本如下

def TEAdecode(c, key):

    tmp_0 = c[0]

    tmp_1 = c[1]

    sum = 0xa6a53780

    delta = 0x3d3529bc

    for i in range(32):

        tmp_1 -= ((tmp_0<<4) + key[2]) ^ (tmp_0 + sum) ^ ((tmp_0>>5) + key[3])

        tmp_1 &= 0xffffffff

        tmp_0 -= ((tmp_1<<4) + key[0]) ^ (tmp_1 + sum) ^ ((tmp_1>>5) + key[1])

        tmp_0 &= 0xffffffff

        sum -= delta

    return (tmp_0, tmp_1)



def XTEAdecode(circle, c, key):

    tmp_0 = c[0]

    tmp_1 = c[1]

    delta = 0x70C88617

    sum = 0xE6EF3D20

    for i in range(circle):    

        tmp_1 -= (((tmp_0 << 4) ^ (tmp_0 >> 5)) + tmp_0) ^ (sum + key[(sum>>11) & 3])

        tmp_1 &= 0xffffffff        

        sum += delta;  

        tmp_0 -= (((tmp_1 << 4) ^ (tmp_1 >> 5)) + tmp_1) ^ (sum + key[sum & 3])

        tmp_0 &= 0xffffffff

    return (tmp_0, tmp_1)







c = [0x1F306772, 0xB75B0C29, 0x4A7CDBE3, 0x2877BDDF, 0x1354C485, 0x357C3C3A, 0x738AF06C, 0x89B7F537]

key = [0xfffd,0x1fffd,0x3fffd,0x7fffd]







for i in range(0, 4, 2):

    c[i] ^= 0xfd

    c[i+1] ^= 0x1fd

for i in range(4, 8, 2):

    c[i] ^= 0x3fd

    c[i+1] ^= 0x7fd





flag = ''  

for i in range(0, 4, 2):

    ans = XTEAdecode(32, c[i:], key)

    flag += hex(ans[0])[2:] + hex(ans[1])[2:]

for i in range(4, 8, 2):

    ans = TEAdecode(c[i:], key)

    flag += hex(ans[0])[2:] + hex(ans[1])[2:]

print("QWB{"+flag.upper()+"}")

得到flag

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值