欢乐时光
无壳,64位elf文件,拖入ida,看主函数

用ida的findcrypt插件,发现是tea加密,
特征值找到,delta=1640531527
v5是4个32位组合,而TEA加密的key就是128位,所以v5就是key
那么密文就是main中的v6,需要将他们重新组合
分析一下找到的cry函数,进一步确认是xxtea加密。
与标准XXTEA比对,查看是否有魔改
#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
void btea(uint32_t *v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52/n;
sum = 0;
z = v[n-1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++)
{
y = v[p+1];
z = v[p] += MX;
}
y = v[0];
z = v[n-1] += MX;
}
while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52/n;
sum = rounds*DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
}
int main()
{
uint32_t v[2]= {1,2};
uint32_t const k[4]= {2,2,3,4};
int n= 2; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("加密前原始数据:%u %u\n",v[0],v[1]);
btea(v, n, k);
printf("加密后的数据:%u %u\n",v[0],v[1]);
btea(v, -n, k);
printf("解密后的数据:%u %u\n",v[0],v[1]);
return 0;
}
发现就是标准的XXTEA加密,对脚本进行修改,就可以获得本题脚本

再加一个十六进制转换字符串就好了

#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
void btea(uint32_t *v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 1444 + 415/n;
sum = 0;
z = v[n-1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++)
{
y = v[p+1];
z = v[p] += MX;
}
y = v[0];
z = v[n-1] += MX;
}
while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 114 + 415/n;
sum = rounds*DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
}
int main()
{
unsigned int v[11] = {0x480AC20C, 0xCE9037F2, 0x8C212018, 0xE92A18D, 0xA4035274, 0x2473AAB1, 0xA9EFDB58, 0xA52CC5C8, 0xE432CB51, 0xD04E9223, 0x6FD07093};
unsigned int k[4] = {0x79696755, 0x67346F6C, 0x69231231, 0x5F674231};
int n= 11; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("加密前原始数据:%u %u\n",v[0],v[1]);
btea(v, -n, k);
printf("解密后的数据:%u %u\n",v[0],v[1]);
char *p = (char *)v;
for (int i = 0; i < 44; i++)
{
printf("%c", *p);
p++;
}
return 0;
}//
rc4
查壳,32位无壳,运行一下,发现无法运行,拖入ida

