2025年湾区杯网络安全大赛初赛
hardtest
IDA 打开反编译,逻辑很清晰,就是两块加密,第一个输入一个伪随机数没什么用
__int64 __fastcall main(int a1, char **a2, char **a3)
{
unsigned int seed; // eax
unsigned __int64 v5; // rax
void *v6; // rsp
unsigned __int64 v7; // rax
void *v8; // rsp
__int64 encFlag1[4]; // [rsp+8h] [rbp-F0h] BYREF
char v10; // [rsp+29h] [rbp-CFh] BYREF
char v11; // [rsp+2Ah] [rbp-CEh]
char v12; // [rsp+2Bh] [rbp-CDh]
int j; // [rsp+2Ch] [rbp-CCh]
int i; // [rsp+30h] [rbp-C8h]
int flag_len; // [rsp+34h] [rbp-C4h]
__int64 v16; // [rsp+38h] [rbp-C0h]
__int64 *p_encFlag1; // [rsp+40h] [rbp-B8h]
__int64 v18; // [rsp+48h] [rbp-B0h]
__int64 *p_encFlag1_1; // [rsp+50h] [rbp-A8h]
char flag[104]; // [rsp+58h] [rbp-A0h] BYREF
unsigned __int64 v21; // [rsp+C0h] [rbp-38h]
v21 = __readfsqword(0x28u);
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
seed = time(0LL);
srand(seed);
v12 = rand() % 255 + 1;
printf("input your number(1-255): ");
if ( __isoc99_scanf("%d", &v10) == 1 && v12 == v10 )
{
while ( getchar() != 10 )
;
printf("flag: ");
fgets(flag, 100, stdin);
flag[strcspn(flag, "\n")] = 0;
flag_len = strlen(flag);
v16 = flag_len - 1LL;
encFlag1[2] = flag_len;
encFlag1[3] = 0LL;
encFlag1[0] = flag_len;
encFlag1[1] = 0LL;
v5 = 16 * ((flag_len + 15LL) / 0x10uLL);
while ( encFlag1 != (encFlag1 - (v5 & 0xFFFFFFFFFFFFF000LL)) )
;
v6 = alloca(v5 & 0xFFF);
if ( (v5 & 0xFFF) != 0 )
*(&encFlag1[-1] + (v5 & 0xFFF)) = *(&encFlag1[-1] + (v5 & 0xFFF));
p_encFlag1 = encFlag1;
crypto1(flag, encFlag1);
v18 = flag_len - 1LL;
v7 = 16 * ((flag_len + 15LL) / 0x10uLL);
while ( encFlag1 != (encFlag1 - (v7 & 0xFFFFFFFFFFFFF000LL)) )
;
v8 = alloca(v7 & 0xFFF);
if ( (v7 & 0xFFF) != 0 )
*(&encFlag1[-1] + (v7 & 0xFFF)) = *(&encFlag1[-1] + (v7 & 0xFFF));
p_encFlag1_1 = encFlag1;
for ( i = 0; i < flag_len; ++i )
*(p_encFlag1_1 + i) = crypto2(*(p_encFlag1 + i));
v11 = 1;
for ( j = 0; j < flag_len; ++j )
{
if ( *(p_encFlag1_1 + j) != enc[j] )
{
v11 = 0;
break;
}
}
if ( v11 )
puts("right");
return 0LL;
}
else
{
puts("error");
return 1LL;
}
}


