PHP简单代码审计(1)

CTF复习-PHP代码简单审计

function is_trying_to_hak_me($str)
{   
    $blacklist = ["' ", " '", '"', "`", " `", "` ", ">", "<"];
    if (strpos($str, "'") !== false) {
        if (!preg_match("/[0-9a-zA-Z]'[0-9a-zA-Z]/", $str)) {
            return true;
        }
    }
    foreach ($blacklist as $token) {
        if (strpos($str, $token) !== false) return true;
    }
    return false;
}

整个函数顾名思义,进行输入检测,判断是否是黑客行为,要使函数返回false即可绕过这个输入检测。

定义了一个黑名单:

$blacklist = ["' ", " '", '"', "`", " `", "` ", ">", "<"]

黑名单:单引号+空格、空格+单引号、双引号、反引号、反引号+空格、空格+反引号、<、>

  1. 过滤单引号和空格的组合,通常是为了防止类似**’ or ‘1’ = ‘1’**这种类似的注入
  2. 双引号通常用于Sql语句闭合字符串
  3. 反引号一般用于包裹MySql表名或字段名,也可用于命令执行
  4. 两个尖括号通常用于php代码或者xss的payload
if (strpos($str, "'") !== false) {
        if (!preg_match("/[0-9a-zA-Z]'[0-9a-zA-Z]/", $str)) {
            return true;
        }
    }

前面的过滤并非是把单引号直接打死,而是禁止单引号与空格的组合,在这串代码里面,就对单引号作了更严格的过滤

preg_match函数会拿着前面的正则表达式在**$str**变量里面匹配,也就是说可以用单引号,但是单引号前后必须有数字或者字母

继续审计

$db = new SQLite3("/var/db.sqlite");
$result = $db->query("SELECT * FROM users WHERE username='$user'");
if ($result === false) die("pls dont break me");
else $result = $result->fetchArray();
if ($result) {
    $split = explode('$', $result["password"]);
    $password_hash = $split[0];
    $salt = $split[1];
    if ($password_hash === hash("sha256", $pass.$salt)) $logged_in = true;
    else $err = "Wrong password";
}
else $err = "No such user";

实例化一个 SQLite3 对象,连接到服务器路径 /var/db.sqlite 的数据库文件

需要让输入的$user插入sql语句中能够正确返回

注意两个点:语句整体正确和注释符号正确

对于输入的result值里面提取到password,将’$’左边作为password的hash值,右边作为盐值

将password处输入的pass与盐值拼接进行sha256计算,如果等于输入的password_hash,则会通过验证

这里面就不能用#,需要用—或者–+

user传入admin’union select 1,’49d180ecf56132819571bf39d9b7b342522a2ac6d23c1418d3338251bfe469c8$7’–+

pass传入6

49d180ecf56132819571bf39d9b7b342522a2ac6d23c1418d3338251bfe469c8为67的sha256计算值,此时返回$logged_in为true

上一篇
下一篇