https://webhacking.kr/challenge/bonus-4/
내 ip와 정보에 대해 나온다. wrong ip라고 한다. 소스코드를 보면서 풀어보자.
<?php
extract($_SERVER);
extract($_COOKIE);
$ip = $REMOTE_ADDR;
$agent = $HTTP_USER_AGENT;
if($REMOTE_ADDR){
$ip = htmlspecialchars($REMOTE_ADDR);
$ip = str_replace("..",".",$ip);
$ip = str_replace("12","",$ip);
$ip = str_replace("7.","",$ip);
$ip = str_replace("0.","",$ip);
}
if($HTTP_USER_AGENT){
$agent=htmlspecialchars($HTTP_USER_AGENT);
}
echo "<table border=1><tr><td>client ip</td><td>{$ip}</td></tr><tr><td>agent</td><td>{$agent}</td></tr></table>";
if($ip=="127.0.0.1"){
solve(24);
exit();
}
else{
echo "<hr><center>Wrong IP!</center>";
}
?>
중요해보이는 php 코드만 긁어왔다.
$ip의 값이 127.0.0.1과 같다면 문제는 풀리게 된다.
우선 extract()함수에 대해서 알아보자.
extract()함수는 연관배열을 넣으면 키와 밸류로 변수를 만들어준다. 예를 들어보겠다.
$연관배열=array("과일1"=>"사과","과일2"=>"바나나")
다음과 같은 배열이 있다.
extract($연관배열)을 한다면
과일1이라는 변수와 과일2라는 변수에 사과와 바나나라는 값이 들어간 변수가 선언된다.
위 문제에서는 $_SERVER를 넣었다.
$_SERVER는 php에서 미리 정의된 서버 변수이다. 현재 스크립트와 웹 서버간의 상호작용과 관련된 정보를 제공하는 배열이다.
다음과 같은 정보를 제공한다.
- $_SERVER['PHP_SELF']: 현재 실행 중인 스크립트의 파일 경로와 파일명을 나타냅니다.
- $_SERVER['SERVER_ADDR']: 서버의 IP 주소를 나타냅니다.
- $_SERVER['SERVER_NAME']: 서버의 호스트 이름을 나타냅니다.
- $_SERVER['SERVER_SOFTWARE']: 서버가 사용하는 소프트웨어의 이름과 버전을 나타냅니다.
- $_SERVER['REQUEST_METHOD']: 클라이언트로부터 요청된 HTTP 메서드를 나타냅니다(GET, POST, 등).
- $_SERVER['QUERY_STRING']: URL의 쿼리 스트링을 나타냅니다.
- $_SERVER['HTTP_HOST']: 클라이언트로부터 받은 Host 헤더 값을 나타냅니다.
- $_SERVER['HTTP_USER_AGENT']: 클라이언트의 브라우저나 사용자 에이전트에 대한 정보를 나타냅니다.
- $_SERVER['REMOTE_ADDR']: 클라이언트의 IP 주소를 나타냅니다.
- $_SERVER['REQUEST_URI']: 클라이언트가 요청한 URI(Uniform Resource Identifier)를 나타냅니다.
문제 풀이에 사용되는 것은 REMOTE_ADDR만 써도 풀어지므로 REMOTE_ADDR만 언급하겠다.
REMOTE_ADDR은 클라이언트의 IP주소를 나타낸다. extract($_SERVER)와 같이 extract함수를 실행했으므로
REMOTE_ADDR= 내 아이피 주소
와 같은 변수가 선언됐다.
이후에 $_COOKIE도 extract()함수에 넣어 실행시킨다. 여기서 취약점이 발생한다.
extract(array &$array, int $flags = EXTR_OVERWRITE, string $prefix = "")
extract()의 기본적인 형식은 다음과 같다. $prefix는 특수한 경우에만 사용하므로 넘어가도록하겠다.
여기서 말하는 $flags는 변수 충돌이 있을 경우에 어떻게 대응할지를 말한다. 덮어쓰기, 스킵 등등의 방법으로 대응을 할 수 있는데 기본적인 설정은 덮어쓰는 것이다. 링크 첨부하겠다. 참고하자.
https://www.php.net/manual/en/function.extract.php
다시 말해서 우리가 cookie로 REMOTE_ADDR의 키를 가진 연관 배열을 만들어준다면 우리의 주소가 담긴 REMOTE_ADDR은 덮어쓰여지게 된다.
쿠키 설정하기 전에 필터링에 대해 짚고 넘어가자.
if($REMOTE_ADDR){
$ip = htmlspecialchars($REMOTE_ADDR);
$ip = str_replace("..",".",$ip);
$ip = str_replace("12","",$ip);
$ip = str_replace("7.","",$ip);
$ip = str_replace("0.","",$ip);
}
우리는 127.0.0.1을 넣어야하는데 다음과 같이 빈 문자열로 치환하고있다. 반복문 없이 빈 문자열로 1번만 치환하고 있다. 또한 ..을 .으로 치환하니 .을 한번 더 넣어주어야한다.
112277...00...00...1
다음과 같이 우회해주자.
이제 이 값을 쿠키로 만들어주자.
관리자 도구에서 Application을 통해 쿠키를 만들 수 있다.
다음과 같이 만들어주자.
이후 새로고침을 해주면
짜자잔
요약
-extract()함수를 사용함에 있어서 발생한 취약점이다. extract($_SERVER) 이후에 extract($_COOKIE)가 위치해 있어서 $REMOTE_ADDR의 값을 변조할 수 있었다.
공격에 대한 방어
-extract($_SERVER)의 위치와 extract($_COOKIE)의 위치를 바꿔준다면 해당 공격을 방지할 수 있을 것이다.
'웹 해킹 > webhacking.kr' 카테고리의 다른 글
[Webhacking.kr] old - 38 풀이 (0) | 2023.08.23 |
---|---|
[webhacking.kr] old - 61 풀이 (0) | 2023.07.20 |
[Webhacking.kr] old - 39 풀이 (0) | 2023.07.14 |
[webhacking.kr] Challenge 16 풀이 (0) | 2023.07.14 |
[webhacking.kr] old - 26 풀이 (0) | 2023.06.27 |