buu 代码审计
代码审计
[HCTF 2018] WarmUp
查看源码
访问 source.php
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
看到hint.php
利用indlue函数 文件包含漏洞
这边是 在source.php文件下如果满足这三个条件,就输出指定文件
因为参数在source.php文件下 所以要在source.php文件下传参
检查file是否在白名单中,在就返回true
试着传参
发现输出了两 遍源码
这两段代码一样是为了防止用户传参时,符号被urlencode导致无法解析
mb_substr()函数:返回字符串的一部分
这段是说,截取传入的file的值,从开始到?处(不包含?
)将截取后的字符串和白名单做对比,可以就返回true
只有一遍源码了
所以在第二个source.php?后面直接访问fllllaaaagggg
但是因为此时source.php会被当成一个文件夹,所以加个/
../
返回上一级目录
[BJDCTF2020]Mark loves cat
dirsearch扫描发现是git泄露
githack.py下载得到源文件 index.php
<?php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}index.php
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;
flag.php
<?php
$flag = file_get_contents('/flag');
foreach循环导致变量覆盖
foreach是用于数组和对象的循环语句
-
<?PHP $authors = array( "Java", "PHP", "CSS", "HTML" ); foreach ( $authors as $val ) { echo $val . "\n"; } ?>
-
<?php //from ww w . ja va2s . c o m $myBook = array( "title" => "Learn PHP from www.w3cschool.cn", "author" => "www.w3cschool.cn", "pubYear" => 2000 ); foreach ( $myBook as $key => $value ) { echo "$key \n"; echo "$value \n"; } ?>
-
<?PHP /*www .j a va 2 s. c o m*/ $authors = array( "Java", "PHP", "CSS", "HTML" ); // Displays "Java PHP Javascript HTML"; foreach ( $authors as $val ) { if ( $val == "CSS" ) $val = "Javascript"; echo $val . " "; } print_r ( $authors ); ?>
可变变量
如果一个变量的值刚好是另一个变量的名字 就可以通过访问一个变量来得到另一个变量
方法; 在此变量 之前加一个 $
例如 $$x
相当于 $($x)
1.构造payoad
yds=flag
exit()也是输出的一种
yds=flag
被处理为 $yds=$flag
因为没有传入 $_GET和$_POST
所以直接输出exit()
$handsome = 'yds';
使 yds=flag
输出handsome为flag{}
2.构造payload
经处理 $is=$flag
输出$flag 构造 flag=flag
是为了exit(is)
[ZJCTF 2019]NiZhuanSiWe
源码
<?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__);
}
?>
file_get_contents
把文件读到一个字符串中
利用伪协议php://input
绕过file_get_contents
函数
读取文件里的字符串,要和 welcome to the zjctf
相等
构造paylaod
flag
被匹配掉了
尝试读取useless.php源码,用php://filter
base64解码
看到__toString
方法
构造payload读取flag.php,将N替换为flag.php
访问源码