Covenant

본 포스트는 https://www.udemy.com/의 강좌 화이트헤커가 되기 위한 8가지 웹 해킹 기술 강좌를 바탕으로 작성했습니다.



SQL 인젝션 공격이란?

 데이터베이스에 전송되는 SQL 쿼리문을 조작하여 데이터베이스를 변조하거나 허가되지 않는 정보에 접근하는 것을 말한다. 최근에도 자주 사용되는 방법이다. 11년 소니 해킹, 15년 뽐뿌 해킹, 15년 어나니머스 WTO해킹에 해당한다.

 

공격 시나리오

ID=1 을 사용자가 요청한다. 요청을 받으면 웹 애플리케이션은 내부에 있는 데이터베이스로 SQL쿼리문을 전송한다. 쿼리문안에 WHERE라는 조건문이 있고 사용자 ID가 조건문에 입력된다고 하자, 전체 쿼리문의 뜻은 ID=1의 경우 users라는 사용자 테이블에서 사용자와 이메일을 가져 오라는 뜻이다. 이때 해커는 1뒤에 SQL쿼리문을 조작하기 위해서 다음과 같이 입력한다. 그러면 or이라는 키워드가 들어간다. '1'='1'이라는 항상 참이되는 조건문이 삽입되어있다. ID가 다른 경우에도 참이기 때문에 반환이 된다. WHERE구문이 우회되기 때문에 모든 사용자의 정보가 넘어간다.

 

[UNION 공격]

 union키워드를 삽입하여 selet 구문을 삽입한다. union사이에 두고 select가 위치한다. union은 합집합으로 두개의 select 구문의 경우를 포함한다. ID사용자 정보 이외에도 뒤에 select 구문의 결과를 삽입한다. 모든 사용자의 비밀번호가 리턴 된다. #mysql의 구문을 주석 처리하는 것이다. 항상 해커가 원하는 결과를 얻기 위해서이다.

 

Low level

ID1인 사용자의 정보가 나온다. 이런 페이지가 있을 때 SQL 인젝션 공격이 가능한지 보는 방법은 '(작은 따옴표)

입력해 보는 것이다. 취약한 페이지의 경우 SQL관련 에러가 발생한다.

이유는 소스코드를 보면 

id라는 변수는 이미 ''로 둘려 쌓여 있다. 여기에 '가 들어오면 '3개가 되면서 에러가 발생하는 것이다.

비정상적인 문자를 입력했을 때 오류가 발생하면 SQL문으로 처리된다는 뜻이다. 우리가 SQL쿼리문을 조작할 수 있다.

 

1' or '1'='1을 입력한다.

- 테이블의 모든 정보가 나온다.

이 문자열을 넣음으로서 조건문이 항상 참이 나오게 한다. 따라서 모든 id가 나온다.

이것을 이용하면 내 자신의 정보만 조회할 수 있지만 다른 사용자의 정보를 알아내는것이 가능하다.

 

'#을 넣으면 에러가 발생하지 않는다. mySQL DB에서 #이후에 주석을 처리하기 때문에 쿼리문에 영향을 주지 않는다.

이렇게 주석을 처리하면 쿼리문이깨져서 공격에 실패하는 것을 방지한다.

 

 

[Union 키워드를 이용한 공격]

Union을 이용하면 데이터베이스의 모든 정보를 알아낼 수 있다. Union은 합집합이다.

원래 쿼리문이 조회하는 Select의 문의 칼럼 개수와 Union 뒤에서 요청하는 칼럼 개수가 같아야 한다.

그렇지 않으면 에러가 발생한다.1

원래의 쿼리문이 몇 개의 칼럼을 리턴 하는지 알아야 한다.

 


1' union select 1#

select 1하면 그것을 그대로 출력한다. 1뿐만 아니라, 2, 3 or NULL을 줄 수 있다.

 

1' union select 1,1

오류가 나지 않고 출력이 된다.

 

*다른 방법

ORDER BY 명령어 : 어떤 칼럼을 기준으로 정렬할 때 사용하는 방법 칼럼 개수보다 큰 값을 입력하면 정렬할 수 없기 때문에 오류가 발생한다.

1' order by 1#

같은 방법으로 2일 때도 오류가 안 난다.

