Error Base SQL Injection을 이용한 Database table, column 이름 알아내기

Step 1 Error Base SQL Payload 준비

select * from userdata where name='' 은 입력받는 유저 이름에 따라 데이터를 제공하는 sql 문이다.

여기서 sql injection이 가능하다면  아래와 같은 코드를 집어넣어 에러문구에 tyrell을 포함하여 출력할 수 있다.

mario' and updatexml(null,concat(0x3a,(select 'tyrell')),null) and '1'='1 
코드가 있다면'

-> select * from userdata 
where name='mario' and updatexml(null,concat(0x3a,(select 'tyrell')),null) and '1'='1'

위 코드를 설명하자면

UPDATEXML(XML_형식, XPath_string, new_value); 

UPDATEXML의 경우 문서의 노드 값을 변경하는 함수이다. 문법은 처음 입력은 xml이 string 형식인지 doc 형식이지 등을 결정하는 칸이고 두번째 xpath는 경로로 해당 경로로 찾아가서 3번째 인자인 새로운 value 값으로 치환해준다. 만약 xpath가 틀릴 경우 xpath를 오류 설명에 포함해 함께 반환한다.

이때 xpath에 경로형식이 아닐 경우도 이 오류를 반환하는데 이를 이용하여 테이블과 컬럼명을 알아내는 것이다.

concat의 경우 문자를 이어주는 역할을 한다. 

저렇게 mario라는 계정이 있다면 name=mario는 참이고 '1'='1'도 참이기 때문에 updatexml을 실행시켜 참인지 확인하게 된다. 이때 updatexml의 경로에 0x3a 을 집어넣게 되면 경로에 문제가 생겨 자동으로 에러를 반환한다. 0x3a는 아키아2 코드의 : 라는 문자이다. 이렇게 되면 에러를 출력할 때 :tyrell을 출력하게 된다. 즉 에러 문구에 코드가 실행되어 출력되는 것이다.  맨뒤에 '1'='1' 논리연산을 확실하게 동작하기 위해서 집어넣은 것이다.

아래는 나의 logindb를 이용하여 사용한 예제이다.

보게되면 updatexml 안에 select database()를 쓴 것을 볼 수 있다. 이는 database의 이름을 출력하는 것으로 xpath syntax error를 보게되면 ':logindb'를 출력된 것을 볼수 있다. 이는 실제 database 이름과 같다는 것을 볼 수 있다.

updataxml과 비슷한 코드로는 Extractmxl이 존재한다. 

extractvalue(xml_target, xpath_expr) 로 xml_target에서 xpath_expr과 일치하는 xml 노드를 반환하는 함수이다.

이를 응용하면

select * from login where login_id='aa' and extractvalue(0x3a, concat(0x3a,(select database())));

가 될것이다. 이를 적용하면 updatexml과 같은 에러 결과가 나오게 된다. 

 

이를 이용하여 select database() 위치에 table 이름이나 열을 알아내는 코드를 넣으면 알아낼 수 있다. 이를 통해 

database의 구조를 알아내어 값을 추출해 낼 수 있는 것이 Error SQL injection이다.

+ Recent posts