WAR GAME/Nebula

[Exploit-Exercises: Nebula] level07 풀이

jir4vvit 2020. 6. 29. 15:28

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

* level07

ID: level07

PW: level07

 

문제07

flag07 계정 사용자는 웹 서버에서 호스트에 연결할 수 있는지 확인하기 위해 ping을 할 수 있는 첫 번째 perl 프로그램을 작성하고 있었다.

이 level을 해결하려면 level07 계정으로 로그인해라. 이 단계의 파일은 /home/flag07에서 찾을 수 있다.

 

 

문제에서 제공해 준 코드

일단 문제에서 계정 flag07 사용자가 ping 테스트를 하기 위해 첫 번째 perl 프로그램을 작성했다고 한다.

 

ping 테스트 : 어떤 시스템과 네트워크 상에서 통신이 가능한지 안한지 여부를 테스트 하는 것.

단순하게 통신 가능 여부를 테스트 할 뿐이지만 테스트하는 장치가 죽었는지 살았는지 확인이 가능하다.

 

 

perl 스크립트 : perl이란 프로그래밍 언어. 그냥 편하게 perl이라는 언어로 스크립트를 작성했다고 생각하면 된다.

 


이제 .. 문제를 풀어보도록 하겠다.

개인적으로 모르는 개념들이 많아서 힘들었다.

 

저기에 문제에서 제공해준 코드인 index.cgi가 보이고, thttpd.conf가 보인다.


thttpd.conf부터 살펴보자.

 

thttpd.conf

d는 데몬을 뜻한다.

맨 앞의 t는 trival 이라고 사소한.. 간단한을 뜻한다.

즉 thttpd는 간단한 http 프로토콜을 지원하는 서비스이다.

그리고 여기 아래 제시된 건 이런 서비스를 구동할 때 사용되는 설정파일이다.

level07@nebula:/home/flag07$ cat thttpd.conf
# /etc/thttpd/thttpd.conf: thttpd configuration file

# This file is for thttpd processes created by /etc/init.d/thttpd.
# Commentary is based closely on the thttpd(8) 2.25b manpage, by Jef Poskanzer.

# Specifies an alternate port number to listen on.
port=7007

# Specifies a directory to chdir() to at startup. This is merely a convenience -
# you could just as easily do a cd in the shell script that invokes the program.
dir=/home/flag07

# Do a chroot() at initialization time, restricting file access to the program's
# current directory. If chroot is the compiled-in default (not the case on
# Debian), then nochroot disables it. See thttpd(8) for details.
nochroot
#chroot

# Specifies a directory to chdir() to after chrooting. If you're not chrooting,
# you might as well do a single chdir() with the dir option. If you are
# chrooting, this lets you put the web files in a subdirectory of the chroot
# tree, instead of in the top level mixed in with the chroot files.
#data_dir=

# Don't do explicit symbolic link checking. Normally, thttpd explicitly expands
# any symbolic links in filenames, to check that the resulting path stays within
# the original document tree. If you want to turn off this check and save some
# CPU time, you can use the nosymlinks option, however this is not
# recommended. Note, though, that if you are using the chroot option, the
# symlink checking is unnecessary and is turned off, so the safe way to save
# those CPU cycles is to use chroot.
#symlinks
#nosymlinks

# Do el-cheapo virtual hosting. If vhost is the compiled-in default (not the
# case on Debian), then novhost disables it. See thttpd(8) for details.
#vhost
#novhost

# Use a global passwd file. This means that every file in the entire document
# tree is protected by the single .htpasswd file at the top of the tree.
# Otherwise the semantics of the .htpasswd file are the same. If this option is
# set but there is no .htpasswd file in the top-level directory, then thttpd
# proceeds as if the option was not set - first looking for a local .htpasswd
# file, and if that doesn't exist either then serving the file without any
# password. If globalpasswd is the compiled-in default (not the case on Debian),
# then noglobalpasswd disables it.
#globalpasswd
#noglobalpasswd

# Specifies what user to switch to after initialization when started as root.
user=flag07

# Specifies a wildcard pattern for CGI programs, for instance "**.cgi" or
# "/cgi-bin/*". See thttpd(8) for details.
cgipat=**.cgi

# Specifies a file of throttle settings. See thttpd(8) for details.
#throttles=/etc/thttpd/throttle.conf

# Specifies a hostname to bind to, for multihoming. The default is to bind to
# all hostnames supported on the local machine. See thttpd(8) for details.
#host=

# Specifies a file for logging. If no logfile option is specified, thttpd logs
# via syslog(). If logfile=/dev/null is specified, thttpd doesn't log at all.
#logfile=/var/log/thttpd.log

