SQL 인젝션 취약점은 웹 서버 영역의 데이터베이스로 전송되는 SQL 쿼리문을 사용자가 임의로 조작할 수 있는 경우 발생한다.
공격자는 이 취약점을 이용하여 데이터베이스에 저장되어 있는 다른 사용자의 개인정보 등 허가되지 않은 정보에 접근하거나 데이터를 변조할 수 있다.
사용자는 ID가 1인 사용자 정보를 요청할 때, 이 요청을 받은 웹 애플리케이션은 내부의 데이터베이스로 다음과 같은 SQL 쿼리문을 전송한다. SELECT name, email FROM users WHERE ID='1'
이는 users라는 사용자 테이블에서 ID가 1인 사용자의 이름과 이메일을 가져오는 쿼리문이다.
이때, SQL 쿼리문을 구성하는 웹 애플리케이션의 소스코드가
$id = $_REQUEST[ 'id' ];
$query = "SELECT name, email FROM users WHERE id = '$id';";
일 때, 사용자가 입력한 ID 파라미터의 값($id)이 쿼리문의 일부로 사용되고 있는데, 이런 경우 SQL 인젝션 취약점이 존재한다.
WHERE 구문 우회
원래의 ID 값 1 대신 SQL 쿼리문을 직접 조작하기 위해 1' or '1'='1을 입력한다.
입력 값이 SQL 쿼리문에 그대로 삽입된다면 쿼리문은 SELECT name, email FROM users WHERE id = '1' or '1'='1'이 되며, 이 결과 값은 ID가 1인 데이터뿐만 아니라 다른 데이터에 있어서도 모두 참의 결과를 갖기 때문에 모든 사용자의 이름과 이메일이 공격자에 전달된다.
UNION 공격
공격자는 or을 이용한 구문 대신에 UNION 키워드를 사입하고 그 뒤에 사용자 이름과 패스워드를 요청하는 SELECT 구문을 삽입한다.
SELECT name, email FROM users WHERE ID = '1' UNION SELECT name, pw FROM users#'
UNION은 합집합으로 두 개의 SELECT 구문의 결과를 모두 포함시키는 키워드이다.
이렇게 되면 뒤의 SELECT 구문에는 WHERE가 없기 때문에 users 테이블에 존재하는 사용자 이름과 비밀번호도 같이 결과로 반환된다.
추가로 코드의 마지막 부분에 있는 #은 뒤에 오는 내용을 주석 처리하여, 혹시 그 뒤에 있을지 모르는 다른 SQL 쿼리문이 공격자가 원하지 않는 명령문이 실행되거나 SQL 형식 에러가 발생하지 않도록 만들어 준다.
이때, SQL 인젝션 공격에 취약한지 테스트해볼 수 있는 방법 중 가장 기본적인 방법은 '를 입력해보는 것이다.
이렇게 뜨는 이유는 SQL 쿼리문이 SELECT name, email FROM users WHERE id=''';이 되기 때문이다(systax error)
그러면 입력이 SQL 쿼리문에 영향을 줄 수 있다는 뜻이고, SQL 인젝션 공격 성공 가능성이 매우 높다.
위와 같이 입력하면 WHERE 조건문이 항상 '참'의 결과를 가져오면서 모든 사용자의 정보가 출력된다.
UNION은 합집합이기 때문에 UNION을 사용하기 위해서는 원래의 SQL 쿼리문이 조회하는 SELECT 문의 칼럼 개수와 UNION 뒤의 SELECT 문에서 요청하는 칼럼 개수가 같아야만 한다.
따라서 원래의 SQL 쿼리문이 몇 개의 칼럼을 반환하는지 알아내야 한다.
칼럼 개수는 ORDER BY 구문으로 알아낼 수 있다.
ORDER BY : 지정된 칼럼을 기준으로 결과를 정렬할 때 사용하는 키워드
ex) ORDER BY 1 : 첫 번째 칼럼을 기준으로 정렬, ORDER BY 2 : 두 번째 칼럼을 기준으로 정렬
이 때, 전체 칼럼 개수보다 큰 값을 입력하면 정렬을 할 수 없기에 에러를 발생시킨다.
에러가 발생하기 직전의 값이 칼럼의 개수가 된다.
여기서 봤을 때, 칼럼 개수 : 2
이후 UNION SELECT1,2와 같이 일련의 번호를 사용 하여 어떤 칼럼의 정보가 웹 페이지의 어느 위치에 나타나는지 확인한다.
웹 애플리케이션이 어떻게 구현되어 있느냐에 따라 칼럼의 정보가 모두 웹 페이지에 표시되는 것이 아니기 때문에 어떤 칼럼이 웹 페이지에 출력되는지도 이 방법을 이용하여 확인할 수 있다.
MySQL 데이터베이스는 information_schema라는 데이터베이스에서 데이터베이스 이름, 테이블, 칼럼 정보 등을 관리한다. -> 여기서 DB 이름 흭득
추가로 dvwa 데이터베이스의 테이블 목록을 알아낸다.
확인 후 users 테이블에 데이터를 확인한다.
이어서 password 칼럼 내용을 확인해 본다.
여기서 패스워드는 평문이 아닌 해시의 값의 형태로 저장되어 있는데, 이는 쉽게 크래킹 될 수 있다.
위와 같이 admin의 패스워드는 password임을 알 수 있다.
블라인드의 경우 단지 사용자의 존재 유무만 알려주는 메시지로 나타나기 때문에, 쉽게 정보를 빼내기도 어렵다.
이와 같은 상황에서는 일반적인 SQL 인젝션 공격을 시도해 볼 수 없다.
위와 같이 AND이하 구문이 실행된다면 블라인드 SQL 인젝션 취약점을 의심해 볼 수 있다.
위와 같이 응답 메시지가 달라지는 경우도 있지만, 어떤 경우에는 웹 사이트에 출력되는 메시지조차 같은 경우도 있다. 이 때는 웹 요청이 응답되는 시간의 차이를 이용하여 참과 거짓을 구별해내는 방법을 시도해 볼 수 있다. 1' AND SLEEP(5)#
이와 같이 결과를 직접적으로 알 수는 없어도, 참과 거짓일 때의 결과 차이를 분석하여 어떤 정보를 알아내는 기법을 블라인드 SQL 인젝션 공격이라고 한다.
다만 블라인드 SQL 인젝션 공격은 일일이 쿼리문을 만들고 실행해야 하기 때문에 시간이 많이 걸린다. 따라서 자동화 프로그램을 많이 사용한다.(일반 SQL 인젝션 공격도 자동화 프로그램으로 공격이 가능)
-sqlmap -h : 옵션들을 볼 수 있다.
-u : 필수 옵션으로 공격을 시도할 URL을 지정한다.
--cookie : 로그인이 필요한 경우, 로그인하고 난 다음 발급된 세션 쿠키 값을 지정한다.
--data : POST 요청의 폼을 공격하고자 할 때, 바디로 전달되는 데이터를 지정한다.
-p : 테스트할 파라미터를 지정한다.
--dbms : 데이터베이스의 종류를 알고 있는 경우 지정한다.(ex.mysql)
--current-db : 현재 데이터베이스의 이름을 알아낸다.
-D : 데이터를 입수할 데이터베이스를 지정한다.
-T : 데이터를 입수할 테이블 이름을 지정한다.
-C : 데이터를 입수할 칼럼을 지정한다.
--tables : 데이터베이스의 테이블들을 알아낸다. 주로 -D 옵션과 같이 사용한다.
--cuolumns : 데이터베이스의 칼럼들을 알아낸다. 주로 -D, -T 옵션과 같이 사용한다.
--dump : 데이터베이스의 정보들을 알아낸다.
sqlmap 프로그램을 사용하기 위해 필요한 필수 옵션은 -u URL 정보이다.
DVWA처럼 로그인된 페이지에 SQL 인젝션 공격을 시도하는 경우에는 쿠키 정보도 필요하다.
sqlmap을 열어 취약점을 분석한다.
위의 내용에서 중요한 정보는 눈에 띄게 표시된다.
표시된 내용에서 취약점, 버전 정보 등을 알 수 있다.
--current-db 옵션을 줘서 현재 데이터베이스의 정보를 알아낸다.
-D dvwa -tables 옵션을 줘서 데이터베이스의 테이블 정보를 알아낸다.
-D dvwa -T users -dump 옵션을 통해 users테이블의 정보를 본다.
SQL 인젝션 공격과 같은 모든 파라미터 입력값 조작으로 이루어지는 공격은 입력값 검증을 통해 대응
화이트리스트 검증을 하는 것이 좋다.
사용자가 입력한 값은 SQL 쿼리문에서 오직 데이터로만 사용되어야지 SQL 쿼리문의 구조에 영향을 줄 수 없도록 해야 한다.
이럴 경우 prepare() 부분에서 미리 실행할 쿼리문의 형태를 작성(prepared statement)해두고 있기 때문에, 그리고 사용자 입력값이 들어갈 id부분은 bindParam()에서 설정했기 때문에 사용자가 입력한 값이 쿼리문의 일부가 될 수 없고, 온전히 데이터로만 처리되기 때문에 or나 UNION등과 같은 키워드가 입력되어도 무의미한 문자열이 된다.
결과적으로 사용자가 SQL 쿼리문을 조작할 방법이 없어 SQL 인젝션 공격을 효과적으로 방지할 수 있다.
위 글은 '화이트 해커를 위한 웹 해킹의 기술 최봉환 저'를 공부하며 작성한 글입니다.
Step6. 크로스 사이트 요청 변조(CSRF) 공격 (0) | 2021.02.26 |
---|---|
Step5. 크로스 사이트 스크립팅 공격 (0) | 2021.02.25 |
Step4. 커멘드 인젝션 공격 (0) | 2021.02.24 |
Step2. 취약한 인증 공격 (0) | 2021.02.21 |
Step1. 정보수집 (0) | 2021.02.20 |
댓글 영역