본문 바로가기
Web/DVWA 실습

DVWA - SQL Injection (low,medium) 실습

by jh117jh 2022. 10. 30.
728x90

SQL Injection

사용자 입력이 서버측에서 실행되는 SQL 쿼리에 삽입되어 사용자의 의도와는 다른 동작이 수행 되게하는 취약점이다.

 

low level

 

<?php

if( isset( $_REQUEST'Submit' ] ) ) {
    
// Get input
    
$id $_REQUEST'id' ];

    switch (
$_DVWA['SQLI_DB']) {
        case 
MYSQL:
            
// Check database
            
$query  "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
            
$result mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res mysqli_connect_error()) ? $___mysqli_res false)) . '</pre>' );

            
// Get results
            
while( $row mysqli_fetch_assoc$result ) ) {
                
// Get values
                
$first $row["first_name"];
                
$last  $row["last_name"];

                
// Feedback for end user
                
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
            }

            
mysqli_close($GLOBALS["___mysqli_ston"]);
            break;
        case 
SQLITE:
            global 
$sqlite_db_connection;

            
#$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']);
            #$sqlite_db_connection->enableExceptions(true);

            
$query  "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
            
#print $query;
            
try {
                
$results $sqlite_db_connection->query($query);
            } catch (
Exception $e) {
                echo 
'Caught exception: ' $e->getMessage();
                exit();
            }

            if (
$results) {
                while (
$row $results->fetchArray()) {
                    
// Get values
                    
$first $row["first_name"];
                    
$last  $row["last_name"];

                    
// Feedback for end user
                    
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
                }
            } else {
                echo 
"Error in fetch ".$sqlite_db->lastErrorMsg();
            }
            break;
    } 
}

?>

low 레벨에서는 필터링 없이 SQL INjection기법을 모두 사용할 수 있다.

먼저 user_id를 입력하면 해당하는 first_name, last_name 을 출력해준다.

'or true #';을 입력하여 WHERE절을 항상 참으로 만들어 모든 사용자를 출력 할 수 있다.

 

이제 다른 테이블에 있는 정보도 출력 하기 위해 union 인젝션을 활용해보자

' union select 1, schema_name from information_schema.schemata# 을 입력하여 데이터베이스 종류를 파악할 수 있다.

information_schema, bWAPP, drupageddon, dvwa, mysql 등의 데이터베이스가 존재하고 우리가 필요한 데이터 베이스는 dvwa 테이블 이기 때문에

 ' union select 1, table_name from information_schema.tables where table_schema='dvwa'#' 을 이용해 guestbook, user 테이블을 찾아 냈다.

패스워드를 알아내기 위해서는 user테이블을 살펴봐야 되므로 

' union select 1, column_name from information_schema.columns where table_schema='dvwa' and table_name='users'# 을 이용하여 어떤 컬럼이 있는지 확인할 수 있다.

 

 이중 password 컬럼을 출력하는 쿼리를 ' union select user_id, password from dvwa.users# 통해 작성하면

password를 알 수 있다.

 

medium level

medium 레벨에서는 input 태그 대신 select태그를 이용해 아이디를 지정된 값만 입력할 수 있게 만들었다.

 

버프스위트로 요청 확인후 id값을 바꿔주기로 하였다.

id값을 low레벨에서 password를 알아내기 위해 입력했던 ' union select user_id, password from dvwa.users# 으로 변경해보았다.

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\' union select user_id, password from dvwa.users#'

에러가 났다....

 

 코드 확인결과

id 파라미터의 " "가 사라졌다 즉 문자열이 아닌 숫자로 받는다는 의미 이다.

' union select user_id, password from dvwa.users# 여기서 따옴표를 빼고 user_id에 들어가는 값(숫자) 아무것나 입력후 요청을 전송하면

password가 출력 된다.

728x90