# Specifies a file to write the process-id to. If no file is specified, no
# process-id is written. You can use this file to send signals to thttpd. See
# thttpd(8) for details.
#pidfile=

# Specifies the character set to use with text MIME types.
#charset=iso-8859-1

# Specifies a P3P server privacy header to be returned with all responses. See
# http://www.w3.org/P3P/ for details. Thttpd doesn't do anything at all with the
# string except put it in the P3P: response header.
#p3p=

# Specifies the number of seconds to be used in a "Cache-Control: max-age"
# header to be returned with all responses. An equivalent "Expires" header is
# also generated. The default is no Cache-Control or Expires headers, which is
# just fine for most sites.
#max_age=
level07@nebula:/home/flag07$

#은 주석을 뜻한다.

 

대충 보면서 문제 풀면서 알아야할 부분(?)을 보겠당...

# Specifies an alternate port number to listen on.
port=7007

# Specifies a directory to chdir() to at startup. This is merely a convenience -
# you could just as easily do a cd in the shell script that invokes the program.
dir=/home/flag07

첫 번째 문단(?)은 7007번 포트로 접속하라는 의미고 두 번째 문단은 초기에 접속이 될때 디렉토리가 /home/flag07로 설정이 된다는 뜻이다.

 

# Specifies what user to switch to after initialization when started as root.
user=flag07

이 부분이 가장 중요하다고 생각이된다.

계정이 flag07로 설정되는 부분이다.

 


이제 문제에서 제공해 준 코드, index.cgi를 살펴보자..

 

 

CGI (Common Gateway Interface)
서버와 웹 어플리케이션과 데이터를 동적으로 주고받기 위한 기술
이 기술이 적용된 프로그램을 cgi 프로그램이라고 한다
jsp, perl 등, 백엔드에서 사용될 수 있는 컴퓨터 언어이다.

 

맨 아래 빨간색 네모의 ping(param("Host")); 부터 살펴보자.

얘는 Host란 글자를 param이라는 함수에 넣어서 서버로 보낸다는 뜻이다.

param이라는 함수는 위에 use한 CGI 모듈 내부에 정의되어 있는 함수이다.

더 자세하게 말하면 GET이나 POST 방식으로 전달되는 파라미터를 받아올 수 있는 함수이다.

 

여기서 GET을 보고 느낀점이 서버로 접속해서 쿼리스트링으로 Host 변수에 url을 적으면 그 url에 대하여 ping 테스트를 하지 않을까 싶었다. ping 테스트를 한다는 것은 저기 파란색 네모 코드 부분을 보고 알았다.

 

@output = `ping -c 3 $host 2>&1`;

먼저 ` `안의 것은 명령이라는 것을 뜻하고, 저기 안에 정의된 명령이 실행되어 output 배열에 담긴다는 뜻이다.

$host에게 3번의 ping을 보내겠다는 뜻이다. (처음의 윈도우 cmd창에서 확인했듯이 보통 4번 보낸다.)

output은 배열인데 파란색 네모 바로 아래의 foreach문을 살펴보면 이것은 아까 윈도우 cmd창에서 라인이 4줄 나타난 것처럼 print함수로 출력을 하겠다는 뜻이다.

 

위 아래의 html코드를 보면 아 ㄹㅇ 화면에 띄워지겠구나.. 이란 것을 알 수 있다.

 

2>&1 부분은 파일 디스크립터 부분이라고 한다.

사실 이 부분은 잘 모르겠다 ㅠㅠ

2는 표준 에러를 뜻하고, 1은 표준 출력을 뜻한다.

내 생각엔 에러들을 출력한다는 뜻 같다... 

 


여기서 취약점은 빨간색 네모처럼 사용자로부터 값을 받아왔는데 필터링이 전혀 되지 않고 파란색 네모처럼 실행이 되고 있다는 뜻이다.

 

그래서 두개의 명령어가 실행되게 하는 커맨드 인젝션(Command Injection)을 사용해보았다.

 

 

위의 url 부분을 살펴보면

 

? 뒤에 Host에 ;getflag를 적어줌으로서 커맨드 인젝션을 수행했다는 것을 볼 수 있다.

; 대신에 %3B라고 적은 이유는 url 인코딩 때문이다.

 

저 쿼리스트링을 실행(?)하게 되면 아까 설정파일에서 봤다시피 계정이 flag07로 전환이 되기때문에 flag07 계정으로 getflag가 실행이 되었다고 생각할 수 있다.

 

 

 

 

 

어렵다.. 복습 열심히 하자...