直接抄下来,跑破就完事了
exp 如下
# Encrypted data from address 0x2120
encrypted_data = [
0x97, 0xd5, 0x60, 0x43, 0xb4, 0x10, 0x43, 0x73, 0x0f, 0xda, 0x43, 0xcd,
0xd3, 0xe8, 0x73, 0x4a, 0x94, 0xc3, 0xcd, 0x71, 0xbd, 0xdc, 0x97, 0x1a
]
Sbox = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01,
0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D,
0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4,
0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7,
0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E,
0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB,
0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB,
0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C,
0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C,
0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D,
0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A,
0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3,
0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A,
0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E,
0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9,
0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99,
0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
def rotate_left(value, shift):
return ((value << shift) | (value >> (8 - shift))) & 0xFF
def rotate_right(value, shift):
return ((value >> shift) | (value << (8 - shift))) & 0xFF
def sub_1313(v4):
index = 255
v2 = 1
while index:
if (index & 1) != 0:
v2 = v4 * v2 % 257
v4 = v4 * v4 % 257
index >>= 1
return v2
enc1 = [0] * len(encrypted_data)
for i in range(len(encrypted_data)):
for char in range(32, 128):
temp = char
enc1[i] = rotate_left(char, (i % 7) + 1)
v1 = rotate_left(enc1[i] ^ 0x5A, 3)
v3 = sub_1313((16 * ((3 * (v1 >> 4)) & 0xF)) | (5 * (v1 & 0xF)) & 0xF)
if encrypted_data[i] == Sbox[rotate_right(v3, 2)]:
print(chr(temp), end="")
break# Encrypted data from address 0x2120
encrypted_data = [
0x97, 0xd5, 0x60, 0x43, 0xb4, 0x10, 0x43, 0x73, 0x0f, 0xda, 0x43, 0xcd,
0xd3, 0xe8, 0x73, 0x4a, 0x94, 0xc3, 0xcd, 0x71, 0xbd, 0xdc, 0x97, 0x1a
]
Sbox = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01,
0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D,
0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4,
0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7,
0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E,
0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB,
0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB,
0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C,
0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C,
0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D,
0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A,
0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3,
0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A,
0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E,
0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9,
0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99,
0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
def rotate_left(value, shift):
return ((value << shift) | (value >> (8 - shift))) & 0xFF
def rotate_right(value, shift):
return ((value >> shift) | (value << (8 - shift))) & 0xFF
def sub_1313(v4):
index = 255
v2 = 1
while index:
if (index & 1) != 0:
v2 = v4 * v2 % 257
v4 = v4 * v4 % 257
index >>= 1
return v2
enc1 = [0] * len(encrypted_data)
for i in range(len(encrypted_data)):
for char in range(32, 128):
temp = char
enc1[i] = rotate_left(char, (i % 7) + 1)
v1 = rotate_left(enc1[i] ^ 0x5A, 3)
v3 = sub_1313((16 * ((3 * (v1 >> 4)) & 0xF)) | (5 * (v1 & 0xF)) & 0xF)
if encrypted_data[i] == Sbox[rotate_right(v3, 2)]:
print(chr(temp), end="")
break
flag{Bl@st1ng_1s_a_g00d_Way!!}
strangeApp
有点唐的,app 运行不起来,后来在公司试了不少测试机,并且还得插卡,Java 层有检测,然后跑起来,
并用 frida-dexdump 脱壳,
第一个就是关键的 dex 文件,JADX 打开,如果报 checksum 有问题,那么就在首选项把下面这个选项关掉,或者写个脚本修复一下
关掉之后,就可以正常打开了
package com.swdd.strangeapp;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/* loaded from: C:\Users\16219\Desktop\strangeapp\classes.dex */
public class MainActivity extends AppCompatActivity {
private static final byte[] TARGET = {118, 17, 7, 124, -99, 51, 23, -123, -78, 23, -53, 1, 42, 109, -77, 5, -87, 10, -77, 106, 78, 100, 123, -118, -47, 31, 19, 56, 115, -105, -11, -38, -18, -72, 12, 42, 17, 55, -121, -44, 119, -41, 87, 118, 95, -76, -84, 69};
public static String a(String algo) {
if (algo == null || algo.isEmpty()) {
return algo;
}
char first = algo.charAt(0);
char changed = (char) (first ^ 5);
return changed + algo.substring(1);
}
@Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText flag = (EditText) findViewById(R.id.inputText);
Button checkButton = (Button) findViewById(R.id.checkButton);
checkButton.setOnClickListener(new View.OnClickListener() { // from class: com.swdd.strangeapp.MainActivity$$ExternalSyntheticLambda0
@Override // android.view.View.OnClickListener
public final void onClick(View view) {
this.f$0.m160lambda$onCreate$0$comswddstrangeappMainActivity(flag, view);
}
});
}
/* renamed from: lambda$onCreate$0$com-swdd-strangeapp-MainActivity */
/* synthetic */ void m160lambda$onCreate$0$comswddstrangeappMainActivity(EditText inputText, View v) {
String input = inputText.getText().toString();
try {
byte[] encrypted = aa(input);
if (compareBytes(encrypted, TARGET)) {
showDialog("Good");
} else {
showDialog("NO");
}
} catch (Exception e) {
showDialog("加密失败: " + e.getMessage());
}
}
private byte[] aa(String input) throws Exception {
Key secretKey = new SecretKeySpec("1234567891123456".getBytes(StandardCharsets.UTF_8), a("DES"));
IvParameterSpec iv = new IvParameterSpec("1234567891123456".getBytes(StandardCharsets.UTF_8));
Cipher cipher = Cipher.getInstance(a("DES/CBC/PKCS5Padding"));
cipher.init(1, secretKey, iv);
return cipher.doFinal(input.getBytes(StandardCharsets.UTF_8));
}
private boolean compareBytes(byte[] a, byte[] b) {
if (a == null || b == null || a.length != b.length) {
return false;
}
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}
private void showDialog(String msg) {
new AlertDialog.Builder(this).setMessage(msg).setPositiveButton("OK", (DialogInterface.OnClickListener) null).show();
}
}
就是一个 AES 加密,DES 以字符串的形式传到 a 方法,然后首字母进行异或一下,就是 AES,赛博厨子一把梭
minigame
小程序逆向,给的附件中没有文件后缀,加一下就可以了
然后使用这个项目解包,biggerstar/wedecode: 全自动化,微信小程序 wxapkg 包 源代码还原工具, 线上代码安全审计

