이번에는 File Upload 공격을 막을 수 있는 BLOB 저장 방식을 구현해보겠습니다.
File Upload 취약점이라는 건 서버에 공격자가 업로드한 파일이 저장되고, 그 파일을 실행시킬 수 있기 때문에
발생하는데요,
하지만 BLOB 형식인 긴 문자열의 데이터로 이미지나 파일을 저장시킨다면
이는 File Upload 공격에 대한 완벽한 대비책이 됩니다.
BLOB ( Binary Large Object )
JavaScript에서 Blob은 이미지, 사운드, 비디오 같은 멀티미디어 데이터를 다룰 때 사용합니다.
- BLOB
- TINYBLOB
- MEDIUMBLOB
- LONGBLOB
이 중, LONGBLOB은 4GB까지의 데이터를 저장가능합니다.
터미널을 열고 다음과 같은 코드를 입력해 blob 을 저장할 테이블을 하나 추가합니다.
CREATE TABLE `blob` (
image_id tinyint(3) NOT NULL AUTO_INCREMENT,
image_type varchar(25) NOT NULL,
image longblob NOT NULL,
image_size varchar(255) NOT NULL,
image_name varchar(50) NOT NULL,
KEY image_id (image_id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query OK라는 글자가 뜨면 성공한겁니다.
desc `blob`; 을 입력하니 예쁘게 잘 만들어진 것 같습니다.
테스트를 위해 blobtest.php라는 파일을 하나 생성합니다.
blobtest.php
<form enctype="multipart/form-data" action="uploadblob.php" method="post">
<div><input name="myfile" type="file"/></div>
<div><input type="submit" value="Submit"/></div>
</form>
화면에 이렇게 잘 구성되었습니다.
uploadblob.php 파일도 하나 생성해줍니다.
uploadblob.php
<?php
/*** check if a file was submitted ***/
if(!isset($_FILES['myfile']))
{
echo '<p>Please select a file</p>';
}
else
{
try {
upload();
/*** give praise and thanks to the php gods ***/
echo '<p>Thank you for submitting</p>';
}
catch(Exception $e)
{
echo '<h4>'.$e->getMessage().'</h4>';
}
}
function upload(){
/*** check if a file was uploaded ***/
if(is_uploaded_file($_FILES['myfile']['tmp_name']) && getimagesize($_FILES['myfile']['tmp_name']) != false)
{
/*** get the image info. ***/
$size = getimagesize($_FILES['myfile']['tmp_name']);
/*** assign our variables ***/
$type = $size['mime'];
$imgfp = fopen($_FILES['myfile']['tmp_name'], 'rb');
$size = $size[3];
$name = $_FILES['myfile']['name'];
$maxsize = 99999999;
/*** check the file is less than the maximum file size ***/
if($_FILES['myfile']['size'] < $maxsize )
{
$dbh = new PDO("mysql:host=localhost;dbname=test", 'root', 'root-password');
/*** set the PDO error mode to exception ***/
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/*** our sql query ***/
$stmt = $dbh->prepare("INSERT INTO testblob (image_type ,image, image_size, image_name) VALUES (? ,?, ?, ?)");
/*** bind the params ***/
$stmt->bindParam(1, $type);
$stmt->bindParam(2, $imgfp, PDO::PARAM_LOB);
$stmt->bindParam(3, $size);
$stmt->bindParam(4, $name);
/*** execute the query ***/
$stmt->execute();
}
else
{
/*** throw an exception is image is not of type ***/
throw new Exception("File Size Error");
}
}
else
{
// if the file is not less than the maximum allowed, print an error
throw new Exception("Unsupported Image Format!");
}
}
?>
코드 출처 : https://salix97.tistory.com/181
그리고는 화면으로 돌아가 저번 게시판 구현 때 사용했던 우파루파 사진을 첨부해줍니다.
에러가 떴습니다.
데이터베이스가 선택되지 않았다는 것 같은데... 뭐가 문제일까요
코드를 치다가 그만 host=localhost를 빼먹었군요 이걸 추가해주니 잘 나왔습니다
Thank you for submitting 이라고 업로드가 잘 된 것 같은 문구가 떴습니다.
터미널을 열고 MySQL 쿼리문을 입력해봤습니다.
SELECT * FROM `blob`;
그랬더니 귀여운 우파루파가 데이터 형식으로 DB에 저장된 것을 볼 수 있었습니다.
잘 저장된 것을 불러와서 보는 것도 가능한지 테스트해보겠습니다.
showblob.php를 생성해줍니다.
showblob.php
<?php
/*** assign the image id ***/
$image_id = 1;
try {
/*** connect to the database ***/
$dbh = new PDO("mysql:host=localhost;dbname=test", 'root', 'root-password');
/*** set the PDO error mode to exception ***/
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/*** The sql statement ***/
$sql = "SELECT image, image_type FROM `blob` WHERE image_id=$image_id";
/*** prepare the sql ***/
$stmt = $dbh->prepare($sql);
/*** exceute the query ***/
$stmt->execute();
/*** set the fetch mode to associative array ***/
$stmt->setFetchMode(PDO::FETCH_ASSOC);
/*** set the header for the image ***/
$array = $stmt->fetch();
/*** check we have a single image and type ***/
if(sizeof($array) == 2)
{
/*** set the headers and display the image ***/
header("Content-type: ".$array['image_type']);
/*** output the image ***/
echo $array['image'];
}
else
{
throw new Exception("Out of bounds Error");
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
catch(Exception $e)
{
echo $e->getMessage();
}
?>
URL 창에 showblob.php를 호출했더니 귀여운 우파루파가 잘 보여지고 있습니다.
소스 참조
https://heropy.blog/2019/02/28/blob/
https://salix97.tistory.com/181
'해킹 > Web Hacking' 카테고리의 다른 글
[13주차] 스터디 정리 - 현업의 프로세스 흐름, 모의해킹 보고서 (0) | 2023.06.23 |
---|---|
[12주차] 스터디 정리 - 인증/인가 취약점 (0) | 2023.06.15 |
[11주차] 해킹 스터디 정리 - File Download 공격, LFI 취약점 (0) | 2023.06.08 |
[10주차] 해킹 스터디 정리 - File Upload 공격 (0) | 2023.06.01 |
[9주차] 해킹 스터디 정리 - CSRF Token, SSRF, File Upload 공격 (0) | 2023.05.25 |