이전에 했던 UNION SQLI는 화면에 select한 결과가 출력되는 경우에 사용한다고 말했었습니다. 이번에는 결과가 Error 메시지로 출력이 되는 경우에 사용할 수 있는 Error Based SQLI에 대해 사이트에서 실습하며 알아보겠습니다.
Error Based SQLI를 사용하는 경우는 잘못된 SQL 쿼리를 데이터베이스에 보낸 경우, 해당 쿼리가 왜 틀렸는지를 반환해줍니다. 개발자가 디버깅을 위해서 이 코드를 페이지에 출력되도록 해놓고 이를 방치한 경우에 해당 오류를 이용해서 Error Based SQLI를 실행할 수 있는 것입니다.
이렇게 문법 오류가 나오는 경우에 extractvalue() 함수를 통한 XPath 오류로 SQLI를 사용할 수 있습니다. extractvalue([xml값], [xpath 표현식])의 형태로 사용되는데, xml값에서 xpath표현식에 해당하는 데이터를 추출하는 함수입니다. 그런데 이 때 xpath 표현식이 잘못된 경우에 xpath 에러가 나오는데 중요한 부분은 이 xpath 에러 부분에 해당하는 sql쿼리는 적힌 그대로 반환하는 것이 아니라 실행한 결과값으로 반환한다는 것입니다.
해당 사진에서는 xpath 표현식에 : 를 붙이면 에러가 나온다는것을 이용해 concat() 함수로 select문에 :을 붙여줘서 에러가 나오도록 한 모습입니다. 여기서 select 'normaltic'을 사용했으니 에러부분에도 select 'normaltic' 이라고 나왔어야 하는데 그냥 normaltic이 나온 부분이 보이시나요? 이렇게 select문의 결과를 정상적으로 반환한 모습을 볼 수 있습니다.
xpath 에러를 기반으로 하는 Error Based SQLI는 ' and exractvalue('1', concat(0x3a,([SQL문]))) and '1'='1 형태로 사용 가능합니다. 해당 사이트에서는 ID를 중복검사하기 위해 ID를 검색하는 SQL문이 있고, 우리가 넣는 부분은 앞 뒤로 '로 감싸여 있을테니 먼저 '를 써서 앞 '부분을 닫고, exractvalue()를 사용하기 위해 and문으로 감싸줍니다. 그 후 extractvalue()함수에 xml값 부분에는 어떤 값이 와도 상관없으니 그냥 1을 넣어주고, concat()함수로 :과 select문을 이어주면 완성입니다. 이번 테스트 사이트에서는 아무 정보 없이 그냥 flag를 찾아야합니다. 그러니 모든 데이터베이스와 테이블을 뒤져봐야겠군요.
먼저 DB의 이름을 찾아보겠습니다. 위에 적어둔 format에서 SQL문 부분에 select database()만 적으면 됩니다.
DB의 이름은 errSqli입니다.
다음은 테이블 이름입니다. 테이블 이름은 이전 UNION SQLI 부분에서 적어두었던 방법을 이용하면 됩니다.
그런데 테이블 이름이 아니라 다른 에러가 나왔습니다. 직역해보면 서브쿼리가 1개의 로우를 더 리턴했다는 뜻입니다. 여기서 알 수 있는 것은 Error Based SQLI는 한 개의 리턴값만 받을 수 있다는 것을 알 수 있습니다. LIMIT문으로 해결해줍시다.
테이블의 이름은 flagTable이군요.
마지막으로 컬럼 이름을 알아봐야겠죠? 컬럼 이름도 이전 UNION SQLI 부분에서 알아봤었습니다.
limit 0,1에서 나온 정보는 idx로 flag와는 무관해보여 다음번호인 limit 1,2를 검색해본 결과 flag라는 컬럼을 알 수 있었습니다.
이제 마지막으로 flag 데이터를 추출해내면 끝입니다.
얻은 정보를 조합해 flag 획득 성공!