Code::Security/비박스(BWAPP)

비박스(bWAPP) SQL Injection (GET/Search)

태군 코드 2019. 6. 24. 16:59
반응형

이 도구를 이용하여 허용받지 않은 서비스 대상으로 해킹을 시도하는 행위는 범죄 행위 입니다. 해킹을 시도할 때에 발생하는 법적인 책임은 그것을 행한 사용자에게 있다는 것을 명심하시기 바랍니다. 

 

A1 - SQL Injection (GET/Search)

 

SQL Injection은 사용자가 입력한 값을 서버에서 검증하지 않고 데이터베이스 쿼리 일부분으로 인식하여 데이터베이스의 정보가 노출되거나 인증이 우회되는 취약점 입니다. SQL Injection은 사용자가 데이터를 입력할 수 있는 곳 어디에서든 발생할 수 있습니다.

 

참고 사이트 - https://sql--injection.blogspot.com/

 

SQL Injection (GET/Search)의 문제 화면 입니다. 그럼 먼저 검색란에 작은따옴표(')를 입력하여 SQL Injection 취약점이 있는지 알아보도록 하겠습니다. 만약 SQL Injection 취약점이 존재할경우 SQL 오류 메시지를 출력할 것 입니다. (해당 페이지는 GET 방식이므로 테스트시 URL의 변화를 보면서 테스트를 하시기 바랍니다)

 

작은따옴표(')를 입력하였더니 위와 같이 오류 메시지가 나오는 것을 확인할수 있습니다. 작은따옴표를 입력하는 이유는 데이터베이스에서 작은따옴표로 문자 데이터를 구분하기 때문 입니다. 취약점이 존재할경우 작은따옴표를 입력하면 웹 서버에서 데이터베이스 서버에 질의하는 쿼리에 문법 오류가 발생을 하면서 오류 메시지를 출력을 하게 됩니다.

 

오류 메시지에는 데이터베이스 서버 정보가 포함되고, 데이터베이스 서버의 종류에 따라 SQL 구문이 다르므로 가장 먼저 서버 정보를 확인하여야 합니다. 위에 오류 메시지에서는 데이터베이스 서버가 'MySQL'이라는 것을 알 수 있습니다. 

 

그럼 이제 쿼리를 입력하여 어떤 주석 문자를 사용하는지 알아 보도록 하겠습니다.

 

쿼리 결과를 항상 참으로 만들고 기존 코드의 뒷부분을 주석 처리

' or 1=1--

' or 1=1#

 

여기서는 두번째 쿼리를 입력하면 내용과는 상관없이 모든 영화 자료가 출력되는것을 확인할수 있었습니다. 따라서 주석 문자는 #을 사용하도록 하겠습니다.

 

더 자세한 정보를 확인하기 위해서는 UNION SELECT 구문을 사용하여야 합니다.

UNION은 SELECT 문이 둘 이상일 경우 이를 결합하여 두 질의의 결과를 하나로 반환합니다.

 

' UNION SELECT ALL 1#

 

UNION 구문을 사용하려면 이전 쿼리에서 사용하는 SELECT 문의 컬럼 수가 일치해야 합니다. 이는 두 질의의 결과를 하나의 테이블로 합치기 때문에 컬럼을 하나만 추가할 경우 컬럼 수가 일치하지 않는다는 오류 메시지가 나타나고 오류 메시지가 나오지 않을 때까지 컬럼 수를 늘려 페이지의 결과가 참이 되는지 확인을 해야 합니다.

 

컬럼을 하나만 추가하고 확인했을때 오류 메시지가 나오는 것을 확인을수 있습니다.

여기서 컬럼을 하나씩 늘려가면서 테스트를 해보시기 바랍니다.

 

예시) ' UNION SELECT ALL 1,2#

 

컬럼 수를 계속 늘려가며서 확인하였더니 오류메시기 대신 영화 제목의 테이블이 출력되는것을 확인할수 있습니다.

 

더보기

' UNION SELECT ALL 1,2,3,4,5,6,7#

 

이제 시스템 함수를 활용하여 MySQL 버전을 확인해 보도록 하겠습니다. 페이지에 노출되는 컬럼은 2, 3, 4, 5번에 위치한 컬럼이기 때문에 쿼리 결과가 보이는 2, 3, 4, 5번 컬럼 중 하나에 시스템 변수를 넣어주시면 됩니다.

 

' UNION SELECT ALL 1,@@version,3,4,5,6,7# - 2번 컬럼에 시스템 변수를 넣어준 쿼리

 

SQL Injection 결과 MySQL 버전은 5.6.20 이라는 것을 확인할 수 있습니다.

 

시스템 변수 및 함수

database() - 데이터베이스 명을 알려주는 함수

user() - 현재 사용자의 아이디

system_user() - 최고 권한 사용자의 아이디

@@version - 데이터베이스 서버의 버전

@@datadir - 데이터베이스 서버가 존재하는 디렉토리

 

참고 - https://securitycode.tistory.com/68?category=753968

 

■ 테이블과 필드의 정의

- information_schema.schemata : 데이터베이스와 관련된 정보를 가진 테이블

- schema_name : 모든 데이터베이스의 이름 값을 가진 필드

- information_schema.tables : 테이블과 관련된 정보를 가진 테이블

- tables_name : 모든 테이블의 이름 값을 가진 필드

- information_schema.columns : 필드와 관련된 정보를 가진 테이블

- column_name : 모든 필드의 이름 값을 가진 필드

 

■ Union 구문을 통한 DB 구조파악 순서

- order by를 통한 column 갯수 확인

- DB 버전 정보 확인

- database 정보 확인

- table 정보 확인

- user 정보 확인

- column 정보 확인

- recode 정보 확인

 

이제 테이블 명을 확인해 보도록 하겠습니다. 테이블 명을 확인하려면 Information_schema를 사용하여 쿼리를 입력을 해주어야 합니다.

 

' UNION SELECT ALL 1, table_name,3,4,5,6,7 from information_schema.tables# 해당 쿼리를 조회하여 서버에 존재하는 테이블을 알아 보았습니다.

 

출력된 테이블 명 중 users 테이블에 사용자의 계정 정보가 들어있다고 여기서는 추측을 할수 있습니다. 쿼리를 이용하여 users 테이블에 컬럼명을 확인해 보도록 하겠습니다.

 

' UNION SELECT ALL 1,column_name,3,4,5,6,7 from information_schema.columns where table_name='users'#

 

users 테이블의 컬럼 명을 출력하여 확인하였더니, id, login, password, email 정보가 있는것을 확인할수 있습니다. 이제 컬럼 내용을 확인해 보도록 하겠습니다.

 

' UNION SELECT ALL 1,concat(id,login),password,email,secret,6,7 from users#

 

지금까지 URL의 파마미터 부분을 확인을 하면서 진단을 하셨다면, A1 - SQL Injection (GET/Select) 항목도 진단을 하실수 있을거라고 생각이 됩니다.

 

컬럼 내용을 확인하려면 페이지에 노출되는 컬럼 순서에 맞춰 확인하고 싶은 컬럼명을 입력합니다. 페이지에 노출된 컬럼 수보다 확인하려는 컬럼 수가 많을 때는 concat 함수를 사용하여 컬럼 명을 인자로 입력하면 여러 컬럼의 내용을 볼 수 있습니다.

 

난이도 상

 

난이도 상에서는 sqli_check_2 함수로 SQL Injection을 우회하고 있습니다. sqli_check_2 함수는 functions_external.php에 정의 되어 있습니다.

 

PHP 기본 제공 함수인 mysql_real_escape_string 함수를 사용하여 입력한 데이터를 우회 합니다. mysql_real_escape_string 함수는 사용자 입력 값에 SQL 문법에서 사용하는 특수 문자가 있을 경우 다음의 문자에 백슬래시를 붙여 SQL 문법으로 인식하지 않게 방어 합니다. 우회 문자: \x00, \n, \r, \, ', ", \x1a

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형