본문 바로가기

IT/웹해킹

오늘의 공부

1.INTRO

어제 알아본 SQL injection 취약점은 데이터베이스에 저장된 중요 정보를 획득할 수 있기에 DBMS 보안에 있어 큰 파급력을 가진다. 해당 문제는 이용자의 입력 값을 검사하지 않고 DBMS 보안에 있어 큰 파급력을 지닌다. 해당 문제점은 이용자의 입력 값을 검사하고 있지 않아, DBMS 쿼리의 일부로 사용하는 등 개발자의 실수로 인해 발생한다. 

개발자는 어플의 용도와 목적에 따라 알맞은 DBMS를 선택해서 사용하는데, 선택한 DBMS의 특징을 이해하지 못한다면 더 큰 문제를 야기할 가능성이 있다. 

 

각각의 DBMS는 설정 파일을 통해 특정 기능을 활성화 하거나 접근 가능한 디렉토리 등을 설정할 수 있다. 일부 기능은 보안성을 위해 비활성화 되어 있따. 그러나 일부 개발자는 개발 과정에서 마주하는 오류를 쉽게 해결 하고, 접근성을 위해 이러한 기능을 활성화 하는 경우가 있따. 실제로 OWASP TOP 10 2021dp EKfmaus "Security misconfiguration" 이 새롭게 등장했따. 이는 계정 및 권한이 적절하게 분리 되지 않거나, 불필요한 기능의 활성화, 데이터베이스의 보안 설정이 미흡한 경우등을 포함한다. 

 

오늘은 이 DBMS의 설정 항목을 잘못 설정했을 때 발생할 수 있는 문제 점에 대해 알아보자.


2. Out of DBMS

 DBMS에서 제공하는 특별한 함수 또는 기능 등을 이요해 파일 시스템, 네트워크, 심지어 OS 명령어 등에도 접근이 가능하다. 이를 통해 SQL injection을 단순히 데이터 베이스의 정보를 획득하는 것 뿐만 아닌 파일 시스템, 네트워크, 시스템 모두 장악할 수 있다. 

 

해당 공격 방식은 DBMS의 버전과 설정에 따라 정상적으로 동작하지 않을 수 있따. DBMS의 버전이 올라감에 따라 위험한 함수나 기능을 제거하거나, 기본 설정/ 권한으로 접근하지 못하게 하는 등 다양한 방법으로 해당 공격방식에 대해 패치를 진행한다.


3.Out of DBMSL :  MySQL

 MYsql에서 파일 관련된 작업을 할 때에는 mysql 권한으로 수행되며, "my.cnf" 설정 파일의 secure_file_priv 값에 영향을 받는다. 해당 설정 파일의 secure_file_priv는 아래와 같은 형태로 정의 되고 있으며, 이는 mysql 쿼리 내에서 load_file 혹은 outfile을 이용해 파일에 접근할 때 접근할 수 있는 파일 경로에 대한 정보를 가지고 있다. 

# my.cnf
[mysqld]
# secure_file_priv = ""   # 미설정. 기본 설정 값으로 설정됩니다.
secure_file_priv = "/tmp" # 해당 디렉터리 하위 경로에만 접근 가능합니다.
secure_file_priv = ""     # mysql의 권한이 가능한 모든 경로에 접근이 가능합니다.
secure_file_priv = NULL   # 기능이 비활성화 됩니다.

기본적으로 secure_file_priv 의 값은 /var/lib/mysql-files/이며, 해당 값은 아래와 같은 쿼리를 통해 확인할 수 있다.

mysql> select @@secure_file_priv;
+-----------------------+
| @@secure_file_priv    |
+-----------------------+
| /var/lib/mysql-files/ |
+-----------------------

 ⅰ) load_file 

 load_file 함수는 인자로 전달된 파일을 읽고, 출력한다. 이때, 전달되는 파일은 전체 경로를 입력해야 하며 해당 파일에 접근 권한이 있어야 한다. 

# echo test1234 > /var/lib/mysql-files/test
mysql> select load_file('/var/lib/mysql-files/test');
+----------------------------------------+
| load_file('/var/lib/mysql-files/test') |
+----------------------------------------+
| test1234                               |
+----------------------------------------+

ⅱ) into outfile

SELECT... INTO 형식의 쿼리는 쿼리 결과를 변수나 파일에 쓸수 있따. 만약, secure_file_priv의 값이 올바르지 않아 임의 경로에서 파일 작업을 수행 할 수 있따면 이를 웹셀을 업로드 하는 등의 공격이 가능한다. 