3을 넣으면 오류가 난다. 3번째 칼럼으로 정렬할 때 문제가 발생했기 때문에 칼럼의 개수는 2개가 된다는 것이다.

 

 

1' union select schema_name,1 from information_schema.schemata

information_schema라는 데이터베이스에서 schemata라는 정보를 가져오고 있다.

mySQL에서 information_schema라는 데이터베이스에서 데이터베이스 칼럼 정보 등을 관리하고 있다.

schema_name을 가져오면 데이터베이스 네임을 가져온다.

 

 

1' union select table_schema, table_name from information_schema.tables where table_schema = 'dvwa' 구문을 사용한다.

dvwa 데이터베이스에 관심이 있기 때문에 dvwa로 들어간 것이다.

users 테이블에 사용자 정보가 있는 것 같으니

 

 

1' union select table_name, column_name from information_schema.columns where table_schema = 'dvwa' and table_name = 'users'#

입력하여 users 테이블 칼럼 조회한다.

 

1' union select user,password from users로 사용자 이름과 비밀번호를 가져온다. password가 해사값으로 저장되어 있다. 데이터베이스가 털려도 암호화되어있으면 해커는 알지 못한다.

md-5 라는 보안에 취약한 해시 값을 사용하고 있기 때문에 비밀번호를 알 수 있다.

 

 

 

[블라인드 SQL인젝션]

SQL injection (Blind) 탭으로 이동한다.

 

에러가 발생되지 않으니 조작할 수 있는지, 조작하더라도 데이터를 그대로 출력하지 않기 때문에 정보를 알기 어렵다

 

1' AND 1=2# 을 입력하면 User ID is MISSING from the database.라는 결과가 나온다.

이는 커맨드 라인에서 SELECT user from users where id='1' AND 1=1 이라고 입력하면 전체가 참인 조건이 되서 사용자가 있다고 나오고

1=2 라고 하면 조건문이 거짓이 되어서 사용자가 없다고 나온다. 어떤 폼 뒤에 AND같은 연산이 실행된다는 것은 SQL 쿼리문이 뒤에 있다는 중요한 조건이 된다.

비록 직접적인 결과를 알 수 없지만 admin이라는 사용자가 존재하는가? 명제를 준 다음에 AND 조건을 다르게 주어서 그 명제가 참인지 거짓인지 줄 수 있다.

시간은 오래 걸리겠지만 일일이 이것은 있는지 없는지로 원하는 정보를 알 수 있다. 참 거짓의 차이를 보고 알아내는 것을 블라인드 인젝션이라고 한다.

그러나 어떨 때는 표시되는 메시지가 가은 경우도 있다. 이 때 응답시간의 차이를 두는 것을 시도해 볼 수 있다. 참이 때는 sleep 이나 wait for를 두어서 아는 방법이 있다.

 

* 방법 브라우저에서 F12를 누른다. Network 탭을 열어둔다.


1' AND sleep(5)#

5초 뒤에 결과가 온 것을 알 수 있다.

 

6' AND sleep(5)#

바로 응답이 온다.

이를 통해서 1이라는 사용자는 존재하고 6이라는 사용자는 존재하지 않는 것을 알 수 있다.

 

많은 정보를 찾기 위해서 일일이 입력해야 한다. 따라서 프로그램을 사용하는 것이 유용하다. SQL MAP을 사용하여 블라인드 인젝션 공격을 한다.

 

 

[SQL MAP]

SQL MAPSQL 인젝션 프로그램 중에 제일 대중화된 프로그램이다.

칼리에 기본 설치된 SQL MAP에서 테스트를 하겠다. 파이썬을 기반으로 제작된 프로그램으로 터미널에서 명령을 줄 수 있다.

필수 옵션은 -u 공격할 URL이다. DVWA처럼 로그인 상태에서 공격할 때는 쿠키 정보를 추가로 주어야 한다. 그러면 SQL MAP이 로그인 된 것처럼 공격할 수 있다.

* 쿠기 값 아는 법 F12 개발자 옵션에서 Console -> document.cookie 입력하면 쿠키 값이 나온다.

sqlmap -u "공격 사이트 주소" --cookie="쿠키 값" 을 입력