[SK쉴더스 Rookies 19기] 클라우드 기반 스마트 융합보안 과정
01. File upload vulnerability
파일 업로드 기능에서 파일의 크키/개수/종류를 제한하지 않고 외부에서 접근 가능한 경로에 파일을 저장하는 경우 발생
→
서버의 연결 및 디스크 자원을 고갈시켜 정상적인 서비스를 방해
서버에서 실행 가능한 파일을 업로드해서 실행 - 웹쉘(WebShell)
방어
- 파일의 크기와 개수를 제한
제공 할 서비스에 맞게 적절한 크기와 개수를 정의
- 파일의 종류를 제한
업로드 가능한 파일의 종류를 미리 정의하고 정의된 범위(화이트 리스트)내에서만 업로드를 허용
- 파일을 외부에서 접근할 수 없는 경로에 저장
Web Root 밖에 저장
- 파일의 이름을 외부에서 알 수 없는 형태로 변경해서 알 수 없는 경로에 저장
- 파일의 실행 속성을 제거하고 저장
02. Bee.box - Unrestricted File Upload
low
파일을 업로드 하는 기능
업로드하면 here 부분에 경로가 생김
http://bee.box/bWAPP/images/dog.jpg
외부에서 접근 가능한 경로에
업로드 파일명으로 저장중
PHP기반 웹쉘을 업로드해서 파일 업로드 취약점이 있는 지 확인해보자
칼리에 있는 백도어 파일을 올려보자
업로드 된 웹쉘
실행도 잘 됨
medium
function file_upload_check_1($file, $file_extensions = array("asp", "aspx", "dll", "exe", "jsp", "php"), $directory = "images")
{
$file_error = "";
// Checks if the input field is empty
if($file["name"] == "")
{
$file_error = "Please select a file...";
return $file_error;
}
// Checks if there is an error with the file
switch($file["error"])
// URL: http://php.net/manual/en/features.file-upload.errors.php
{
case 1 : $file_error = "Sorry, the file is too large. Please try again...";
break;
case 2 : $file_error = "Sorry, the file is too large. Please try again...";
break;
case 3 : $file_error = "Sorry, the file was only partially uploaded. Please try again...";
break;
case 6 : $file_error = "Sorry, a temporary folder is missing. Please try again...";
break;
case 7 : $file_error = "Sorry, the file could not be written. Please try again...";
break;
case 8 : $file_error = "Sorry, a PHP extension stopped the file upload. Please try again...";
break;
}
if($file_error)
{
return $file_error;
}
// Breaks the file in pieces (.) All pieces are put in an array
$file_array = explode(".", $file["name"]);
// Puts the last part of the array (= the file extension) in a new variabele
// Converts the characters to lower case
$file_extension = strtolower($file_array[count($file_array) - 1]);
// Searches if the file extension exists in the 'allowed' file extensions array
if(in_array($file_extension, $file_extensions))
{
$file_error = "Sorry, the file extension is not allowed. The following extensions are blocked: <b>" . join(", ", $file_extensions) . "</b>";
return $file_error;
}
// Checks if the file already exists in the directory
if(is_file("$directory/" . $file["name"]))
{
$file_error = "Sorry, the file already exists. Please rename the file...";
}
return $file_error;
}
확장자 검증을 진행하나.. 블랙리스트로 목록에 있으면 오류 처리
php3로 카피해서 넣어보자
php확장자는 막혔지만
php3로 바꿔주면 가능해짐
high
function file_upload_check_2($file, $file_extensions = array("jpeg", "jpg", "png", "gif"), $directory = "images")
{
...
// Searches if the file extension exists in the 'allowed' file extensions array
if(!in_array($file_extension, $file_extensions))
{
$file_error = "Sorry, the file extension is not allowed. Only the following extensions are allowed: <b>" . join(", ", $file_extensions) . "</b>";
return $file_error;
}
화이트 리스트에 포함된 경우만 허용
03. (if..) Unrestricted File Upload - web root 밖에 파일을 저장 (다운로드 기능 추가)
web root 밖에 저장하게 코드를 바꿔주자
/var/www/bWAPP/unrestricted_file_upload.php
전체 코드
<?php
/*
bWAPP, or a buggy web application, is a free and open source deliberately insecure web application.
It helps security enthusiasts, developers and students to discover and to prevent web vulnerabilities.
bWAPP covers all major known web vulnerabilities, including all risks from the OWASP Top 10 project!
It is for security-testing and educational purposes only.
Enjoy!
Malik Mesellem
Twitter: @MME_IT
bWAPP is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (http://creativecommons.org/licenses/by-nc-nd/4.0/). Copyright © 2014 MME BVBA. All rights reserved.
*/
include("security.php");
include("security_level_check.php");
include("functions_external.php");
include("selections.php");
if(isset($_POST["form"]))
{
$file_error = "";
switch($_COOKIE["security_level"])
{
case "0" :
move_uploaded_file($_FILES["file"]["tmp_name"], "images/" . $_FILES["file"]["name"]);
break;
case "1" :
$file_error = file_upload_check_1($_FILES["file"]);
if(!$file_error)
{
move_uploaded_file($_FILES["file"]["tmp_name"], "images/" . $_FILES["file"]["name"]);
}
break;
case "2" :
$file_error = file_upload_check_2($_FILES["file"], array("jpg","png"));
if(!$file_error)
{
move_uploaded_file($_FILES["file"]["tmp_name"], "/data/images/" . $_FILES["file"]["name"]);
}
break;
default :
move_uploaded_file($_FILES["file"]["tmp_name"],"images/" . $_FILES["file"]["name"]);
break;
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Architects+Daughter">-->
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen" />
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />
<!--<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>-->
<script src="js/html5.js"></script>
<title>bWAPP - Unrestricted File Upload</title>
</head>
<body>
<header>
<h1>bWAPP</h1>
<h2>an extremely buggy web app !</h2>
</header>
<div id="menu">
<table>
<tr>
<td><a href="portal.php">Bugs</a></td>
<td><a href="password_change.php">Change Password</a></td>
<td><a href="user_extra.php">Create User</a></td>
<td><a href="security_level_set.php">Set Security Level</a></td>
<td><a href="reset.php" onclick="return confirm('All settings will be cleared. Are you sure?');">Reset</a></td>
<td><a href="credits.php">Credits</a></td>
<td><a href="http://itsecgames.blogspot.com" target="_blank">Blog</a></td>
<td><a href="logout.php" onclick="return confirm('Are you sure you want to leave?');">Logout</a></td>
<td><font color="red">Welcome <?php if(isset($_SESSION["login"])){echo ucwords($_SESSION["login"]);}?></font></td>
</tr>
</table>
</div>
<div id="main">
<h1>Unrestricted File Upload</h1>
<form action="<?php echo($_SERVER["SCRIPT_NAME"]);?>" method="POST" enctype="multipart/form-data">
<p><label for="file">Please upload an image:</label><br />
<input type="file" name="file"></p>
<input type="hidden" name="MAX_FILE_SIZE" value="10">
<!-- <input type="hidden" name="MAX_FILE_SIZE" value="100000"> -->
<input type="submit" name="form" value="Upload">
</form>
<br />
<?php
if(isset($_POST["form"]))
{
if(!$file_error)
{
echo "The image has been uploaded <a href=\"/data/images/" . $_FILES["file"]["name"] . "\" target=\"_blank\">here</a>.";
echo "<img src=\"/data/images/" . $_FILES["file"]["name"] . "\">";
}
else
{
echo "<font color=\"red\">" . $file_error . "</font>";
}
}
?>
</div>
<div id="side">
<a href="http://twitter.com/MME_IT" target="blank_" class="button"><img src="./images/twitter.png"></a>
<a href="http://be.linkedin.com/in/malikmesellem" target="blank_" class="button"><img src="./images/linkedin.png"></a>
<a href="http://www.facebook.com/pages/MME-IT-Audits-Security/104153019664877" target="blank_" class="button"><img src="./images/facebook.png"></a>
<a href="http://itsecgames.blogspot.com" target="blank_" class="button"><img src="./images/blogger.png"></a>
</div>
<div id="disclaimer">
<p>bWAPP is licensed under <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank"><img style="vertical-align:middle" src="./images/cc.png"></a> © 2014 MME BVBA / Follow <a href="http://twitter.com/MME_IT" target="_blank">@MME_IT</a> on Twitter and ask for our cheat sheet, containing all solutions! / Need an exclusive <a href="http://www.mmebvba.com" target="_blank">training</a>?</p>
</div>
<div id="bee">
<img src="./images/bee_1.png">
</div>
<div id="security_level">
<form action="<?php echo($_SERVER["SCRIPT_NAME"]);?>" method="POST">
<label>Set your security level:</label><br />
<select name="security_level">
<option value="0">low</option>
<option value="1">medium</option>
<option value="2">high</option>
</select>
<button type="submit" name="form_security_level" value="submit">Set</button>
<font size="4">Current: <b><?php echo $security_level?></b></font>
</form>
</div>
<div id="bug">
<form action="<?php echo($_SERVER["SCRIPT_NAME"]);?>" method="POST">
<label>Choose your bug:</label><br />
<select name="bug">
<?php
// Lists the options from the array 'bugs' (bugs.txt)
foreach ($bugs as $key => $value)
{
$bug = explode(",", trim($value));
// Debugging
// echo "key: " . $key;
// echo " value: " . $bug[0];
// echo " filename: " . $bug[1] . "<br />";
echo "<option value='$key'>$bug[0]</option>";
}
?>
</select>
<button type="submit" name="form_bug" value="submit">Hack</button>
</form>
</div>
</body>
</html>
case "2" :
$file_error = file_upload_check_2($_FILES["file"], array("jpg","png"));
if(!$file_error)
{
move_uploaded_file($_FILES["file"]["tmp_name"], "/data/images/" . $_FILES["file"]["name"]);
}
break;
경로 변경
<?php
if(isset($_POST["form"]))
{
if(!$file_error)
{
echo "The image has been uploaded <a href=\"/data/images/" . $_FILES["file"]["name"] . "\" target=\"_blank\">here</a>.";
echo "<img src=\"/data/images/" . $_FILES["file"]["name"] . "\">";
}
else
{
echo "<font color=\"red\">" . $file_error . "</font>";
}
}
?>
링크(<a>)와 출력(<img>) 경로 수정
디렉토리 생성
당연히 찾을 수 없슴!!
web root 아래에 존재하지 않으니까 . . .
제대로 작동하게 다운로드 기능을 추가하자 (연결고리 느낌)
/var/www/bWAPP/download.php
<?php
$target_Dir = "/data/images/";
$file = $_GET['file'];
$down = $target_Dir.$file;
$filesize = filesize($down);
if(file_exists($down)){
header("Content-Type:application/octet-stream");
header("Content-Disposition:attachment;filename=$file");
header("Content-Transfer-Encoding:binary");
header("Content-Length:".filesize($target_Dir.$file));
header("Cache-Control:cache,must-revalidate");
header("Pragma:no-cache");
header("Expires:0");
if(is_file($down)){
$fp = fopen($down,"r");
while(!feof($fp)){
$buf = fread($fp,8096);
$read = strlen($buf);
print($buf);
flush();
}
fclose($fp);
}
} else{
?><script>alert("존재하지 않는 파일입니다.")</script><?
}
?>
👍
04. (if..) 경로 조작 취약점 path traversal
다운로드 기능을 구현할 때 지정된 경로를 벗어나서 파일을 읽지 못하게 하지 않는다면.. 경로 조작 취약점 발생
download?file=../../../../../../../../../etc/passwd 처럼 상위 디렉토리로 이동해서 각종 파일들을 볼 수 있음
'Rookies > 애플리케이션 보안' 카테고리의 다른 글
[SK shieldus Rookies 19기] Python 시큐어코딩 가이드 - 입력 데이터 검증 및 표현 02 (0) | 2024.03.31 |
---|---|
[SK shieldus Rookies 19기] Python 시큐어코딩 가이드 - 입력 데이터 검증 및 표현 01 (0) | 2024.03.31 |
[SK shieldus Rookies 19기] Cookie / Session (1) | 2024.03.30 |
[SK shieldus Rookies 19기] Django pybo - 크로스 사이트 요청 위조 (CSRF) (0) | 2024.03.30 |
[SK shieldus Rookies 19기] bWAPP bee.box - 크로스 사이트 요청 위조 (CSRF) (0) | 2024.03.30 |