카테고리 없음

bWAPP을 이용한 SQL 실습 2

작성자 - 재감자숭

Blind based SQL

 DB로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용한다. 로그인 폼에서 SQL Injection이 가능하다고 가정할 때, 서버가 응답하는 로그인 성공과 실패 메시지를 이용하여 DB의 테이블 정보를 추출할 수 있다.

 

 Blind Injection을 이용하여 DB의 테이블 명을 알아내는 방법으로 인젝션이 가능한 로그인 폼을 통하여 악의적인 사용자는 임의로 가입한 ABC123이라는 아이디와 함께 abc123’ and ASCII(SUBSTR(SELECT name From information_schema.tables WHERE table_type=’base table’ limit 0,1)1,1)) > 100 -- 이라는 구문(MySQL에서 테이블 명을 조회하는 구문)을 주입한다.

 만약 조회되는 테이블 명이 Users 라면 ‘U’ 자가 ascii 값으로 조회가 될 것이고, 뒤의 100 이라는 숫자 값과 비교를 하게 됩니다. 거짓이면 로그인 실패, 참이 될 때까지 뒤의 100이라는 숫자를 변경해 가면서 비교를 한다. 공격자는 이 프로세스를 자동화 스크립트를 통하여 단기간 내에 테이블 명을 알아낼 수 있다.

Time Based SQL

 서버로부터 특정한 응답 대신에 참. 거짓의 응답을 통해서 DB의 정보를 유추하는 기법이다. 사용되는 함수는 MySQL기준으로 SLEEPBENCHMARK 이다.

 로그인 폼에 주입이 되었으며 임의로 abc123 이라는 계정을 생성해 악의적인 사용자가 abc123’ OR (LENGTH(DATABASE())=1 AND SLEEP(2)) 이라는 구문을 주입한다. 여기서 LENGTH 함수는 문자열의 길이를 반환하고, DATABASE 함수는 데이터베이스의 이름을 반환한다.

 

 여기서 주입된 구문에 LENGTH(DATABASE()) = 1 가 참이면 SLEEP(2) 이 동작하고, 거짓이면 동작을 하지 않는다. 이를 통해서 숫자 1 부분을 조작하여 데이터베이스의 길이 또한 알아낼 수 있다

 

 SOAP

 

어플리케이션 게층의 프로토콜을 전송 계층의 프로토콜로 사용할 수 있게 하는 프로토콜이다.

, HTTP, HTTPS, SMTP 등을 통하여 XML기반의 메세지가 네트워크에서 교환된다. 웹 서비스는 네트워크에 있는 정보를 모아 서비스를 제공하므로 SOAP 덕분에 물리적으로 인접하지 않은 서버에 정보를 요청하고 요청에 대한 응답 값을 확인할 수 있다.

Query 결과를 참. 거짓으로 출력하는 페이지를 이용하여 DB 내용을 추측하는 내용이다.

 

 sqli_5.php는 선택한 영화에 남아 있는 티켓 수를 출력하는 페이지로, 티켓 수 출력에 SOAP을 활용하여 예매 가능한 티켓 수를 사용자에게 보여준다.이 페이지는 SOAP 기능을 통해, Boolean Based SQL injection, Time Based SQL injection이 가능하다.URL에 드러난 'title' 변수에 작은따옴표를 입력하여 SQL인젝션이 가능한지 알아본다.변수에 SQL인젝션 취약점이 있는 경우 SQL 오류메세지 출력한다.

SQL Injection_GET

 검색란에 작은따옴표(‘)를 입력하니 에러 메세지가 떴다. 작은 따옴표를 입력하는 이유는 데이터베이스에서 작은 따옴표로 문자데이터를 구분하기 때문이다. 따라서 취약점이 존재할 때 작은따옴표를 입력하면 웹 서버에서 데이터베이스 서버에 질의하는 쿼리에 문법 오류가 생긴다.

 

 구문 오류 에러가 떴고, 사용하는 디비는 'MySQL'이라고 정보를 출력하였다. 즉 에러 메세지는 데이터베이스