아래는 공격쿼리의 예시이다.

SELECT ... INTO var_list             # column 값을 변수에 저장
SELECT ... INTO OUTFILE  'filename'  # 쿼리 결과의 rows 값을 파일에 저장
SELECT ... INTO DUMPFILE 'filename'  # 쿼리 결과(single row)를 파일에 저장
mysql> select '<?=`ls`?>' into outfile '/tmp/a.php';
/* <?php include $_GET['page'].'.php'; // "?page=../../../tmp/a" */

바로 위의 내용은 SELECT .... INTO 를 이용한 웹셀 작성 방법이다. 


4.Out of DBMS: MSSQL

MSSQL에서는 xp_cmdshell기능을 이용해 OS 명령어를 실행할 수 있따. 과거 MSSQL에서는 해당 기능이 기본적으로 활성화 되어 있어 SQL Injection이 발생할 경우 임의 코드 실행이 가능했다. 그러나 SQL Server 2005 버전 이후로부터는 비활성화 되어 있어 임의로 활성화 하지 않는 이상 해당 기능을 이용한 공격은 불가능하다. 

 

해당 기능의 활성화 여부를 판단하는 쿼리는 아래와 같으며, 해당 쿼리의 실행 결과에서 1이 반환되면 활성화, 0이라면 비활성화 상태를 의미한다.

SELECT * FROM sys.configurations WHERE name = 'xp_cmdshell'

만약 xp_cmdshell 기능이 활성화 되어 있는 경우 아래와 같은 방식으로 OS 명렁어를 실행할 수 있다. 

EXEC xp_cmdshell "net user";
EXEC master.dbo.xp_cmdshell 'ping 127.0.0.1';

5. DBMS 권한 문제 주의 사항 

1) DBMS 어플 작동 권한

 리눅스 서버에서는 이용자 별로 권한을 나누어 관리한다. 이를 이용해 서버에서 DBMS를 작동할 떄 DBMS 전용 계정 ( nologin)을 만들어 사용해야 한다. 루트 계정이나, 다른 어플 권한이 탈취되면 큰 문제가 발생할 수 있다. 

 

계정을 분리하지 않을 경우 앞서 다룬 Out of DBMS 내용과 같이 파일 시스템, 네트워크 접근이 가능할 뿐만 아닌 OS 명령어를 실행할 수 있다. 

 

2)DBMS 계정 권한

일반적으로 DBMS 내부에 계정과 권한이 존재한다. 웹 어플에서 DBMS의 루트 걔정을 사용하고, 여러 서비스에서 같은 DBMS의 루트 계정을 사용하고, 여러 서비스에서 같은 DMBS를 사용할 때 접속 계정을 분리하지 않는 경우가 있다. 이때, 한 서비스에서 SQL Injection 취약점이 발생하면 서비스에서 사용하는 DBMS 계정으로 타 데이터베이스에 접근할 수 있따. 따라서 루트 계정의 사용을 지양하고, 서비스 및 기능 별로 계정을 생성해 사용해야한다. 


6.DBMS 문자열 비교 주의 사항 

각각의 DBMS는 문자열을 비교하는 방법이 서로 다르다. 같은 이유로 웹 어플과 DBMS에서 문자열을 비교하는 방식이 다를 수 있는데, 이로 인해 개발자의 의도와 다르게 동작하는 경우가 존재한다.

<?php
...
// $input = "Admin"; # 대소문자 구분
// $input = "admin "; # 공백 문자로 끝나는 문자열 비교
if($input === "admin") die("can't account lookup"); // filter bypass
/*
DBMS
uid: admin, account_info: secret
...
*/
echo query("select account_info from users where uid='{$input}';");

위의 예시는 문자열 검사가 미흡한 예제이다. 어플에서는 "admin" 계정을 획득하지 못하도록 입력밧에서 해당 문자열을 검사한다. 언뜻 보면, 올바르게 작성된 코드처럼 보일 수 있으나, 이는 DMBS에 따라 우회가능성이 있다. 

 

대소문자 구분

일부 DBMS에서는 비교 연산에서 대소문자를 구분하지 않는데. 아래의 두예시는 각각 MySQL, MSSQL 에서 소문자와 대문자를 비교하는 쿼리를 실행한 모습이다. 쿼리 실행 결과를 살펴보면, 소문자와 대문자를 비교한 연산에서 참을 반환하는 것을 알 수 있다. 

