[침투 테스팅] HackTheBox - Popcorn : Web Shell 업로드를 이용한 내부 침투

2022. 1. 10. 10:03Penetration Testing/Medium

NMAP 스캐닝 결과

 

SSH 서버와 웹 서버가 열려있다.  이외에도 운영체제가  Ubuntu라는 것을 확인, 정확한 OS 정보는 웹 서버를 탐색하면서 더 자세히 얻을 수 있는 경우가 많다.

 

 

 

 

 

Openssh 관련 취약점 검색

 

Searchsploit을 통해 취약점을 검색해보았지만 별다른 내용을 확인할 수 없었다. 일단 대부분 Username Enumeration이라 지금 당장 큰 도움은 되지 않을 것 같고 중간에 있는 Command Execution 관련 취약점은 CVE도 안붙었고 자세한 내용을 찾을 수 없었다. 

 

웹에서 취약점을 찾아보고 공격 벡터가 발견되지 않는다면 Command Execution 관련 취약점을 찾아보던가 Username Enumeration과 Brute Force를 연계한 공격을 시도하는 것으로 하고 일단은 넘어가자.

 

 

 

 

 

웹 접속 시도

일단 기본 페이지에 아무것도 있지 않다. 이런 경우 웹 서버만 열려있고 실제 서비스를 하고 있지 않은 것 처럼 보이지만 실제로는 다른 디렉토리에서 서비스가 동작하는 경우가 많으므로 Brute Force로 숨겨진 디렉토리를 검색해야된다.

 

보통은 Kali linux의 기본적으로 설치되어있는 Dirb 라는 도구를 이용하지만 해당 도구는 상당히 느려서 gobuster라는 도구를 이용하는 것을 추천한다.

sudo apt-get install gobuster

 

sudo gobuster dir --url http://10.10.10.6/ --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -z

다음과 같은 명령어로 실행할 수 있다. Wordlist는 Kali Linux의 Dirb가 이용하는 리스트를 그대로 사용했다. 약 22000개의 단어가 있어서 웬만하면 주요 디렉토리를 모두 찾을 수 있다.

 

