第二
re(527)
so_easy(252)
主要函数
__int64 __fastcall Java_com_so_easy_MainActivity_soEasy(__int64 a1, __int64 a2, __int64 a3)
{
unsigned int v5; // r13d
const char *v6; // rax
const char *v7; // r12
size_t v8; // rax
size_t v9; // r8
__int64 v10; // rsi
int v11; // edx
__int64 v12; // rdi
__int64 v13; // rsi
__int64 v14; // rdi
__int64 v15; // rcx
size_t v16; // rax
size_t v17; // rcx
unsigned __int8 v18; // di
__int128 v20[6]; // [rsp+0h] [rbp-98h] BYREF
int v21; // [rsp+60h] [rbp-38h]
unsigned __int64 v22; // [rsp+68h] [rbp-30h]
v22 = __readfsqword(0x28u);
v5 = 0;
v6 = (const char *)(*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 1352LL))(a1, a3, 0LL);
v7 = v6;
memset(v20, 0, sizeof(v20));
v21 = 0;
if ( *v6 )
{
v8 = strlen(v6);
v9 = 0LL;
do
{
v10 = *(_QWORD *)&v7[v9];
v11 = 255;
do
{
v12 = (2 * v10) ^ 0x71234EA7D92996F5LL; // 对输入字符串的每个8字节块进行多次位运算:
if ( v10 >= 0 )
v12 = 2 * v10;
v13 = (2 * v12) ^ 0x71234EA7D92996F5LL;
if ( v12 >= 0 )
v13 = 2 * v12;
v14 = (2 * v13) ^ 0x71234EA7D92996F5LL;
if ( v13 >= 0 )
v14 = 2 * v13;
v15 = (2 * v14) ^ 0x71234EA7D92996F5LL;
if ( v14 >= 0 )
v15 = 2 * v14;
v10 = (2 * v15) ^ 0x71234EA7D92996F5LL;
if ( v15 >= 0 )
v10 = 2 * v15;
v11 -= 5;
}
while ( v11 );
*(_QWORD *)((char *)v20 + v9) = v10;
v9 += 8LL;
}
while ( v8 > v9 );
}
if ( *v7 )
{
v16 = strlen(v7);
v17 = 0LL;
LOBYTE(v5) = 0;
do
{
v18 = v5 + (*(_WORD *)((char *)v20 + v17) == *(_WORD *)((char *)&unk_560 + v17));
v17 += 2LL;
v5 = v18;
}
while ( v16 > v17 );
}
(*(void (__fastcall **)(__int64, __int64, const char *))(*(_QWORD *)a1 + 1360LL))(a1, a3, v7);
return v5;
}
多次位分析最后和unk_560比较
unk_560[] =
{
0xAE, 0x81, 0xBA, 0xC1, 0xF0, 0x95, 0x0A, 0x54, 0x14, 0x03,
0x4A, 0xE2, 0x52, 0x4E, 0x84, 0xF8, 0xC9, 0x3E, 0x14, 0x98,
0x8F, 0x98, 0xFD, 0x09, 0x5E, 0xAD, 0x05, 0xB4, 0x01, 0x0F,
0xC0, 0x3F
};
exp
# 倒序板子
def main():
arr = "AE81BAC1F0950A5414" # 定义字符串
length = len(arr) # 获取字符串长度
# 使用for循环反向打印字符串的前半部分
for i in range(length // 2):
print(arr[length - 2 * i - 2], end='') # 打印字符,并使用空字符串''作为分隔符
print(arr[length - 2 * i - 1], end='')
print() # 打印换行符
# 调用主函数
if __name__ == "__main__":
main()
# CRC32板子
secret = [0x540A95F0C1BA81AE,0xF8844E52E24A0314,0x9FD988F98143EC9,0x3FC00F01B405AD5E]
key = 0x71234EA7D92996F5
flag = ""
for s in secret:
for i in range(255):
sign = s & 1
if sign == 1:
s ^= key
s //= 2
# 防止负值除2,溢出为正值
if sign == 1:
s |= 0x8000000000000000
j = 0
while j < 8:
flag += chr(s & 0xFF)
s >>= 8
j += 1
print(flag)
quite_easy(275)
目测是一个TLS
花指令去掉了
如下
.text: nop
.text:00407C83 nop
.text:00407C84 nop
.text:00407C85 nop
.text:00407C86 nop
.text:00407C87 nop
.text:00407C88 nop
.text:00407C89 nop
.text:00407C8A nop
.text:00407C8B nop
.text:00407C8C nop
.text:00407C8D nop
.text:00407C8E nop
.text:00407C8F nop
.text:00407C90 nop
基于rand的一个简单加密
int __cdecl sub_40A5A0(char *Str, int a2)
{
int v2; // eax
char v3; // al
char v4; // si
char v5; // si
char v6; // di
_BYTE *v7; // eax
char v8; // si
char v9; // si
char v10; // di
_BYTE *v11; // eax
const char *v12; // eax
_BYTE *v14; // [esp+10h] [ebp-158h]
int v15; // [esp+18h] [ebp-150h]
int m; // [esp+E4h] [ebp-84h]
int k; // [esp+F0h] [ebp-78h]
int j; // [esp+FCh] [ebp-6Ch]
int i; // [esp+108h] [ebp-60h]
char v20[36]; // [esp+114h] [ebp-54h] BYREF
char v21[32]; // [esp+138h] [ebp-30h] BYREF
int v22; // [esp+164h] [ebp-4h]
__CheckForDebuggerJustMyCode(&unk_41A036);
sub_40111D(Str);
v22 = 1;
sub_40111D(&::Str);
v2 = sub_401663(v21);
srand(v2 + 89);
for ( i = 0; i < 16; ++i )
{
v3 = rand();
sub_4013E3(v3);
}
if ( sub_401663(v21) != 48 )
exit(99);
for ( j = 0; j < 16; ++j )
{
v4 = *sub_4010DC(j);
v5 = *sub_4010DC(j + 32) ^ v4;
v6 = *sub_4010DC(j);
v7 = sub_4010DC(j + 32);
sub_4013E3(~(*v7 & v6) & v5);
}
for ( k = 16; k < 32; ++k )
{
v8 = *sub_4010DC(k);
v9 = *sub_4010DC(k - 16) ^ v8;
v10 = *sub_4010DC(k);
v11 = sub_4010DC(k - 16);
sub_4013E3(~(*v11 & v10) & v9);
}
for ( m = 0; m < 32; ++m )
{
v14 = sub_4010DC(m);
*v14 -= *(m + a2);
}
sub_401460();
v12 = sub_4014E7(v20);
v15 = strcmp(v12, Str2);
LOBYTE(v22) = 0;
sub_401357(v20);
v22 = -1;
sub_401357(v21);
return v15;
}
考点基本就是antidebug 动静结合得到加密流程
rand得到ke后 前16个与其异或 后16个和前16个异或进行
exp
#include <stdlib.h> // For srand() and rand()
#include <stdio.h>
int main() {
int ke[33] = {0};
int temp[16];
for(int k = 0; k < 255; k++) {
srand(k + 89);
for(int i = 0; i < 16; ++i) {
ke[i] = rand() & 0xff;
}
char flag[33] = "flag{ed1d665e6516a37ab09f0b7a40}";
int data[33] = {0x80, 0xD3, 0x6F, 0xFF, 0x15, 0x03, 0x98, 0x8C, 0xB4, 0x5B,
0x96, 0xC0, 0x59, 0xAC, 0x18, 0xDF, 0x2D, 0xCE, 0x3F, 0xFB,
0xC4, 0xED, 0xD8, 0xD2, 0xA8, 0x2D, 0xF8, 0x23, 0x9F, 0x22,
0x25, 0xCE};
for(int i = 0; i < 32; i++) {
data[i] += flag[i];
}
if((data[0] ^ ke[0]) == 87) {
for(int i = 0; i < 16; i++) {
int flag1 = (data[i] ^ ke[i % 16]) & 0xff;
int flag2 = data[i+16]^flag1;
printf("%c", flag1);
printf("\n2:%c", flag2);
}
}
}
return 0;
}
然后手动整理一下 WKCTF{08898c40064d1fc4836db94fe}
ai
how_to_encrypt
import torch
import torch.nn as nn
# 读取 ciphertext.txt 中的内容并转换为张量
def read_ciphertext(file_path):
with open(file_path, 'r') as f:
lines = f.readlines()
data = []
for line in lines:
data.append([float(x) for x in line.split()])
return torch.tensor(data)
# 定义网络结构
class Net(nn.Module):
def __init__(self, n):
super(Net, self).__init__()
self.linear = nn.Linear(n, n * n)
self.conv = nn.Conv2d(1, 1, (2, 2), stride=1, padding=1)
def forward(self, x):
x = self.linear(x)
x = x.view(1, 1, n, n)
x = self.conv(x)
return x
# 加载 ciphertext.txt 和 model.pth
ciphertext = read_ciphertext('ciphertext.txt')
n = int(ciphertext.shape[-1]) # 假设最后一维是 n
ciphertext = ciphertext.view(1, 1, n, n)
# 确保n与保存的模型一致
n = 47 # 根据错误信息设置为47
# 初始化网络
mynet = Net(n)
mynet.load_state_dict(torch.load('model.pth'))
# 定义一个可优化的输入变量
flag_tensor = torch.randn(n, requires_grad=True, dtype=torch.float32)
# 优化器
optimizer = torch.optim.Adam([flag_tensor], lr=0.1)
# 目标输出
target_output = ciphertext
# 迭代优化输入
for epoch in range(10000):
optimizer.zero_grad()
output = mynet(flag_tensor)
loss = nn.MSELoss()(output, target_output)
loss.backward()
optimizer.step()
if epoch % 1000 == 0:
print(f'Epoch {epoch}, Loss: {loss.item()}')
# 获取优化后的输入
optimized_flag = flag_tensor.detach().numpy()
# 将优化后的输入转换回字符
flag = ''.join([chr(int(round(x))) for x in optimized_flag])
print("Recovered flag:", flag)
修改一下部分细节最后确认一下
flag{Mi_muhe_mosi!Mi_muhe_mita,mita_movo_lata!}