PHP反序列化总结

问题原因:漏洞的根源在于unserialize()函数的参数可控。如果反序列化对象中存在魔术方法,而且魔术方法中的代码或变量用户可控,就可能产生反序列化漏洞,根据反序列化后不同的代码可以导致各种攻击,如代码注入、SQL注入、目录遍历等等。
魔术方法:PHP的类中可能会包含一些特殊的函数叫魔术函数,魔术函数命名是以符号__开头的; 有以下的魔术方法: __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set(), _state(), __clone(), __debugInfo()

参考文章

https://www.jianshu.com/p/631606cc5b76
https://www.freebuf.com/vuls/116705.html
https://blog.csdn.net/qq_42196196/article/details/81217375
https://blog.spoock.com/2016/11/08/hitcon-babytrick-writeup/

method = $method;
        $this->args = $args;
 
        $this->__conn();
    }
 
    function show() {
        list($username) = func_get_args();//func_get_args()返回一个包含函数参数列表的数组,即传入show()函数的参数
        $sql = sprintf("SELECT * FROM users WHERE username='%s'", $username);
        //sprintf()把百分号(%)符号替换成一个作为参数进行传递的变量
 
        $obj = $this->__query($sql);
        if ( $obj != false  ) {
            $this->__die( sprintf("%s is %s", $obj->username, $obj->role) );
        } else {
            $this->__die("Nobody Nobody But You!");
        }
        
    }
 
    function login() {
        global $FLAG;
        list($username, $password) = func_get_args();
        $username = strtolower(trim(mysql_escape_string($username)));//strtolower()转小写trim()去空格mysql_escape_string()转义在 SQL 语句中使用的字符串中的特殊字符。
        $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 ) {                //特殊字符Ã绕过;
        //stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)
            $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!");
        }
    }
 
    function source() {
        highlight_file(__FILE__);
    }
 
    function __conn() {
        global $db_host, $db_name, $db_user, $db_pass, $DEBUG;
 
        if (!$this->conn)
            $this->conn = mysql_connect($db_host, $db_user, $db_pass);
        mysql_select_db($db_name, $this->conn);
 
        if ($DEBUG) {
            $sql = "CREATE TABLE IF NOT EXISTS users ( 
                        username VARCHAR(64), 
                        password VARCHAR(64), 
                        role VARCHAR(64)
                    ) CHARACTER SET utf8";
            $this->__query($sql, $back=false);
 
            $sql = "INSERT INTO users VALUES ('orange', '$db_pass', 'admin'), ('phddaa', 'ddaa', 'user')";
            $this->__query($sql, $back=false);
        } 
 
        mysql_query("SET names utf8");                          //使用utf8编码方式
        mysql_query("SET sql_mode = 'strict_all_tables'");//严格模式
    }
 
    function __query($sql, $back=true) {
        $result = @mysql_query($sql);//mysql_query() 函数执行一条 MySQL 查询。
        if ($back) {
            return @mysql_fetch_object($result);
        }
    }
 
    function __die($msg) {
        $this->__close();
 
        header("Content-Type: application/json");
        die( json_encode( array("msg"=> $msg) ) );
    }
 
    function __close() {
        mysql_close($this->conn);
    }
 
    function __destruct() {
        $this->__conn();             //将数据写入数据库;
 
        if (in_array($this->method, array("show", "login", "source"))) {
            @call_user_func_array(array($this, $this->method), $this->args);
        } else {
            $this->__die("What do you do?");
        }
 
        $this->__close();
    }
 
    function __wakeup() {
        foreach($this->args as $k => $v) {
            $this->args[$k] = strtolower(trim(mysql_escape_string($v)));
        }
    }
}
 
if(isset($_GET["data"])) {                        //侦测有无data的get获取;
    @unserialize($_GET["data"]);                  //跳过 __wakeup()函数;调用析构函数
} else {
    new HITCON("source", array());
}
?>

你可能感兴趣的:(PHP反序列化总结)