WAR GAME/Nebula

[Exploit-Exercises: Nebula] level09

jir4vvit 2020. 7. 6. 15:25

환경설정 : iso 파일을 이용하여 서버를 연 후, cygwin을 이용하여 ssh로 서버에 접속함.

* level09

ID: level09

PW: level09

 

문제09

취약한 PHP 코드에 대한 C setuid wrapper가 있는데…

이 level을 통과하려면 level09계정으로 로그인해라. 이 level의 파일은 /home/flag09에서 찾을 수 있다.

 

문제에서 제공해 준 코드

php 파일을 제공해주고 있다...

 


/home/flag09로 이동해서 살펴보았다.

flag09와 flag09.php가 보인다.

flag09가 flag09의 계정으로 setuid가 걸린 파일처럼 보인다.

 

file 명령으로 flag09 파일과 flag09.php 파일이 무슨 파일들인지 살펴보았다.

flag09는 setuid가 걸린 실행파일이었고, flag09.php는 php 스크립트 파일이었다.

 

 

일단 flag09를 실행할 수 있으니까 무작정 실행시켜보았다.

PHP Notice와 PHP 경고가 떴다. flag09.php과 관련있을 것 같아 flag09.php를 살펴보았다.

 

 

flag09.php

notice와 warning이 뜬 22번째와 13번째 줄을 살펴보았다.

그냥 실행할 때 인자값 두개를 같이 넣어서 실행시켜야하는데 인자값 없이 실행시켜서 저 경고들이 나왔다.

첫번째 인자값으로 어떤 file을 생상하여 filename을 넣어주고 두번째 인자값으로 use_me(?)를 넣어주도록 하겠다.

 


아 그런데 이 문제를 풀려면 flag09의 권한으로 getflag를 발동시켜야하는데 어떻게 발동시키지?? 

일단 flag09의 권한은 flag09계정으로 setuid가 걸린 flag09를 실행시키면서 잠시 flag09의 권한으로 바꿀 수 있다.

뭔가 php코드 안,.. 인자값... 등등을 이용하여 getflag명령을 발동시켜야할 것 같다는 생각이 들었다.


다시 돌아와서 filename과 use_me(?)를 넣어줘야하는데 어떤 file의 name을 넣어줘야하는 것일까?

 

  • $contents = preg_replace("/(\[email (.*)\])/e", "spam(\"\\2\")", $contents);

15번째줄의 이 부분이 수상하다고 생각되었다. 

preg_replace와 /e인 e modifier가 문제인 것 같다. PHP 버전 5.5.5이상부터는 저게 사용이 되지 않는다. preg_replace_callback함수를 사용하도록 권장하고 있다. 

 

  • preg_replace("[패턴]" , "[바꿀 패턴]" , "[바꿀 문장]");

그냥 문자들을 필터링하는 함수이다. $contents는 [패턴]에 따른 문자열을 만족하는데 이를 [바꿀 패턴]에 따라 바꾸어준다.

 

e modifier가 왜 위험하냐면 이는 [바꿀 패턴]를 php 코드 그대로 해석하기 때문이다.

원래는 [바꿀 패턴] 부분에 문자열이 오는데, e modifier는 [바꿀 패턴]을 php 코드 그대로 해석하기 때문에 정확히는 저 spam 함수의 리턴값이 [바꿀 패턴]에 들어가게 된다. 또한 e modifier에서는 spam의 매개변수인 \2, 즉 역참조 문자를 사용할 수 있다. 

 

아래 사이트에서 정규표현식을 테스트해볼 수 있다.

https://regexr.com/

 

RegExr: Learn, Build, & Test RegEx

RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

regexr.com

 

먼저 [패턴]에 해당하는 (\[email (.*)\])는 위의 포맷을 만족한다. 

"[email"은 반드시 와야하고 이 문자 하나고 *이 문자가 0회 이상 나타낸다.  "]"도 반드시 와야한다.

 

그럼 이제는 spam의 매개변수인 \2, 즉 역참조 문자열이 무엇인지 알아보자.

 

 

차이가 보이는가? 

"(" , ")" 로 묶이면 그룹을 뜻하는데 \1은 첫번째 그룹이 뒤에 한번 더 반복되고, \2은 두번째 그룹이 뒤에 한번 더 반복된다. 

 

위의 코드에서는 \2이므로, 두번째 그룹이 해당이 되게 된다. test@test.test가 spam 함수의 매개변수로 들어가게 된다.


일단 테스트를 해보기로 했다.

/tmp/test가 markup의 preg_replace 안의 spam함수에 잘 들어가서 치환이 어쩌구저쩌구 잘 된 것을 살펴볼 수 있다.

 

/tmp/test파일의 내용을 잘 조작하면 문제를 풀 수 있을 것 같다.

 

/tmp/test의 내용을 아래처럼 고쳐주고 실행시켜보았다.

  • [email {${system("getflag")}}]

하지만 아래의 오류로 보아 ""가 막혀있다는 것을 알 수 있었다. 참고로 system함수는 php파일 안에서도 os에 해당하는 커맨드 명령어(외부명령어)를 실행시키게 할 수 있는 함수이다.

 

 

/tmp/test의 내용을 사진처럼 고쳐주었다.

 

hello라고 적은 부분에 저런 명령어는 존재하지않는다고 이야기하고 있다. 그럼 저기에 getflag를 적으면 되지 않을까?

 

 

성공적으로 getflag를 발동시켰다고 말해주고있다!!!

 

 

 

개인적으로 이 문제 이해하는데 오래걸렸다 ㅠㅠ 찝찝해 나중에 다시 더 봐야겠다.

level10으로 가즈아ㅏ 드뎌 두자리 수 레벨이당..