今年的逆向很🐶
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