문제분석 & 풀이
문제에 접속하니 클라이언트 IP 주소 , 클라이언트 에이전트 정보가 나와있다.
소스도 주어져있으니 소스를 봐보도록하자.
소스를 분석하면 다음과 같다.
1. extract() 를 통해 $_SERVER , $_COOKIE 정보를 변수로 선언한다. (2,3번)
2. $ip 변수에 클라이언트 ip, $agent 변수에 클라이언트 에이전트 정보를 넣는다. (4,5번)
3. 클라이언트 ip는 여러번의 replace()를 통해 값을 변환하고 $ip변수에 넣는다. (6~12번)
4. 최종적으로 $ip 변수의 값이 "127.0.0.1"이면 문제가 해결된다.
결론적으로 $ip에 들어갈 값
즉, 클라이언트의 ip값을 "127.0.0.1" 만들어야 한다는 것인데.... 이것은 불가능해보인다.
그렇다면 어떻게 $ip값을 "127.0.0.1"로 만들 수 있을까??
필자는 php의 extract() 함수에 취약점이 있다는 사실을 알아냈다.
extract() 함수의 경우 인자로 받는 객체를 변수로 선언하는 함수인데 3번줄에 보면 쿠키값 또한 변수로 선언하고 있다.
쿠키값의 경우, 우리가 설정해서 값을 전송 할 수 있기 때문에, 우리가 변수를 선언할 수 있다는 것이다!
그렇다면 REMOTE_ADDR 쿠키를 우리가 만들고 값을 설정하면 extract()를 통해 $REMOTE_ADDT 변수가 우리가 원하는 값으로 재선언되고 따라서 최종적으로 실제 클라이언트의 ip값이 $ip 변수로 들어가지 않고 우리가 선언한 변수 값이 들어갈 것이다.
근데 문제는 6~12번 줄을 보면 $REMOTE_ADDR 값이 여러 번의 치환과정을 거치기 때문에 이것까지 고려하여 최종적으로 "127.0.0.1"이 되는 입력값을 만들어야 한다.
최종적으로 "127.0.0.1"이 되는 값을 만들기 위해 필자는 치환과정의 역순으로 값을 하나씩 만들어보겠다.
입력값을 만들기 어려워 할 수도 있는데 쉽게 생각해서 "0." 이 공백으로 치환된다고 가정하면 "0"과 "." 사이에 "0."을 넣으면 된다. 나머지도 이런식으로 값을 만들면 편할 것이다.
이제 112277...00...00...1 이라는 입력값을 완성했으니 개발자도구를 이용해 REMOTE_ADDR이라는 쿠키를 만들어서 이 값을 넣어보자.
만들었으니 이제 새로고침을 해보자!
클리어!!