정보보안공부

웹보안_21. Blind Injection 본문

정보보안/웹보안

웹보안_21. Blind Injection

Steady_sp 2018. 3. 20. 23:56

Blind Injection

- 임의의 SQL 구문을 삽입하여 인가되지 않은 데이터를 열람할 수 있는 공격 방법이라는 점에서 SQL Injection과 동일하지만, SQL Injection은 조작된 쿼리를 입력해 한번에 원하는 데이터를 얻을 수 있지만, Blind Injection은 쿼리 결과에 따른 서버의 참과 거짓 반응을 통해 공격을 수행한다.

- 쿼리에 대한 결과가 참일때와 거짓일 때 서버의 반응이 나타나야하며 이를 구분할 수 있어야 한다.

 

# injection에 취약한 부분 확인하는 법

-> 참/거짓을 이용

-> 모든 취약점은 에러

 

테스트 해보기위해 table을 작성하고 view.php파일을 실행시켜보자.

 

 

 

table을 작성한뒤 Blind Injection에 취약하도록 코드를 작성한다.

 

# no값이 정수

 

이제 웹페이지로 접속할때 where조건의 no 값에 따라 해당 데이터들을 확인할 수 있다.

 

 

no값을 이용해서 해당 데이터를 불러온다 이때 and 연산자를 이용해 참과 거짓으로 해당 쿼리의 내용의 결과를 구분할 수 있다.

 

-> and 1=2 라는 조건은 거짓이므로 해당 쿼리의 내용이 거짓이라는 조건에 의해 출력되지 않는다.

 

 

-> and 1=1 라는 조건은 참이므로 해당 쿼리의 내용이 참이라는 조건에 의해 원래 쿼리 그대로 출력이 된다.

 

이번에는 no값이 정수가아닌 문자로 작성되도록 한뒤 실행보자.

 

# no값이 문자 : mysql 주석 #(%23)을 사용

 

no값이 문자로 받아지도록 '$_GET[no]'로 설정하였다.

 

 

-> no=2' and 1=1 '로 쿼리가 작성되 에러가 발생했다. 맨뒤의 쿼터 ( 기존의 ' '안에 no=2' and 1=1로 작성했으므로 뒤의쿼터 ' 한개가 남아있다.) #(%23)을 이용해 주석처리해야한다.

 

 

-> and 1=1에 의해 참으로 판단

 

 

-> and 1=2에 인해 거짓으로 판단

 

# Mysql 실시간 로그확인하는 방법

 

쿼리를 실행할때마다 로그를 보기위해서는 먼저 동작되고있는 mysql을 정지한다.

 

그다음 mysqld_safe --log=query.log & 를 작성한다 이때 log = query.log로 작성되지 않도록 띄여쓰기에 주의한다.

 

 

 

-> tail명령어를 이용해 쿼리가 실행될때 바로바로 쿼리실행 결과를 확인할 수 있다.

 

# injection으로 새로운 select쿼리 실행

-> 취약한점이 발견됬다면 해당쿼리뒤에 새로운 select쿼리를 작성해보자.

-> union을 사용해서 작성할 수 있다.

 

 

-> union을 사용하면 select쿼리 2개를 전부 출력할 수 있는데 이때 select 쿼리의 컬럼수가 일치해야 실행이된다. test의 컬럼은 no와 content 2개이므로 union이후 select로 출력하려는 컬럼도 2개여야된다. 위 사진은 컬럼대신 문자열이지만 이해하기 위해 작성했다.

 

# select쿼리 실행하기위해 컬럼수 확인하기

-> union을 사용하기 위해서는 컬럼수를 확인해야한다.

-> 컬럼수를 확인하는 방법은 order by 숫자를 입력하는 것이다.

-> 컬럼수를 확인하면 union을 사용해 select 쿼리의 컬럼도 일치하게 작성한다.

 

 

-> anews테이블에는 2개의 컬럼이 작성되어있다. (no, title)

-> order by 숫자는 해당 컬럼이상으로 숫자를 작성할 수 없다. order by 2 의 의미는 2번째 컬럼을 기준으로 순서를 정렬하는 것이다. anews에서 1번째 컬럼은 no, 2번째 컬럼은 title이다. 따라서 title 내용의 첫번째 문자를 기준으로 정렬되었다. order by 1은 no 기준으로 정렬되는 것이므로 해당컬럼 이상 작성하게되면 error가 발생한다.

-> 이점을 이용해 해당 컬럼의 수를 확인할 수 있다.

 

-> news의 컬럼은 3개이라는 것을 확인할 수 있다.

 

# 테이블 Guessing(추측하기)

-> 컬럼의 개수를 알아냈다면 union을 사용해 select를 해야하는데 이때 해당 테이블의 이름을 추측해야한다. 일반적인 테이블의 이름을 이용해 추측한다.

-> 예를들면 사용자 테이블 : user, user_table, member, ...

-> union select 추측컬럼 from 테이블이름

-> 에러가 발생하면 존재하지않는 테이블이거나 테이블이 존재해도 해당 컬럼의 개수가 일치하지 않다는 것이다. 여러가지 상황을 고려해 추측해야한다.

 

# Information_schema

-> mysql 5.0 이상에서만 사용가능하다. ( 타깃 서버가 mysql 버전이 5.0이상인 경우만)

-> 타깃서버가 mysql 5.0이상인경우 사용하는 방법이다.

 

 

-> information_schema에서 테이블의 목록들을 확인한다.

 

 

-> TABLES는 테이블의 이름과 테이블의 타입정보를 확인할 수 있다. 

-> COLUMNS는 모든 테이블의 이름과, 컬럼의 이름을 알수 있다.

 

# TABLES 테이블

 

 

-> tables라는 테이블의 table_name이라는 컬럼이 모든 데이터베이스의 테이블이름을 확인할 수 있다. table_type은 각 테이블의 타입을 나나타낸다.

 

 

-> 일반적인 table_type은 base table이다. where 조건을 이용해 table_type = 'base table'을 이용하면 찾는 내용을 단축할 수 있다.

 

-> table_type = 'base table'인것중에 table_name을 조회하면 이중에 공격하려는 테이블을 선택할 수 있다.

 

# COLUMNS 테이블

 

 

-> columns 테이블을 이용하면 table_schema,table_name, column_name이라는 테이블의 DB, 테이블의 이름, 컬럼의 이름을 모두 조회할 수 있지만 결과값을 보면 728개라는 아주많은 양의 데이터를 확인할수있다. 이렇게되면 굉장히 비효율적이다. 따라서 TABLES 테이블에서 해당 테이블의 이름을 알아낸뒤 WHERE조건을 이용해 COLUMNS테이블에서 컬럼의 이름을 찾아본다.

 

 

-> 이쿼리는 information_schema라는 DB에 TABLES테이블이다.

 

 

-> blind Injection을 수행할때는 mysql에서 테이블을 사용하기전에 데이터베이스를 선택하는 use information_schema를 따로 입력할 수 없기 때문에 해당DB도 확인한뒤 .을이용해 DB.table이름으로 작성한다.

Comments