源码下载
链接:https://pan.baidu.com/s/1gQbyhunPqrQ0qOidU7fR6Q 提取码:me3r 复制这段内容后打开百度网盘手机App,操作更方便哦
首先需要了解
PDO::prepare
首先我们看见函数定义了几个在db.php
global $db, 声明 $db 的作用范围为全局,就可以在函数里面使用了
这是已正序查看数据库name表里面的前五个字段名
function get_top_products() { global $db; $statement = $db->prepare( "SELECT name FROM products LIMIT 5"
check_errors($statement->execute()); 检查sql语句执行是否有错误
$res = $statement->get_result(); 执行sql得到的结果
check_errors($res);
$products = []; 定义数组products
while ( ($product = $res->fetch_assoc()) !== null) { //将结果便利到数组里面
array_push($products, $product); 把数组里面的添加到数组s
}
$statement->close();
return $products; 返回数组的值
这个其实不是重点
第二个函数
function get_product($name) { global $db; $statement = $db->prepare( "SELECT name, description FROM products WHERE name = ?" ); check_errors($statement); $statement->bind_param("s", $name); //定义$name的类型 ‘s’,$name是?处的值 check_errors($statement->execute()); 执行sql看是否报错 $res = $statement->get_result(); 得到结果 非数组 check_errors($res); $product = $res->fetch_assoc(); 便利到数组 $statement->close(); return $product;
第三个函数
function insert_product($name, $secret, $description) { global $db; $statement = $db->prepare( "INSERT INTO products (name, secret, description) VALUES//向数据库里面添加三个值 分别为name。。。。。 (?, ?, ?)" ); check_errors($statement); //检测错误 $statement->bind_param("sss", $name, $secret, $description); 定义???出的变量 check_errors($statement->execute()); 执行函数 $statement->close(); }
第四个函数
function check_name_secret($name, $secret) { global $db; $valid = false; $statement = $db->prepare( "SELECT name FROM products WHERE name = ? AND secret = ?" //查询 ); check_errors($statement); $statement->bind_param("ss", $name, $secret); //定义变量 check_errors($statement->execute()); $res = $statement->get_result(); //查询结果 check_errors($res); if ($res->fetch_assoc() !== null) { $valid = true; } $statement->close(); return $valid;//查询存在返回ture }
好的 主函数分析完了我们来看看 各个页面add.php
function validate_secret($secret) { if (strlen($secret) < 10) { //密码长度大于10 return false; } $has_lowercase = false; $has_uppercase = false; $has_number = false; foreach (str_split($secret) as $ch) { if (ctype_lower($ch)) { //密码里面有小写字母 $has_lowercase = true; } else if (ctype_upper($ch)) {//密码里面大写字母 $has_uppercase = true; } else if (is_numeric($ch)) {//变量里面含有数字 $has_number = true; } } return $has_lowercase && $has_uppercase && $has_number; //返回密码的hash到mysql }
$product = get_product($name);
if ($product !== null) {
return "Product name already exists, please enter again";
}
//执行查询语句 判断数据库是否存在这个产品
然后就是view.php
if (isset($name) && $name !== "" && isset($secret) && $secret !== "") { if (check_name_secret($name, hash('sha256', $secret)) === false) {//加密你的密码 然后进数据库查询
有朋友说可以注入啊
但是
echo "<p>Product details:"; echo "<ul><li>" . htmlentities($product['name']) . "</li>"; echo "<li>" . htmlentities($product['description']) . "</li></ul></p>"; 就已经完全杜绝注入了
那么 如何查到你想要的数据呐??
这里需要利用sql查询的漏洞 在增加用户名的时候 sql自动忽略64字节后面的数据 那么我们只需要构造 xxxx+60*空格+name 然后就行了 。
then you can in view.php get your flag。。