check逻辑就在 wasm 文件里,ghidra 装插件就可以直接反编译了
就是一个 xor,直接一把梭
后面补个 大括号
flag{fae0b27c451c728867a567e8c1bb4e53}
checkwebshell
进流量包搜索flag:

看到709包有明显的flag脚本内容,直接追踪HTTP流并下载为1.php
<?php
class SM4 {
const ENCRYPT = 1;
private $sk;
private static $FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC];
private static $CK = [
0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229,
0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209,
0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
];
private static $SboxTable = [
0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05,
0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62,
0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6,
0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8,
0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35,
0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x0D, 0x2D, 0xEC,
0x84, 0x9B, 0x1E, 0x87, 0xE0, 0x3E, 0xB5, 0x66, 0x48, 0x02, 0x6C, 0xBB, 0xBB, 0x32, 0x83, 0x27,
0x9E, 0x01, 0x8D, 0x53, 0x9B, 0x64, 0x7B, 0x6B, 0x6A, 0x6C, 0xEC, 0xBB, 0xC4, 0x94, 0x3B, 0x0C,
0x76, 0xD2, 0x09, 0xAA, 0x16, 0x15, 0x3D, 0x2D, 0x0A, 0xFD, 0xE4, 0xB7, 0x37, 0x63, 0x28, 0xDD,
0x7C, 0xEA, 0x97, 0x8C, 0x6D, 0xC7, 0xF2, 0x3E, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7,
0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x36, 0x24, 0x07, 0x82, 0xFA, 0x54, 0x5B, 0x40,
0x8F, 0xED, 0x1F, 0xDA, 0x93, 0x80, 0xF9, 0x61, 0x1C, 0x70, 0xC3, 0x85, 0x95, 0xA9, 0x79, 0x08,
0x46, 0x29, 0x02, 0x3B, 0x4D, 0x83, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x1A, 0x47, 0x5C, 0x0D, 0xEA,
0x9E, 0xCB, 0x55, 0x20, 0x15, 0x8A, 0x9A, 0xCB, 0x43, 0x0C, 0xF0, 0x0B, 0x40, 0x58, 0x00, 0x8F,
0xEB, 0xBE, 0x3D, 0xC2, 0x9F, 0x51, 0xFA, 0x13, 0x3B, 0x0D, 0x90, 0x5B, 0x6E, 0x45, 0x59, 0x33
];
public function __construct($key) {
$this->setKey($key);
}
public function setKey($key) {
if (strlen($key) != 16) {
throw new Exception("SM4");
}
$key = $this->strToIntArray($key);
$k = array_merge($key, [0, 0, 0, 0]);
for ($i = 0; $i < 4; $i++) {
$k[$i] ^= self::$FK[$i];
}
for ($i = 0; $i < 32; $i++) {
$k[$i + 4] = $k[$i] ^ $this->CKF($k[$i + 1], $k[$i + 2], $k[$i + 3], self::$CK[$i]);
$this->sk[$i] = $k[$i + 4];
}
}
public function encrypt($plaintext) {
$len = strlen($plaintext);
$padding = 16 - ($len % 16);
$plaintext .= str_repeat(chr($padding), $padding);
$ciphertext = '';
for ($i = 0; $i < strlen($plaintext); $i += 16) {
$block = substr($plaintext, $i, 16);
$ciphertext .= $this->cryptBlock($block, self::ENCRYPT);
}
return $ciphertext;
}
private function cryptBlock($block, $mode) {
$x = $this->strToIntArray($block);
for ($i = 0; $i < 32; $i++) {
$roundKey = $this->sk[$i];
$x[4] = $x[0] ^ $this->F($x[1], $x[2], $x[3], $roundKey);
array_shift($x);
}
$x = array_reverse($x);
return $this->intArrayToStr($x);
}
private function F($x1, $x2, $x3, $rk) {
return $this->T($x1 ^ $x2 ^ $x3 ^ $rk);
}
private function CKF($a, $b, $c, $ck) {
return $a ^ $this->T($b ^ $c ^ $ck);
}
private function T($x) {
return $this->L($this->S($x));
}
private function S($x) {
$result = 0;
for ($i = 0; $i < 4; $i++) {
$byte = ($x >> (24 - $i * 8)) & 0xFF;
$result |= self::$SboxTable[$byte] << (24 - $i * 8);
}
return $result;
}
private function L($x) {
return $x ^ $this->rotl($x, 2) ^ $this->rotl($x, 10) ^ $this->rotl($x, 18) ^ $this->rotl($x, 24);
}
private function rotl($x, $n) {
return (($x << $n) & 0xFFFFFFFF) | (($x >> (32 - $n)) & 0xFFFFFFFF);
}
private function strToIntArray($str) {
$result = [];
for ($i = 0; $i < 4; $i++) {
$offset = $i * 4;
$result[$i] =
(ord($str[$offset]) << 24) |
(ord($str[$offset + 1]) << 16) |
(ord($str[$offset + 2]) << 8) |
ord($str[$offset + 3]);
}
return $result;
}
private function intArrayToStr($array) {
$str = '';
foreach ($array as $int) {
$str .= chr(($int >> 24) & 0xFF);
$str .= chr(($int >> 16) & 0xFF);
$str .= chr(($int >> 8) & 0xFF);
$str .= chr($int & 0xFF);
}
return $str;
}
}
try {
$key = "a8a58b78f41eeb6a";
$sm4 = new SM4($key);
$plaintext = "flag";
$ciphertext = $sm4->encrypt($plaintext);
echo base64_encode($ciphertext) ; //VCWBIdzfjm45EmYFWcqXX0VpQeZPeI6Qqyjsv31yuPTDC80lhFlaJY2R3TintdQu
} catch (Exception $e) {
echo $e->getMessage() ;
}
?>
复制脚本给GPT,并且提示词:
帮我写一个这个解密脚本,从base64_encode($ciphertext)还原到plaintext,输出的base64是VCWBIdzfjm45EmYFWcqXX0VpQeZPeI6Qqyjsv31yuPTDC80lhFlaJY2R3TintdQu。直接给我逆向脚本就可以了
解密脚本:
<?php
class SM4 {
const ENCRYPT = 1;
const DECRYPT = 0;
private $sk;
private static $FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC];
private static $CK = [
0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229,
0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209,
0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
];
private static $SboxTable = [
0xD6,0x90,0xE9,0xFE,0xCC,0xE1,0x3D,0xB7,0x16,0xB6,0x14,0xC2,0x28,0xFB,0x2C,0x05,
0x2B,0x67,0x9A,0x76,0x2A,0xBE,0x04,0xC3,0xAA,0x44,0x13,0x26,0x49,0x86,0x06,0x99,
0x9C,0x42,0x50,0xF4,0x91,0xEF,0x98,0x7A,0x33,0x54,0x0B,0x43,0xED,0xCF,0xAC,0x62,
0xE4,0xB3,0x1C,0xA9,0xC9,0x08,0xE8,0x95,0x80,0xDF,0x94,0xFA,0x75,0x8F,0x3F,0xA6,
0x47,0x07,0xA7,0xFC,0xF3,0x73,0x17,0xBA,0x83,0x59,0x3C,0x19,0xE6,0x85,0x4F,0xA8,
0x68,0x6B,0x81,0xB2,0x71,0x64,0xDA,0x8B,0xF8,0xEB,0x0F,0x4B,0x70,0x56,0x9D,0x35,
0x1E,0x24,0x0E,0x5E,0x63,0x58,0xD1,0xA2,0x25,0x22,0x7C,0x3B,0x01,0x0D,0x2D,0xEC,
0x84,0x9B,0x1E,0x87,0xE0,0x3E,0xB5,0x66,0x48,0x02,0x6C,0xBB,0xBB,0x32,0x83,0x27,
0x9E,0x01,0x8D,0x53,0x9B,0x64,0x7B,0x6B,0x6A,0x6C,0xEC,0xBB,0xC4,0x94,0x3B,0x0C,
0x76,0xD2,0x09,0xAA,0x16,0x15,0x3D,0x2D,0x0A,0xFD,0xE4,0xB7,0x37,0x63,0x28,0xDD,
0x7C,0xEA,0x97,0x8C,0x6D,0xC7,0xF2,0x3E,0x1A,0x71,0x1D,0x29,0xC5,0x89,0x6F,0xB7,
0x62,0x0E,0xAA,0x18,0xBE,0x1B,0xFC,0x56,0x36,0x24,0x07,0x82,0xFA,0x54,0x5B,0x40,
0x8F,0xED,0x1F,0xDA,0x93,0x80,0xF9,0x61,0x1C,0x70,0xC3,0x85,0x95,0xA9,0x79,0x08,
0x46,0x29,0x02,0x3B,0x4D,0x83,0x3A,0x0A,0x49,0x06,0x24,0x1A,0x47,0x5C,0x0D,0xEA,
0x9E,0xCB,0x55,0x20,0x15,0x8A,0x9A,0xCB,0x43,0x0C,0xF0,0x0B,0x40,0x58,0x00,0x8F,
0xEB,0xBE,0x3D,0xC2,0x9F,0x51,0xFA,0x13,0x3B,0x0D,0x90,0x5B,0x6E,0x45,0x59,0x33
];
public function __construct($key) {
$this->setKey($key);
}
public function setKey($key) {
if (strlen($key) != 16) throw new Exception("SM4");
$key = $this->strToIntArray($key);
$k = array_merge($key, [0,0,0,0]);
for ($i=0;$i<4;$i++) $k[$i] ^= self::$FK[$i];
for ($i=0;$i<32;$i++) {
$k[$i+4] = $k[$i] ^ $this->CKF($k[$i+1], $k[$i+2], $k[$i+3], self::$CK[$i]);
$this->sk[$i] = $k[$i+4];
}
}
public function decrypt($ciphertext) {
$plaintext = '';
for ($i=0; $i<strlen($ciphertext); $i+=16) {
$block = substr($ciphertext, $i, 16);
$plaintext .= $this->cryptBlock($block, self::DECRYPT);
}
// 去掉 PKCS#7 填充
$pad = ord(substr($plaintext, -1));
return substr($plaintext, 0, -$pad);
}
private function cryptBlock($block, $mode) {
$x = $this->strToIntArray($block);
for ($i=0; $i<32; $i++) {
$rk = $this->sk[$mode==self::ENCRYPT ? $i : (31-$i)];
$x[4] = $x[0] ^ $this->F($x[1], $x[2], $x[3], $rk);
array_shift($x);
}
$x = array_reverse($x);
return $this->intArrayToStr($x);
}
private function F($x1,$x2,$x3,$rk){return $this->T($x1^$x2^$x3^$rk);}
private function CKF($a,$b,$c,$ck){return $a ^ $this->T($b^$c^$ck);}
private function T($x){return $this->L($this->S($x));}
private function S($x){
$r=0;
for($i=0;$i<4;$i++){
$b=($x>>(24-$i*8))&0xFF;
$r|=self::$SboxTable[$b]<<(24-$i*8);
}
return $r;
}
private function L($x){return $x ^ $this->rotl($x,2)^$this->rotl($x,10)^$this->rotl($x,18)^$this->rotl($x,24);}
private function rotl($x,$n){return (($x<<$n)&0xFFFFFFFF)|(($x>>(32-$n))&0xFFFFFFFF);}
private function strToIntArray($str){
$res=[];
for($i=0;$i<4;$i++){
$o=$i*4;
$res[$i]=(ord($str[$o])<<24)|(ord($str[$o+1])<<16)|(ord($str[$o+2])<<8)|ord($str[$o+3]);
}
return $res;
}
private function intArrayToStr($arr){
$s='';
foreach($arr as $int){
$s.=chr(($int>>24)&0xFF).chr(($int>>16)&0xFF).chr(($int>>8)&0xFF).chr($int&0xFF);
}
return $s;
}
}
try {
$key = "a8a58b78f41eeb6a";
$sm4 = new SM4($key);
$cipher_b64 = "VCWBIdzfjm45EmYFWcqXX0VpQeZPeI6Qqyjsv31yuPTDC80lhFlaJY2R3TintdQu";
$cipher_raw = base64_decode($cipher_b64);
$plaintext = $sm4->decrypt($cipher_raw);
echo $plaintext; // 输出: flag
} catch (Exception $e) {
echo $e->getMessage();
}
?>
获得flag:

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1621925986@qq.com