跟进一下主要就是mian和main0函数,0x100就是256,结合题目,很明显这是一个RC4加密,
从str到a1,在结合循环填充,所以gamelab@就是key,v5就是密文
非常标准的RC4加密,甚至没有任何异或
用标准的解密脚本
def rc4_init(s_box, key, key_len): # rc4初始化函数,产生s_box
k = [0] * 256
i = j = 0
for i in range(256):
s_box[i] = i
k[i] = key[i % key_len]
for i in range(256):
j = (j + s_box[i] + ord(k[i])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
def rc4_crypt(s_box, data, data_len, key, key_len): # rc4算法,由于异或运算的对合性,RC4加密解密使用同一套算法,加解密都是它
rc4_init(s_box, key, key_len)
i = j = 0
for k in range(data_len):
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
data[k] ^= s_box[t]
if __name__ == '__main__':
s_box = [0] * 257 # 定义存放s_box数据的列表
# 此处的data即要解密的密文,需要定义成列表形式,其中的元素可以是十六进制或十进制数
# 如果题目给出的是字符串,需要你自己先把数据处理成列表形式再套用脚本
data = [235, 13, 97, 41, 191, 155, 5, 34, 243, 50, 40, 151, 227, 134,
77, 45, 90, 42, 163, 85, 170, 213, 180, 108, 139, 81, 177]
#key一定要字符串
key = "wanyuanshenwande"
rc4_crypt(s_box, data, len(data), key, len(key))
for i in data:
print(chr(i), end='')

揭秘脚本好像有点问题,用ai重写一下
def rc4_init(s_box, key, key_len): # RC4初始化函数,产生s_box
k = [0] * 256
i = j = 0
for i in range(256):
s_box[i] = i
k[i] = ord(key[i % key_len]) # 确保从字符串中提取字符的ASCII值
for i in range(256):
j = (j + s_box[i] + k[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
def rc4_crypt(s_box, data, data_len, key, key_len): # RC4算法
rc4_init(s_box, key, key_len)
i = j = 0
for k in range(data_len):
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
data[k] ^= s_box[t] # 异或操作
if __name__ == '__main__':
s_box = [0] * 256 # 定义存放s_box数据的列表
# 定义要解密的密文
v5 = [
-74, 66, -73, -4, -16, -94, 94, -87, 61, 41, 54, 31, 84, 41, 114, -88,
99, 50, -14, 68, -117, -123, -20, 13, -83, 63, -109, -93, -110, 116,
-127, 101, 105, -20, -28, 57, -123, -87, -54, -81, -78, -58
]
# 将负数转换为无符号字节
v5 = [(x + 256) % 256 for x in v5]
# 定义密钥
key = "gamelab@"
# 执行RC4解密
rc4_crypt(s_box, v5, len(v5), key, len(key))
# 输出解密结果
for i in v5:
print(chr(i), end='')
cc

打开对应的界面
-
加密算法:AES(高级加密标准)
-
密钥(Key):
gamelab@gamelab@ -
初始向量(IV):
gamelab@gamelab@ -
模式(Mode):CBC(密码块链接模式)
-
输入(Input):Raw(原始数据)
-
输出(Output):Hex(十六进制格式)
基本上什么都有了,找个在线工具就行了

Theorem

打开py文件,加密方式和数据都有了,直接喂给chatgpt

from Crypto.Util.number import long_to_bytes
from gmpy2 import *
n = 94581028682900113123648734937784634645486813867065294159875516514520556881461611966096883566806571691879115766917833117123695776131443081658364855087575006641022211136751071900710589699171982563753011439999297865781908255529833932820965169382130385236359802696280004495552191520878864368741633686036192501791
d1 = 4218387668018915625720266396593862419917073471510522718205354605765842130260156168132376152403329034145938741283222306099114824746204800218811277063324566
d2 = 9600627113582853774131075212313403348273644858279673841760714353580493485117716382652419880115319186763984899736188607228846934836782353387850747253170850
c = 36423517465893675519815622861961872192784685202298519340922692662559402449554596309518386263035128551037586034375613936036935256444185038640625700728791201299960866688949056632874866621825012134973285965672502404517179243752689740766636653543223559495428281042737266438408338914031484466542505299050233075829
# 计算 p 和 q
p = prev_prime(isqrt(n))
q = next_prime(p)
# 计算 φ(n)
phi = (p - 1) * (q - 1)
# 通过中国剩余定理恢复 d
from gmpy2 import invert
def custom_crt(a1, m1, a2, m2):
""" 计算 d 使得:
d ≡ a1 (mod m1)
d ≡ a2 (mod m2)
"""
M1 = invert(m1, m2) * m1
M2 = invert(m2, m1) * m2
return (a1 * M2 + a2 * M1) % (m1 * m2)
d = custom_crt(d1, q, d2, p)
# 解密得到明文
m = pow(c, d, n)
# 转换为字符串
flag = long_to_bytes(m)
print(flag.decode())
Signature
同理,打开文件,喂给chatgpt

解密脚本
from sympy import mod_inverse
# 椭圆曲线的阶
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
# 已知数据
r1 = 4690192503304946823926998585663150874421527890534303129755098666293734606680
s1 = 111157363347893999914897601390136910031659525525419989250638426589503279490788
s2 = 74486305819584508240056247318325239805160339288252987178597122489325719901254
# 计算哈希值(假设 SHA256 计算的哈希值)
h1 = int.from_bytes(b'Hi.', 'big')
h2 = int.from_bytes(b'hello.', 'big')
# 计算 k
s_diff = (s1 - s2) % n
h_diff = (h1 - h2) % n
k = (h_diff * mod_inverse(s_diff, n)) % n
# 计算私钥 dA
dA = ((s1 * k - h1) * mod_inverse(r1, n)) % n
print(f"Recovered k: {k}")
print(f"Recovered dA: {dA}")
23万+

被折叠的 条评论
为什么被折叠?



