방명록
- Old-262024년 12월 31일 17시 58분 01초에 업로드 된 글입니다.작성자: sonootri
문제
소스코드가 주어졌다. 이외에는 별다른 기능이 보이지 않는걸 보니 쿼리문을 사용해서 푸는게 아닐까 싶다.
<?php include "../../config.php"; if($_GET['view_source']) view_source(); ?><html> <head> <title>Challenge 26</title> <style type="text/css"> body { background:black; color:white; font-size:10pt; } a { color:lightgreen; } </style> </head> <body> <?php if(preg_match("/admin/",$_GET['id'])) { echo"no!"; exit(); } $_GET['id'] = urldecode($_GET['id']); if($_GET['id'] == "admin"){ solve(26); } ?> <br><br> <a href=?view_source=1>view-source</a> </body> </html>
문제 분석
#(1)
첫 번째 조건문이다. 사용자로부터 url 쿼리 문자열에서 id값을 받아온다. 이때 id값이 admin이라면 no를 출력한다.
#(2)
사용자로부터 id값을 받아온다. 그리고 받아온 id값을 디코딩한다. 예를들어 '#'은 인코딩하면 %23이 되고, 이를 디코딩하면 #가 된다. 이후 디코딩한 값이 admin이라면 문제가 풀리는 것 같다.
<body> <?php if(preg_match("/admin/",$_GET['id'])) { echo"no!"; exit(); } #(1) $_GET['id'] = urldecode($_GET['id']); #(2) if($_GET['id'] == "admin"){ solve(26); } ?> <br><br> <a href=?view_source=1>view-source</a> </body>
urldecode()
% 기호와 뒤에 있는 두 개의 16진수 숫자로 이어진 인코딩된 문자를 실제 문자로 변환하여 디코딩하고, + 기호는 공백 문자로 대체하는 함수이다.
$url = 'https://www.example.com/page.php?name=John Doe'; $encoded_url = urlencode($url); echo $encoded_url . '<br>'; // 출력: https%3A%2F%2Fwww.example.com%2Fpage.php%3Fname%3DJohn+Doe $decoded_url = urldecode($url); echo $decoded_url; // 출력: https://www.example.com/page.php?name=John Doe
<주의해야할 점>
$_GET, $_POST, $_REQUEST와 같은 슈퍼글로벌 변수는 이미 URL 디코딩이 된 상태이다. 이러한 변수에서 urldecode() 함수를 사용하면 예상치 못한 결과 및 보안 문제가 발생할 수 있다. 따라서 이러한 변수를 추가로 디코딩하지 않아야 한다.취약점
1. (1)번에 의해 id가 admin이면 안되고, (2)에 의해 복호화된 id가 admin이면 문제가 풀린다. 입력값은 admin이 아니되 출력값은 admin이여야한다?
익스플로잇(write-up 참고)
PHP에서 url로 전달되는 데이터 id는 슈퍼글로벌 변수에 저장되기 전에 자동으로 디코딩된다(정리 부분 참고). 때문에 url 인코딩 된 문자열이 디코딩된 상태로 preg_match()에 전달된다.
if(preg_match("/admin/",$_GET['id'])) { echo"no!"; exit(); } #(1) $_GET['id'] = urldecode($_GET['id']); #(2) if($_GET['id'] == "admin"){ solve(26);
따라서 우리는 admin을 2번 인코딩 한 값을 id값으로 넣어주면 된다.
인코딩 1번 %61%64%6d%69%6e 인코딩 2번 %2561%2564%256d%2569%256e -> preg_match()가 두 번째 조건문보다 위에 위치하기 때문에 %2561%2564%256d%2569%256e이 디코딩 된 %61%64%6d%69%6e값은 admin과 다르기 때문에 걸리지 않게 되고, 아래 조건문의 urldecode에 의해 admin으로 디코딩되며 문제가 풀리는 것이다.
정리
이중 인코딩(Double Encoding)
: 동일한 인코딩 체계(URL Encoding)를 이용하여 이중으로 인코딩한 것을 의미한다. 일반적으로 사용자 입력을 가로채는 권한 부여 첵께나 보안 필터를 우회하는 공격 기법으로 사용된다.웹 서버와 브라우저 사이에서 데이터를 교환할 때, 브라우저는 <form>에서 입력 받은 데이터를 자동으로 인코딩한 값으로 보내고, php는 자동으로 디코딩 하여 해석한다.
-> 슈퍼 글로벌 변수는 단순히 디코딩된 데이터를 제공할 뿐이다.'PRIVATE > webhacking.kr' 카테고리의 다른 글
old-16 (0) 2025.01.02 old-15 (0) 2024.12.31 다음글이 없습니다.이전글이 없습니다.댓글