[모의해킹 실습] Union SQL Injection 게시판 구현 및 공격실습 2

반응형

UNION SQL Injection 취약 게시판 구현 및 공격 실습

1. 공격 원리

1. SQL Injection 공격 가능 여부 확인
2. 컬럼 수 추출
3 . 각 컬럼 데이터형 추출
4. 데이블 목록 추출
5. 원하는 테이블의 컬럼명 추출
6. 원하는 데이터 추출


SQL에서 Union은 두 개의 쿼리문에 대한 결과를 통합하여 하나의 테이블로 보여주게 하는 키워드이다. 정상적인 쿼리문에 Union 키워드를 사용하여 인젝션에 성공하면, 원하는 쿼리문을 실행할 수 있게 된다. Union SQL Injection은 이전 Select 문과 Union Select 문의 칼럼 수가 동일해야 한다는 특징과 칼럼은 각 순서별로 동일한 데이터 형이어야 한다는 특징을 이용한다. 공격 과정은 다음과 같다.

 

2. 공격 실습

No. 실습 위치 비고
1 localhost/freeboard/search 게시글 검색 기능

게시판 구현

<div id="board_area"> 
  <h2>자유게시판</h2>
<?php
echo "<p>{$_SESSION['username']} 님 환영합니다.</p>";
?>
  <p>자유롭게 글을 쓸 수 있는 게시판입니다.</p>
    <table class="table table-hover" style="border: 1px solid;">
      <thead class="thead-dark">
          <tr>
              <th scope="col" width="70">번호</th>
                <th width="500">제목</th>
                <th width="120">글쓴이</th>
                <th width="100">작성일</th>
                <th width="100">조회수</th>
            </tr>
        </thead>
<?php
    $menu = $_GET['menu'];
    $search = $_GET['search'];
if(isset($_GET["search"]))
{
    $search = $_GET["search"];
    $sql = "SELECT * FROM freeboard WHERE title LIKE '%" . $search . "%'";
    $recordset = mysqli_query($link, $sql);
    if(!$recordset)
    {
        // die("Error: " . mysql_error());
?>
        <tr height="50">
            <td colspan="5" width="580"><?php die("Error: " . mysqli_error($link)); ?></td>
        </tr>
<?php
    }
    if(mysqli_num_rows($recordset) != 0)
    {
        while($row = mysqli_fetch_array($recordset))
        {
            // print_r($row);
?>
        <tr height="30">
          <td width="70"><?php echo $row['idx']; ?></td>
          <td width="500"><a href="/freeboard/read?idx=<?php echo $row["idx"];?>"><?php echo $row["title"];?></a></td>
          <td width="120"><?php echo $row['name']?></td>
          <td width="100"><?php echo $row['date']?></td>
          <td width="100"><?php echo $row['hit']; ?></td>
        </tr>
<?php
        }
    }
    else{
?>
        <tr height="50">
            <td colspan="5" width="580">No Result found!</td>
        </tr>
<?php
}
mysqli_close($link);
}
?>
</table>

freeboard/search.php 중 일부

공격 실습

Step1. 취약한 게시판 사이트에 접근 후 싱글 쿼터를 입력해 문법상 에러를 유발해 SQL Injection 공격이 가능한지 여부를 확인한다.

싱글 쿼터 입력 시 에러 메시지 출력 확인

Step2. 컬럼 수를 확인하기 위해 구문의 컬럼 수를 추가하며 에러 발생 여부를 확인한다. 컬럼 수가 맞지 않을 경우 에러가 발생하고, 일치하는 경우 검색 결과와 컬럼 위치를 확인할 수 있다. 이 과정을 통해 8개의 컬럼 수를 확인할 수 있습니다.

입력 구문: ’ UNION SELECT ALL 1#

컬럼 수 확인 시도(1)

입력 구문: ‘UNION SELECT ALL 1,2,3,5,6,7,8#

컬럼 수 확인 성공

 

Step3. Union절에 대응하는 컬럼은 데이터형이 같아야 한다는 특징을 이용해 각 컬럼의 데이터형을 추출할 수 있으며 첫 번째 컬럼의 데이터형은 정수형임을 알 수 있다.

입력 구문: ' UNION SELECT ALL 1,2,table_name,4,5,6,7,8 from information_schema.tables#

컬럼 별 자료형 추출

Step4. Union Select를 이용하여 데이터베이스에서 사용하는 테이블 명을 확인한다.

입력 구문: ' UNION SELECT ALL 1,2,table_name,4,5,6,7,8 from information_schema.tables#

테이블 명 추출

Step 5. 테이블에서 사용하는 컬럼명을 추출한다.

입력 구문: ' UNION SELECT ALL 1,2,column_name,4,5,6,7,8 from information_schema.columns where table_name='member'#

테이블의 컬럼명 노출

Step 6.추출한 컬럼명을 이용해 데이터를 추출할 수 있다.

입력구문: ' UNION SELECT ALL id, name, pw, name, address, sex, email, 8 from member#

데이터 추출 성공

Union 키워드를 이용해 데이터를 추출할 수 있는 것을 확인했다. 주석, 싱글 쿼터(‘), Union 등 사용자의 입력 값을 검증하지 않아 발생한 취약점으로 사용자 입력 값의 검증이 필요하다.