본문 바로가기

WarGame/webhacking.kr

[webhacking.kr] Challenge 44 :: Command Injection 2



Summary

  • Command Injection을 사용하여 디렉터리 리스트를 확인해야 합니다.
  • Chaining Operators에는 어떤것들이 있을까요?
  • Linux에서 Single Quotes(')와 Double Quotes(")의 차이는 무엇일까요?



Challenge 44는 다음과 같습니다.



name Form에서 "html" Parameter를 POST방식으로 보낸 다음, META Tag를 이용하여 index/go.html으로 Redirection하고 "hello [Input Value]"를 출력하고 있습니다. 그런데 Redirection 과정에서 HTTP Request/Response를 보면 아무런 값을 넘기지 않고 있습니다. 아무런 값을 받지 않았는데 어떻게 Input Value를 출력할 수 있을까요?. 이 부분에서 많은 의구심을 품었는데요. 결국 스스로 이 문제가 Command Injection 관련 문제라는 것을 알아내지는 못 했습니다. 다른 분에게 힌트를 얻어서 Command Injection 관련 문제라는 것을 알 수 있었습니다.


Input Field의 maxlength를 조절하여 5글자 이상의 문자열을 보내도 실제 출력될 때는 5글자만 출력되는 것을 보실수 있는데요. Sever-Side에서 substr() 등으로 문자열을 짜르는 것으로 추측할 수 있습니다. 그렇기 때문에 5글자 안에서 문제를 푸셔야 합니다.


위 사항들을 토대로 소스를 예측해 보면 다음과 같습니다.


1
2
3
4
<?
$html = substr($_POST[html],0,5);
system("echo 'hello $html' > index/go.html");
?>
cs

보통 Command Injection을 하기 위해서 Chaining Operators로 ";"(세미콜론)을 많이 사용하는데요. 이 문제에서는 세미콜론이 필터링되어 있습니다. 그렇기 때문에 다른 Chaining Operators를 사용해야 합니다. 자세한 Chaining Operators에 대한 설명은 해당 블로그를 참고하시기 바랍니다. (http://www.tecmint.com/chaining-operators-in-linux-with-practical-examples/)


본 문제에서는 백그라운드로 명령어를 실행시킬 수 있는 "&"를 사용하여 풀도록 하겠습니다. 따라서 &ls라고 입력하면 백그라운드로 ls가 실행되면서 디렉터리 리스트가 출력되야 하는데, 출력이 되지 않습니다. "ls"도 필터링되어 있는 것 입니다.


이것을 우회하기 위해 Single Quotes를 사용하였습니다. 리눅스 Shell Script를 제작해 보신 분들은 Single Quotes와 Double Quotes의 차이에 대해서 어느 정도 알고 계실 텐데요. 자세한 설명은 해당 블로그를 참고하시기 바랍니다.(http://www.howtogeek.com/howto/29980/whats-the-difference-between-single-and-double-quotes-in-the-bash-shell/)


결국, Single Quotes를 사용하면 String이 분리되는 것이 아니라, 그냥 그 자체로 하나의 문자로 인식하게 됩니다. 이 것을 실제 리눅스에서 진행해 보았습니다.



'l' 이라는 것을 문자 l로 인식하므로, ls 명령어가 실행되는 것 입니다. 이것을 이용하여 다음과 같은 결과를 만들 수 있습니다.



싱클쿼터로 감싼 'hello '가 출력되고 백그라운드로 실행된 ls 명령어가 go.html 파일로 Write되었습니다. 

그러나 이와 같이 쿼리를 전송하면 문제가 풀리지 않습니다. 이것은 싱글쿼터의 위치 때문인데요. 다시 한번 추측한 소스코드를 가지고 설명하겠습니다.


1
2
3
4
5
<?
원본 : system("echo 'hello $html' > index/go.html");
변경 : system("echo 'hello '&'l's' > index/go.html");
최종 : system("echo 'hello '&l's' > index/go.html");
?>
cs


2번 라인의 추측한 원본 코드를 보시면 echo 다음에 싱글쿼터로 둘러쌓여 있는 것을 보실수 있습니다. 그렇기 때문에 무슨 명령어를 입력해도 리눅스에서의 싱글쿼터 속성 때문에 명령어가 아닌 문자열로 인식하게 됩니다. 따라서 싱글쿼터의 조작이 필요합니다. 만약 3번라인에서와 같이 &'l's 이런식으로 만든 다면 뒤에 있는 마지막 싱글쿼리와 쌍을 이룰 수 없게 됩니다. 최종적으로 4번 라인과 같이 만들어주면 Challenge를 성공시킬 수 있습니다.