最新消息:

unicode同形转换问题研究

学习探索 pang0lin 554浏览 0评论

0x01 前言

之前看hitcon的一个WEB题目的writeup时,一直对里面的一个问题表示疑惑。原来的代码是这样的

function login() {

  global $FLAG;

  list($username, $password) = func_get_args();

  $username = strtolower(trim(mysql_escape_string($username)));

  $password = strtolower(trim(mysql_escape_string($password)));

  $sql = sprintf("SELECT * FROM users WHERE username='%s' AND password='%s'", $username, $password);

  if ( $username == 'orange' || stripos($sql, 'orange') != false ) {

    $this->__die("Orange is so shy. He do not want to see you.");

  }
  
  $obj = $this->__query($sql);

  if ( $obj != false && $obj->role == 'admin' ) {

    $this->__die("Hi, Orange! Here is your flag: " . $FLAG);

  } else {

    $this->__die("Admin only!");

  }

}

里面有一个验证$username不能是’orange’,但是后面又要求role必须是admin,而role是admin的用户只能是’orange’,这样就陷入了一个怪圈,不能是orange,又必须是orange。

0x02关于unicode字符的同形转化问题

首先看下面的代码

<?php

include "config.php";

$conn = mysql_connect($db_host, $db_user, $db_pass);
mysql_select_db($db_name, $conn);

mysql_query("set names utf8");
 mysql_query("SET sql_mode = 'strict_all_tables'");


 if($_GET['action'] == 'register')
 {
    $query = mysql_query("INSERT INTO users(`username`,`password`,`role`) VALUES('".$_GET['username']."', '".$_GET['password']."', 1)");
    exit();
 }

$query = mysql_query("SELECT * FROM users WHERE username='".$_GET['xxx']."'");
$result = mysql_fetch_object($query);
var_dump($result);

当传入xxx=orange的时候,会得到一条返回记录

但是当我们传入xxx=orÃnge时,同样会得到和orange一样的数据

41

这里面最关键的就是这句话

mysql_query("set names utf8");

也就是说在查询数据库的时候按照utf-8编码方式进行查询,作者亲自试了一下,utf-32, utf-16, gbk, gb2312等一系列编码都不行。但是这也无所谓,有utf-8也就足够了

这是在查询的情况下,可以认为查询的变量会被自动的进行一次unicode同形转换,那么在插入的时候呢?

还是上面的代码,构造

http://localhost/hitcon/test1.php?action=register&username=or%C3nge&password=112222

然后我们看数据库中的数据的时候,可以看到存入数据库的变量orÃnge

42

这也就是说,在插入的时候,unicode字符会原封不动的插入数据库,但是在查询的时候确是会经过一次unicode同形转换。

0x03同形转换的应用场景

Creative usernames and Spotify account hijacking,可以修改任意用户的密码。

问题的鸡叻点在于首先用户注册了一个orange的用户,然后攻击者企图注册一个orÃnge的用户,以达到通过该用户重置正常用户的密码的情况。然而一般的网站在注册的时候都会用注册名做一个查重的操作,这样orÃnge就会被显示已经被注册

参考:http://www.mottoin.com/90890.html

 

转载请注明:我是穿山甲,小弟穿山乙 » unicode同形转换问题研究

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址