PHP 버전 7에서 터지는 잘못된 변수명 trick에 대해 알아보자.
이 기법을 제대로 알게 된건 Sekai CTF 2022 WEB문제인 Sekai-game-start를 업솔빙하면서 알게 됐다.
나중에 한번 롸업이나 해당 문제를 분석해볼 것을 추천한다.
PHP에는 변수명에 .(온점)이나 공백등을 _로 처리한다.
그러나 PHP 버전 7에서는변수명에 [ 뒤에 오는 문자열 파싱에 .(온점)이나 공백을 검사하지 않는다.
말로하면 잘 모르겠으니 php7 환경을 구현해서 실습해보자.
FROM php:7.4-apache
COPY ./app /var/www/html
RUN rm /var/log/apache2/access.log /var/log/apache2/error.log /var/log/apache2/other_vhosts_access.log
EXPOSE 80
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
Dockerfile
<?php
highlight_file(__FILE__);
$test1=$_GET['test1_test2.test3'];
$test2=$_GET['test4_test5 test6'];
if(isset($test1)){
echo "ok test1 성공!<br>";
if(isset($test2)){
echo "wow you can use php trick7@@";
}
}
else
die("hmmmm...")
?>php
간단하게 코드를 설명하면 test1_test2.test3란 변수명을 get으로 넘기면 test 1단계를 통과하고
tes4_test5 test6란 변수명이 존재하면 wow you can use php trick7@@가 출력이 된다.
어떻게 하면 될까?
어떻게 할지 설명하기 전에 php 7의 소스코드를 간단하게 보자.
/* ensure that we don't have spaces or dots in the variable name (not binary safe) */
for (p = var; *p; p++) {
if (*p == ' ' || *p == '.') {
*p='_';
} else if (*p == '[') {
is_array = 1;
ip = p;
*p = 0;
break;
}
}https://github.com/php/php-src/blob/787a1730640a8a971ce46b2269a1a88376d61c74/main/php_variables.c#L105-L115
변수명에 공백이나 .(온점) 을 _로 치환한다. 그러나 변수명 [가 있으면 멈춘다.
그럼 이제 한번 풀어보자.
?test1[test2.test3&test4[test5%20test6
이렇게 하면 [가 _로 치환되고 .(온점)과 공백이 치환되지 않아 변수명을 넘길 수 있다!!!

CTF에서 php7에서 변수명에 . (온점)이나 공백이 있을때 사용하는 우회법이다.
참고로 php8에서는 패치했다.

참고 블로그
https://lebr0nli.github.io/blog/security/SekaiCTF-2022/#sekai-game-start-web
SekaiCTF 2022 Writeups
Yet another CTF writeups ;)
lebr0nli.github.io
내가 보고 내가 참고하려고 만든 블로그
틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다.