mysql> select 'a'='A';
/*
+---------+
| 'a'='A' |
+---------+
|       1 |
+---------+
*/
> select 1 from test where 'a'='A';
/*
-----------
          1
*/

공백 문자로 끝나는 문자열 비교

일부 DBMS에서는 비교 연산시 할당된 컬럼의 크기에 맞게 공백 문자를 채운 후에 비교한다. 예를 들어 CHAR(5)로 생성된 컬럼에 "ab"라는 데이터가 입력 되면 "ab   " 이 되는 것이다. 아래 두 예시는 각각 MYSQL, MSSQL 에서 공백 문자가 추가된 무자열을 비교하는 쿼리를 실행한 모습이며, 쿼리 실행 겨로가를 살펴보면, 공백을 추가하지 않은 문자와 추가한 문자가 서로 같은 것을 알 수 있다. 

mysql> select 'a'='a ';
/*
+---------+
| 'a'='a '|
+---------+
|       1 |
+---------+
*
> select 1 from test where 'a'='a ';
/*
-----------
          1
*/

7.DBMS 다중 쿼리 주의 사항

다중쿼리 (Multi Query)는 다음 예시와 같이 하나의 요청에 다수의 쿼리 구문을 사용하는 것을 의미한다. 대부분의 웹 어플은 DBMS에 쿼리를 전송할 떄 다중 쿼리를 지원하지 않는다. 다중 쿼리를 지원하지 않으면, SQL Injection 취약점이 발생했을 때 해당 쿼리를 벗어나서 새로운 쿼리를 작성하는 것이 불가능하기 떄문에 공격에 제약이 생길 수 밖에 없다. 만약 어플에서 다중 쿼리를 지원한다면 공격자는 본래 실행되는 쿼리문에 새로운 쿼리를 작성해 데이터 베이스를 삭제하거나 값을 추가하는 등의 행위가 가능하다. 

 

SELECT * from users where uid=''; 
INSERT users values (...);

다중 쿼리를 이용한 예시

아래 두가지의 예는 PHP의 PHP Data Object (ODO)를 사용해 다중 쿼리를 실행하는 결과이다.PDO의 query 함수는 다중 쿼리를 지원하지 않고, exec 함수에서는 다중 쿼리를 실행한다는 차이가 존재한다. 실행결과를 보면 'test1.db'는 크기가 0임을, 'test2.db'의 파일의 크기는 2048임을 볼 수 있으며, 다중 쿼리가 실행되었음을 알 수 있다. 

<?php
    $db1 = new PDO('sqlite:test1.db');
    $db2 = new PDO('sqlite:test2.db');
    $query = 'select 1234;create table test(test int);';
    $db1->query($query);
    $db2->exec($query);
?>
$ php test.php
$ ls -al test1.db test2.db
-rw-r--r-- 1 test test    0 Apr 29 11:21 test1.db # create table이 실행되지 않음
-rw-r--r-- 1 test test 2048 Apr 29 11:20 test2.db # create table이 실행됨

8.OUTRO

이번엔 DBMS에서 제공하는 긴으을 잘못 사용했을 때 발생할 수 있는 문제점과 설정 시 주의사항에 대해서 소개했따. 보안성을 위해 기본적으로 비활성화 되어 있는 기능을 활성화하면 시스템이 장악될 수 있으며 어플마다 DBMS의 계정과 권한을 분리하지 않으면 모든 서비스에 영향을 끼칠 수 있따는 것을 배웠따.

 

OWASP TOP 10 "Securtiy Miconfiguration"이 등장한 만큼, 안전한 코드를 작성하는 것 외에도 사용하고 있는 DBMS의 특징을 이해하고 설정을 변경하는 것이 매우 중요하다.

 

 

내일 공부할 부분을 슭 훝어 봤는데,,,큰일 났다.. 상당히 어려워 보인다... 

긴장해야지,,,,

 

아 추가로,, MySQL, MSSQL 에 대한 추가 공부를 현시점에서 하는게 옳은가,,, 궁금하다.. 

정보보안기사를 취득한 뒤 공부를 해볼까,,흠

반응형

'IT > 웹해킹' 카테고리의 다른 글

오늘의 공부: Bypass WAT  (0) 2023.07.21
오늘의 공부  (0) 2023.07.19
SQL Injection -Part2 -1  (0) 2023.01.26
SQL injection -4  (2) 2023.01.25
SQL Injection -3  (0) 2023.01.24