[web] phpreg
문제
php로 작성된 페이지에 접속해 Nickname, Password를 입력하여 Step 2로 넘어간 후 flag를 획득하는 문제입니다.
핵심 - PHP 코드 분석
문제 내 '문제 파일 받기'를 통해 step2.php 소스 파일을 분석 합니다.
전체
<div class="container">
<div class="box">
<!-- PHP code -->
<?php
// POST request
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$input_name = $_POST["input1"] ? $_POST["input1"] : "";
$input_pw = $_POST["input2"] ? $_POST["input2"] : "";
// pw filtering
if (preg_match("/[a-zA-Z]/", $input_pw)) {
echo "alphabet in the pw :(";
}
else{
$name = preg_replace("/nyang/i", "", $input_name);
$pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);
if ($name === "dnyang0310" && $pw === "d4y0r50ng+1+13") {
echo '<h4>Step 2 : Almost done...</h4><div class="door_box"><div class="door_black"></div><div class="door"><div class="door_cir"></div></div></div>';
$cmd = $_POST["cmd"] ? $_POST["cmd"] : "";
if ($cmd === "") {
echo '
<p><form method="post" action="/step2.php">
<input type="hidden" name="input1" value="'.$input_name.'">
<input type="hidden" name="input2" value="'.$input_pw.'">
<input type="text" placeholder="Command" name="cmd">
<input type="submit" value="제출"><br/><br/>
</form></p>
';
}
// cmd filtering
else if (preg_match("/flag/i", $cmd)) {
echo "<pre>Error!</pre>";
}
else{
echo "<pre>--Output--\n";
system($cmd);
echo "</pre>";
}
}
else{
echo "Wrong nickname or pw";
}
}
}
// GET request
else{
echo "Not GET request";
}
?>
</div>
</div>
부분 분석
// pw filtering
if (preg_match("/[a-zA-Z]/", $input_pw)) {
echo "alphabet in the pw :(";
}
- preg_match : 정규 표현식을 사용하여 문자열에서 패턴이 일치하는지 검사하는 php 함수
- "/[a-zA-Z]/" : 정규 표현식 패턴, 알파벳 a-z, A-Z 중 어떤 하나에 대응
분석 : $input_pw 변수의 값에 알파벳(a-z, A-Z)이 하나 이상 포함되어 있는지 검사
$name = preg_replace("/nyang/i", "", $input_name);
$pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);
- preg_replace : 정규 표현식을 사용하여 문자열을 대체하는 PHP 함수
- "/nyang/i": 정규 표현식 패턴, 대소문자를 무시하고 nyang 문자열에 대응
- "/\d*\@\d{2,3}(31)+[^0-8\"]\!/" : 정규 표현식 패턴
- \d*: 0개 이상의 숫자에 대응
- \@: '@' 문자에 대응
- \d{2,3}: 2개 또는 3개의 숫자에 대응
- (31)+: '31'이 1회 이상 반복되는 부분에 대응
- [^0-8\"]\!: '0'부터 '8'까지의 숫자와 '"' 이외의 문자에 대응, 이후에 '!' 문자에 대응
예시) 1@11319!
분석 : $input_name 변수의 값에 대소문자를 무시하고 "nyang" 패턴을 "공백"으로 대체하여 $name에 저장.
$input_pw 변수의 값에 위 정규 표현식 패턴을 "d4y0r50ng"으로 대체하여 $pw에 저장
// cmd filtering
else if (preg_match("/flag/i", $cmd)) {
echo "<pre>Error!</pre>";
}
else{
echo "<pre>--Output--\n";
system($cmd);
echo "</pre>";
}
분석 : $cmd 변수의 값에 대소문자를 무시하고 "flag" 패턴이 포함되어 있는지 검사