문제에 접속하면 내 ip와 agent를 보여주고 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>";
}
?><hr>
이렇게 되어있다. 한번 분석해보자
소스코드 분석
extract($_SERVER);
extract($_COOKIE);
- $_SERVER과 $_COOKIE의 배열들을 변수화함.
extract(배열) : 배열 속의 키값들을 변수화하는 함수
배열은 키와 값으로 이루어져 있는데, $data = array("name"=>"Alice","age"=>30)란 값이 있으면
extract($data)를 하여 $name(키) = Alice, $age(값) = 30이라는 변수들을 생성한다.
$ip = $REMOTE_ADDR;
$agent = $HTTP_USER_AGENT;
- 사용자의 ip와 브라우저 등에 관한 정보들을 변수에 저장함
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);
}
- 특수문자를 html 엔티티로 변환한 뒤 $ip에 저장된 값을 바꾼다.("12" -> "")
htmlspecialchars() : 특수문자를 html 엔티티로 변환함.
예를 들어 < > 는 HTML 태그의 시작과 끝을 나타내는데, 이를 문자열로 표현하고자 할 때 사용하는 것이다.
쉽게 말해 특수문자를 그대로 출력하는 것이다.
또한 XSS공격을 막아주는 기능도 있는데 이는 나중에 나오면 다시 알아보도록 하자
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>";
- 위와 같이 $agent에 저장된 값을 html 엔티티로 변환한다.
- 첫 화면에 나온 것처럼 사용자의 ip, 정보들을 출력한다.
if($ip=="127.0.0.1"){
solve(24);
exit();
}
else{
echo "<hr><center>Wrong IP!</center>";
}
?><hr>
- 만약 사용자의 ip가 127.0.0.1이면 문제가 해결되고 그렇지 않으면 Wrong IP! 를 출력한다.
이제 분석을 다 했으니 한번 풀어보자.
이 문제의 관건은 내 ip를 127.0.0.1로 바꾸는 것이다.
그래서 어떻게 하지 고민하던 중 생각난 것이 바로 쿠키이다.
위에서 보면 쿠키를 추출하는데 키와 값을 변수와 변수의 값으로 가져오는 것을 알 수 있다.
그렇다면 내가 임의로 쿠키를 넣는다면..?
$ip는 $REMOTE_ADDR값을 불러오는데, 위에서 추출할 때 $REMOTE_ADDR이란 변수를 가져오기 때문에(쿠키에 임의로 넣은 것) 이것이 덮어써진다!
물론 이렇게 작성한다면 str_replace에 막히기 때문에
112277...00...00...1 로 작성하면 뚫을 수 있다(삽질해서 찾아냄..).
더보기
뚫리는 이유
str_replace()에선 특수한 문자를 다른 문자로 바꾸는데,
이 코드에선 | .. | 12 | 7. | 0. | 를 각각 | . | (공백) | (공백) | (공백) | 으로 바꾼다.
그러면 다시 돌아와서
112277...00...00...1 을 입력하면 str_replace()에 의해
112277...00...00...1 이 된다.(드래그로 확인가능)
문제 해결 :)
날씨가 많이 추워졌네요
다들 따뜻하게 입으시고 감기 조심하세요!
"건강은 제일의 재산이다." - 에머슨
'Webhacking.kr' 카테고리의 다른 글
[Webhacking.kr] Challenge 10 (1) | 2024.11.17 |
---|---|
[Webhacking.kr] Challenge 18 (2) | 2024.11.08 |
[Webhacking.kr] Challenge 39 (0) | 2024.10.11 |
[Webhacking.kr] Challenge 12 (0) | 2024.10.10 |
[Webhacking.kr] Challenge 26 (0) | 2024.10.08 |