/index                (Status: 200) [Size: 177]
/test                 (Status: 200) [Size: 47034]
/torrent              (Status: 301) [Size: 310] [--> http://10.10.10.6/torrent/]
/rename               (Status: 301) [Size: 309] [--> http://10.10.10.6/rename/]

디렉토리 Brute Force 결과는 다음과 같다.  이제 해당 페이지에 접속해서 공격 벡터가 될 수 있는 서비스가 동작하고 있는지를 확인하면 된다.

 

 

 

 

 

/test 페이지

먼저, 가장 사이즈도 크고 이름도 수상한 test 페이지에 접속한 결과다. 해당 서버에 대한 OS, API 정보 수호신?들을 확인 할 수 있다. 공격과 관련한 중요한 서버 정보를 찾을 수 있다는 점에서 좋은 수확이지만 해당 페이지를 통해 실질적인 공격이 이루어질 수 있을 것 같아보이지는 않는다.

 

 

 

 

 

/torrent 페이지

실제로 웹 콘텐츠가 운영되고 있는 곳은 바로 /torrent 페이지였다. 토렌트관련 서비스인 것으로 추정되며 Upload 버튼이 있는 것으로 보아 파일 업로드 관련 공격을 수행할 수 있을 것 같다. 이외에도 로그인 페이지가 있다 이곳에서 Sql injection을 시도해본 결과 오류 메시지를 통해 SQL 문이 노출된다는 것을 확인하였다.

 

can't execute query

	SELECT userName, password, privilege, email
	FROM users
	WHERE userName = 'a' or 1=1;--' AND password = 'c4ca4238a0b923820dcc509a6f75849b'

패스워드 입력 부분에서는 아무 일도 일어나지 않았지만 로그인 입력 부분에서 Sql Injection을 시도하려 할경우 다음과 같은 오류 메시지가 있는 페이지로 이동된다. Password = ' 앞에 있는 값은 사용자가 패스워드 입력 부분에 입력한 값을 해쉬화 것 같다.

Hash length: 32
Byte length: 16
Bit length:  128

Based on the length, this hash could have been generated by one of the following hashing functions:
MD5
MD4
MD2
HAVAL-128
RIPEMD-128
Snefru
Tiger-128

Dreamhack Tools를 이용하여 해당 hash를 분석해보았다. 해당 해쉬 값에 대응하는 입력 값이 '1' 이었으므로 해쉬화를 통해 해당 해쉬가 정확인 어떤 해쉬인지 확인하는 과정이 필요할 것 같다. 

 

MD5를 이용하여 '1'을 해쉬화하니 동일한 값이 나왔다. 이를 통해 이 웹 서비스에서 이용하는 해쉬가 MD5라는 정보를 얻어냈다.

 

 

또한 /torrent가 실제 서비스가 존재하는 페이지라는 것을 알아냈으니 해당 디렉토리에 대해서도 Brute Force를 해야된다.

sudo gobuster dir --url http://10.10.10.6/torrent --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -z

똑같이 gobuster 도구를 통해 디렉토리를 찾아주자.

 

/index                (Status: 200) [Size: 11356]
/download             (Status: 200) [Size: 0]    
/images               (Status: 301) [Size: 317] [--> http://10.10.10.6/torrent/images/]
/rss                  (Status: 200) [Size: 964]                                        
/login                (Status: 200) [Size: 8367]                                       
/templates            (Status: 301) [Size: 320] [--> http://10.10.10.6/torrent/templates/]
/users                (Status: 301) [Size: 316] [--> http://10.10.10.6/torrent/users/]    
/admin                (Status: 301) [Size: 316] [--> http://10.10.10.6/torrent/admin/]    
/health               (Status: 301) [Size: 317] [--> http://10.10.10.6/torrent/health/]   
/browse               (Status: 200) [Size: 9278]                                          
/comment              (Status: 200) [Size: 936]                                           
/upload               (Status: 301) [Size: 317] [--> http://10.10.10.6/torrent/upload/]   
/css                  (Status: 301) [Size: 314] [--> http://10.10.10.6/torrent/css/]      
/edit                 (Status: 200) [Size: 0]                                             
/lib                  (Status: 301) [Size: 314] [--> http://10.10.10.6/torrent/lib/]      
/database             (Status: 301) [Size: 319] [--> http://10.10.10.6/torrent/database/] 
/secure               (Status: 200) [Size: 4]                                             
/js                   (Status: 301) [Size: 313] [--> http://10.10.10.6/torrent/js/]       
/logout               (Status: 200) [Size: 182]                                           
/preview              (Status: 200) [Size: 28104]

결과는 다음과 같다. 여기서 엄청난 정보를 찾을 수 있었는데 /database 페이지에 접근할 경우 데이터베이스 관련 sql 파일을 열람할 수 있었다.

 

 

 

 

 

/torrent/database

 

/torrent/database/th_database.sql

 

이곳에서 admin 계정을 생성하는 구문을 찾아냈으며 심지어 해당 구문에는 admin 계정의 패스워드 정보까지 있다..! 비록 해당 정보는 해쉬화되어 있지만 우리는 위 과정에서 해당 웹 서비스가 이용하는 해쉬가 MD5라는 것을 알아내었고 MD5는 쉽게 크래킹이 가능하다. 

1844156d4166d94387f1a4ad031ca5fa

< MD5 Decrytion >

admin12

인터넷에 여러 MD5 크랙 사이트가 존재하므로 이를 이용하면 쉽게 Admin 계정의 비밀번호를 탈취할 수 있다.

 

하지만 안타깝게도 현재 Admin 계정의 비밀번호는 admin12가 아니었다. 해당 데이터는 당연히 현재 데이터가 아니기 때문에 과거 Admin 계정이 admin12 였을 수도 있게다고 추측할 수 있을 뿐, 여기서 더이상 진행할 수 있는 부분이 없다.

 

 

그렇다면 Upload를 이용한 공격을 시도해보자. /torrent 페이지에서 해당 웹 서비스에 업로드 기능이 있다는 것을 알아내었고 해당 사이트에 사용자로 로그인만 한다면 이 업로드 기능에 접근 할 수 있다.

 

 

 

 

 

/torrent/torrents.php?mode=upload

 

/torrent 페이지에서 Uplaod 버튼을 누르면 업로드 페이지에 접근이 가능하다. 일단 PHP로 제작된 Reverse Shell을 업로드 해보았다. 이 경우 This is not a valid torrent file. 이라는 메시지와 함께 업로드가 막힌다.

 

그렇다면 정상적인 Torrent 파일을 업로드하여 정상적으로 업로드 되는지 확인해보자 업로드할 파일로는 Kali Linux의 토렌트 파일을 이용하면 될 것 같다.  업로드한 결과 알 수 없는 이유로 /torrent 페이지가 잠깐 멈춰버린다.. 이후 다시 잘 동작하게 되며 확인 결과 Torrent 파일은 잘 업로드 된 것 같다.

 

 

 

 

 

Burp Suite

Burp Suite로 정상 Torrent 파일을 업로드하는 과정을 캡쳐하였다. 이 요청 값을 토대로 PHP 파일을 업로드 했을때의 요청 값을 잘 수정해주시면 파일 검증 시스템을 우회할 수 있을 것 같다.

 

 

 

 

Burp Suite

PHP 파일을 업로드해본 결과 수정할만한 부분은 Content-type 밖에 없었다. Content-Dispsition의 name="torrent" 도 수상했지만 php 파일을 업로드하였을때도 똑같이 Torrent 였다. 하지만 Content-type은 application/php 였기에 해당 부분을 Torrrent 파일 업로드 때와 똑같이 수정해주었다.

 

하지만 이번에도 여전히 This is not a valid torrent file 오류 메시지가 나왔다. 이외에도 이름에 확장자를 넣고 토렌트 파일 중간에 php 코드를 끼워서 보내보아도 결과는 같았다.

 

 

 

 

 

/torrent

다행히도 또 다른 Upload 기능을 찾아냈다. /torrent 페이지 Browse 탭에서 자신이 업로드한 파일을 찾을 수 있는데 여기서 스크린샷 업로드가 가능하다. 다행히도 이곳에서 쉘 업로드가 가능하였다. 기본적으로 위 torrent 파일 업로드 기능 처럼 사용자가 업로드한 파일을 검증하긴 하지만 위와 다르게 image/png로 content-type을 변조할 경우 정상적으로 업로드가 가능하다!

 

 

 

 

 

/torrent/upload

위에서 /torrent 페이지에 대한 디렉토리 Brute Force를 했을때 /upload란 페이지를 발견했었다. 여기에 우리가 업로드한 php 파일이 들어있다. php 파일에 접근하면 Reverse Shell이 실행된다.

 

 

 

 

 

Shell 획득 성공

이것으로 서버 침투 과정을 성공하였다. 하지만 침투한 계정은 www-data이며, 우리는 root 권한이 필요하므로 권한 상승 공격을 통해 root 권한을 얻어야 한다.

 

권한 상승 공격 코드를 검색하는 방법은 여러가지가 있지만 가장 정확한 방법은 피해자의 시스템에서  Linux-exploitation-suggester를 실행하는 것이다.

wget https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh -O les.sh

다음 명령어로 파일을 받을 수 있다.

 

python3 -m http.server

이후 해당 명령어로 간단하게 http 서버를 열어서 피해자의 시스템에서 공격자의 시스템으로 접속할 수 있다. 포트가 80으로 열리지 않으니 꼭 어느 포트로 열렸는지 확인하자. 서버를 열었다면 피해자의 시스템에서 wget 명령어로 Linux-exploitation-suggester를 다운로드 받을 수 있다.

 

이때 반드시 tmp 폴더에서 다운로드 받고 실행해야된다. 그렇지 않으면 권한 거부가 발생할 수도 있다. 

 

 

 

 

 

Linux-exploitation-suggester

피해자의 시스템에서 Linux-exploitation-suggester를 실행하면 이용가능한 CVE를 분석해준다. 굉장히 많이 나오는데 가장 먼저 표시될 수록 가능성이 높으므로 full-nelson이라는 취약점을 이용해서 Exploit 해보도록 하겠다.

 

참고로 그 밑에 있는 Dirty Cow 공격도 통하는 것으로 보인다.

 

Linux-exploitation-suggester이 표시해주는 정보를 보면 친절하게 공격 코드도 제공하고 있으므로 다운받은 다음 위에서 했던 것 처럼 공격자 시스템의 http 서버를 통해 피해자 서버로 파일을 옮기자.

 

 

 

 

 

권한 상승 공격

이렇게 실행만 해주면 즉시 권한 상승 공격이 진행되고 성공적으로 root 계정을 획득할 수 있다. flag는 /root/root.txt에 있다.

 

Medium 문제 치고는 정말 간단하게 풀린다. 아마 스크린샷 업로드 부분을 무시하기 쉬운데다가 Admin 계정관련 함정이 있어서 Easy 문제가 아닌 것 같다.