领航杯初赛 决赛 Wp
Misc
签到
修复png文件头,修改高度。
secret_data
![](https://img2022.cnblogs.com/blog/2031662/202209/2031662-20220903204201818-1651334746.png
50 4b 03 04 被掉过来了。每8位逆向输出
f = open('secret_data', 'rb').read()
b = b''
for i in range(0, len(f),8):
b += f[i:i+8][::-1]
open('f.zip', 'wb').write(b)
在Excel有个保护。找个东西干掉。然后取消隐藏列。
CnHongKe{658f1080a2ed0a8109153799c6f30128}
key.pdf
PDF打开。附件里有flag.rar导出,需要密码。。
全选pdf复制粘贴出来。看到 0u_cAn_n0T_sEe_Mekey y0u_cAn_n0T_sEe_Me
解压不行,怎么看都少个y。补上解压。得到flag
CnHongKe{d3fb34ef4a53552f3e4706351c9306a9}
reverse
serialize
jadx打开, keycode类有sercretData, base64解码看起来是个hashmap字节码。通过java来读取。
MainActivity中点击方法里。
if (MainActivity.this.getString(R.string.secretKey).equals(KeyCodec.encode(trim))) {
MainActivity mainActivity = MainActivity.this;
Toast.makeText(mainActivity, mainActivity.getString(R.string.tips_success), 0).show();
return;
}
要读取secretKey, 在 resouce-values-strings里面看到。 D502F80902D10DC35D610961E7C04F0933921EC3994533B5B5C3C3BCC3BCE76B
解题步骤:
1.反转map
2.每次读2字符通过map转字符。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.Map;
public class Go1 {
public static void main(String[] args) {
java.util.Base64.Decoder decoder = java.util.Base64.getDecoder();
String secretData = "rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAGB3CAAAAIAAAABEdAABIXQAAkU3dAABMHQAAjUwdAABMXQAAjU3dAABMnQAAjVFdAABM3QAAjY1dAABNHQAAjZDdAABNXQAAjczdAABNnQAAjdBdAABN3QAAjgxdAABOHQAAjg4dAABOXQAAjhGdAABQHQAAkMwdAABQXQAAkM3dAABQnQAAkNFdAABQ3QAAkQ1dAABRHQAAkRDdAABRXQAAkUzdAABRnQAAkVBdAABR3QAAkYxdAABSHQAAkY4dAABSXQAAkZGdAABSnQAAjA2dAABS3QAAjBEdAABTHQAAjE0dAABTXQAAjFCdAABTnQAAjIydAABT3QAAjI5dAABUHQAAjMwdAABUXQAAjM3dAABUnQAAjNFdAABU3QAAjQ1dAABVHQAAjRDdAABVXQAAjUzdAABVnQAAjVBdAABV3QAAjYxdAABWHQAAjY4dAABWXQAAjZGdAABWnQAAjc2dAABXnQAAjkydAABX3QAAjk5dAABYXQAAkE3dAABYnQAAkFFdAABY3QAAkI1dAABZHQAAkJDdAABZXQAAkMzdAABZnQAAkNBdAABZ3QAAkQxdAABaHQAAkQ4dAABaXQAAkRGdAABanQAAkU2dAABa3QAAkVEdAABbHQAAkY0dAABbXQAAkZCdAABbnQAAjAydAABb3QAAjA5dAABcHQAAjEwdAABcXQAAjE3dAABcnQAAjFFdAABc3QAAjI1dAABdHQAAjJDdAABdXQAAjMzdAABdnQAAjNBdAABd3QAAjQxdAABeHQAAjQ4dAABeXQAAjRGdAABenQAAjU2dAABe3QAAjVEdAABfXQAAjZCeA==";
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decoder.decode(secretData.getBytes()));
Map codeTable = null;
Map revTable = new HashMap();
try {
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
codeTable = (Map) objectInputStream.readObject();
for (Object k : codeTable.keySet()) {
revTable.put(codeTable.get(k).toString(), k.toString());
}
String secretKey = "D502F80902D10DC35D610961E7C04F0933921EC3994533B5B5C3C3BCC3BCE76B";
StringBuilder res = new StringBuilder();
for (int j = 0; j < secretKey.length(); j += 2) {
String k = secretKey.substring(j, j + 2);
String v = revTable.get(k).toString();
res.append(v);
}
System.out.println(res);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
// CnHongKe{WoW!@you^re_Succeeded!}
初赛
misc
1zipped
套娃解压
181_extract\readme.txt
395_extract\readme.txt
498_extract\readme.txt
The first part of flag: CnHongKe{2967b239
The second part of flag: aea9c72e93279ac06
The third part of flag: a92fb1f6438a66c}
re
easyre
encode3
__int64 __fastcall encode_three(const char *a1, int a2, char *a3, int *a4)
{
char v5; // [rsp+Fh] [rbp-11h]
int i; // [rsp+14h] [rbp-Ch]
const char *v8; // [rsp+30h] [rbp+10h]
v8 = a1;
if ( !a1 || !a2 )
return 0xFFFFFFFFi64;
for ( i = 0; i < a2; ++i )
{
v5 = *v8;
if ( *v8 <= '@' || v5 > 'Z' )
{
if ( v5 <= '`' || v5 > 'z' )
{
if ( v5 <= '/' || v5 > 0x39 )
*a3 = v5; // 其他不变
else
*a3 = (v5 - 48 + 3) % 10 + 48; // 数字右移3
}
else
{
*a3 = (v5 - 97 + 3) % 26 + 97; // 小写右移3
}
}
else
{ // 大写右移3
*a3 = (v5 - 'A' + 3) % 26 + 65;
}
++a3;
++v8;
}
return 0i64;
}
encode2
__int64 __fastcall encode_two(const char *in, int a2, char *out, int *a4)
{
if ( !in || !a2 )
return 0xFFFFFFFFi64;
strncpy(out, in + 26, 0xDui64); // 变换位置
strncpy(out + 13, in, 0xDui64);
strncpy(out + 26, in + 39, 0xDui64);
strncpy(out + 39, in + 13, 0xDui64);
return 0i64;
}
encode1: base64
import base64
enc = 'QmBmT3CWB5PpTT58Le58qV5Y0B3PcfcBWT4Bq3=WgnCmD8PcP7PG'
def step3(txt: str):
ta = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
tb = 'defghijklmnopqrstuvwxyzabcDEFGHIJKLMNOPQRSTUVWXYZABC3456789012'
tab = str.maketrans(tb, ta)
return txt.translate(tab)
def step2(lst):
return lst[13:26] + lst[39:] + lst[:13] + lst[26:39]
m2 = step3(enc)
m1 = step2(m2)
m = base64.b64decode(m1)
print(m)
# b'CnHongKe{a7df0933803cb44e662d4373a45b}'
NotXor
加密在 so 文件中。
__int64 __fastcall Java_com_ctf_cfe_MainActivity_validate(JNIEnv *a1, jobject a2, void *a3)
{
const char *input; // x19
signed int len; // w0
__int64 len1; // x8
int cur; // w9
unsigned int ch; // t1
unsigned int q; // w14
int b0; // w13
unsigned int qa; // w14
unsigned int v13; // w15
__int64 v14; // x8
char v17[256]; // [xsp+8h] [xbp-138h] BYREF
__int64 v18; // [xsp+108h] [xbp-38h]
v18 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
memset(v17, 0, sizeof(v17));
input = (*a1)->GetStringUTFChars(a1, a3, 0LL);
len = strlen(input);
if ( len >= 1 )
{
len1 = (unsigned int)len;
cur = 2; // 3位一处理
do
{
ch = *(unsigned __int8 *)input++;
--len1;
q = 4 * ((ch / 0x24) & 0xFFFFFFC7 | (8 * ((ch / 0x24) & 7)));// 0x24的商 (456位置0 | (留123位 << 3) << 2, 低3位<<5
// 0xff/0x24 最大就是7 等于把商(低3位) << 5 移到高3位去了
b0 = ch - q;
qa = (unsigned __int8)(q / 0x24);
v13 = 4 * ((qa / 0x24) & 0xC0000007 | (8 * ((qa / 0x24) & 0x7FFFFFF)));
LOBYTE(b0) = table1[b0];
LOBYTE(qa) = table1[qa - v13];
v17[cur - 2] = table1[(unsigned __int8)((char)v13 / 0x24) % 0x24u];
v17[cur - 1] = qa;
v17[cur] = b0;
cur += 3;
}
while ( len1 );
}
if ( strlen(v17) == 60LL )
{
v14 = 0LL;
while ( cipher[v14] == v17[v14] )
{
if ( v14++ > 58 )
return 1LL;
}
}
return 0LL;
}
table1 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
cipher = "02002F02602H01K02G01Y01G02901L02A01Z01W01K01L02901G01L02A02E"
直接改一下爆破。
#include <string.h>
#include <malloc.h>
#include "stdio.h"
char table1[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char cipher[] = "02002F02602H01K02G01Y01G02901L02A01Z01W01K01L02901G01L02A02E";
__int64 __fastcall validate() {
char *input = malloc(20);
signed int len;
__int64 len1;
int cur;
unsigned int ch;
unsigned int q;
int b0;
unsigned int qa;
unsigned int v13;
__int64 v14;
char v17[256];
__int64 v18;
strcpy(input, "aaaabaaacaaadaaaeaaa");
memset(v17, 0, sizeof(v17));
len = strlen(input);
if (len >= 1) {
len1 = (unsigned int) len;
cur = 2; // 3位一处理
do {
for (int i = 0x30; i < 128; ++i) {
// ch = *(unsigned __int8 *) input++;
ch = i;
--len1;
q = 4 * ((ch / 0x24) & 0xFFFFFFC7 | (8 * ((ch / 0x24) & 7)));
b0 = ch - q;
qa = (unsigned __int8) (q / 0x24);
v13 = 4 * ((qa / 0x24) & 0xC0000007 | (8 * ((qa / 0x24) & 0x7FFFFFF)));
b0 = table1[b0];
qa = table1[qa - v13];
v17[cur - 2] = table1[(unsigned __int8) ((char) v13 / 0x24) % 0x24u];
v17[cur - 1] = qa;
v17[cur] = b0;
if (v17[cur - 2] == cipher[cur - 2] && v17[cur - 1] == cipher[cur - 1] && v17[cur] == cipher[cur]) {
cur += 3;
printf("%c", i);
break;
} else{
++len1;
}
}
} while (len1);
}
if (strlen(v17) == 60LL) {
v14 = 0LL;
while (cipher[v14] == v17[v14]) {
if (v14++ > 58)
return 1LL;
}
}
return 0LL;
}
int main(int argc, char *argv[], char **env) {
setbuf(stdout, 0);
validate();
return 0;
}
HWNY8XF4Q9RGD89Q49RV
后来分析出来这是转了36进制。那就容易了。