서버 정보를 포함한다. 다음으로 데이터베이스에서 사용하는 주석을 알아보기 위해 ' or 1=1 -- ' or 1=1 # 을 입력해보고 주석 문자를 찾는다. 사용할 쿼리를 해석하면 쿼리 결과는 1 =1을 통해 항상 참이 되고 기존 코드의 뒷부분을 전부 주석처리한다.

 

 SQL구문중에 UNION이라는 구문이 있는데 UNION은 둘 이상의 Select문을 결합하여 하나의 결과물로 출력해주는 구문이다.

 

 갯수를 한 두 개씩 추가하다보니 결과가 참이 되는 경우가 생긴다. 7개의 칼럼을 넣으니 결과 값이 출력된다. 페이지에 노출되는 칼럼은 2,3,4,5 번에 위치한 칼럼이기 때문에 결과가 보이는 칼럼에 시스템 변수를 넣어주어 정보를 탈취한다.

0' union select all 1,version(),user(),database(),5,6,7# 를 넣어주면 MySQL 정보와 현재 사용자 아이디, 그리고 현재 사용하고 있는 DB의 이름까지 출력된다.

 

 SQL인젝션 결과 DB 서버에 존재하는 모든 테이블 명을 출력시키기 위해 > 0'union select all 1,table_name,3,4,5,6,7 from information_schema.tables # 쿼리문을 입력한다. 저 쿼리문을 입력하면 서버에 존재하는 모든 테이블이 출력하게 되고 출력된 테이블 명 중 USERS 테이블에 사용자의 계정 정보가 들어있다고 추측할 수 있다. 칼럼명을 알아내기 위해 WHERE 절로 USERS 테이블 정보만 출력하게끔 조건을 지정한다.

 칼럼 내용을 확인할려면 페이지에 노출되는 칼럼 순서에 맞춰 확인하고 싶은 칼럼명을 입력하면 된다. 그러면 현재 페이지에 노출되어있는 번호는 2,3,4,5 번으로 4가지의 정보를 확인할 수 있다.

쿼리문 > 0' union select all 1,id,login,password,email,6,7 from users#

id칼럼 = 회원순서, login 칼럼 = 아이디, password칼럼 = 비밀번호 해시값 등.. 을 저장한 것을 알 수 있다.

페이지에 노출된 칼럼 수보다 확인하려는 칼럼 수가 많을 때 "concat" 함수를 사용하여 칼럼 명을 인자로 입력하면 여러 칼럼의 내용을 볼 수 있다.

 

쿼리문을 날리고, 원하는 정보가 노출되면 SQL 인젝션을 성공한다.

SQL Injection_POST

 GET 방식과 크게 다를게 없지만 URL에서 다르다. POST방식은 URL에 나타나지 않기 때문에 프락시 도구를 사용해서 공격 해야한다. 수동 프록시 설정한다. 설정에서 RESPONSE 설정에 체크하고 INTERCEPT IS ON을 활성화 시킨다. BODYTITLEACTION 변수 두 개에 SQL 인젝션 공격을 시도한다. TITLE 변수에 작은 따옴표를 입력하고 FORWARD 버튼을 클릭하면 다음과 같은 오류가 생성된다,

 이런 오류가 생성되면 SQL인젝션이 가능하다는 의미이다. SQL인젝션에 취약한 변수는 TITLE이고, GET 방식과 마찬가지로 쿼리문을 입력하면 된다.

 

post search 방식과 비슷하게 post select도 버프스위트를 실행하면 bwapp에 오류가 뜬다.

작은 따옴표나 주석문자를 사용하면 항상 참으로 만드는 쿼리를 입력하여도 SQL 구문 오류가 발생한다.

 

 SQL 인젝션 공격을 시도하기 위해 기존 쿼리리와 결합하여 결과를 출력하는 UNION SELECT 구문을 사용해야 하며, 기존 쿼리에서 사용하는 컬럼 수와 맞춰야 한다. 버프스위트로 MOVIE 변수에 조작한 SQL 구문을 입력할 때 실제 사용하는 변수를 넣으면 표에는 그 값에 해당하는 데이터가 나오기 때문에 사용하지 않는 숫자 값을 넣어야 한다. 그리고 조작한 SQL 구문을 넣어 DB 정보를 출력하고 버프스위트를 통해 값을 넘겨주면 정보가 추가된다. 이 다음 방법은 GETSELECT 방식과 똑같다.

 

 

 
 

 

Contents

이 글이 도움이 되었다면, 응원의 댓글 부탁드립니다.