[Webhacking.kr] old-07 (SQL injection 활용문제)

728x90
반응형

etc-image-0

1. 서론

본 포스팅 시리즈는 webhacking.kr의 문제 풀이를 하면서 정리한 자료이다.
필자가 풀이한 방법들이기 때문에 완벽하지 않을 수도 있다는 점을 참고 바란다. (지적과 조언은 언제나 환영이다)

이번 문제는 old-7, SQL injection 활용이 필요한 문제이다.

2. 본론

스크린샷 2022-03-09 오전 12.53.36.png

이번 문제를 접속해보면 위와 같은 화면이 나타난다. 처음 접속시에 GET 파라미터 쪽에 "val"라는 항목에 1이 전달되어있다.

스크린샷 2022-03-09 오전 1.06.15.png

이건 이번 문제의 소스코드이다.

우선 코드 상단을 보면, 우리가 처음에 봤던 GET 파라미터 "val"를 $go에 대입하는 걸 확인할 수 있다. 그리고 이 값을 정규식 필터를 통해 특정 문자가 포함될 경우 바로 종료가 되도록 되어있다. 금지 문자는 다음과 같다.

스크린샷 2022-03-09 오전 1.08.33.png
금지문자 2, -, +, from, _, =, \s, *, /

그리고 위 if문을 통과한다면 그 다음은 SQL쿼리를 요청하는 부분이 나온다. 여기서 "mysqli_query()" 함수는 쿼리문이 실패할 경우 false를 리턴하는데, 이때 or die()로 인해 즉시 종료되게 된다.

그리고 이 쿼리문이 정상적으로 실행이 되었 경우, 맨 마지막 쪽에서 쿼리 결과의 첫번째(SELECT문으로 가져온 lv 값으로 추정됨)에 따라 여러 분기로 나귀게 된다. 이때 그 값이 2일 경우 이 문제를 해결할 수 있게 된다.

일단 먼저 생각해볼 수 있는건, lv의 값이 2가 되면 되니까 $go 안에 2를 넣어 실행해보는 것이다. 하지만 문제는 정규식 필터로 인해 직접적인 문자 "2"를 넣는 것은 불가능하다. 그래서 2를 사용하지 않고 2를 표현할 방법이 필요하다. 필자는 이를 "8%3"으로 해결하였다(8을 3으로 나눈 나머지).

스크린샷 2022-03-09 오전 1.28.46.png

그래서 "val"에 "8%3"을 대입하고 요청해보면, 아쉽게도 "query error"가 나타난다. 이 메세지가 나타났다는 건 다행히 현재 쿼리문이 실행이 불가능하진 않다라고 볼 수 있고, 아마 "chall7" 테이블 상에 lv의 값이 2인 행이 없는 것으로 추측된다.

그렇다면 방법은 임의로 lv의 값을 2로 만드는 수 밖에 없다.
이때 사용할 수 있는 방법으론 union이 있다. lv에는 "chall7" 테이블 상에 존재하지 않는 lv의 값을 대입하여 결과값이 없는 상태를 만든다음에 union을 이용하여 "select(8%3)"을 엮어주면 lv의 값으로 2가 넣어지게 될 것이다 (굳이 괄호를 쓰는 이유는 브라우저의 URL 입력창을 통해 SQL injection을 시도하기 때문에 스페이스문자는 URL인코딩으로 값이 바뀔 수 있어서 최대한 스페이스문자를 쓰지 않고 쿼리를 만들기 위함이다).

스크린샷 2022-03-09 오전 1.39.48.png
필자의 경우, 이미 정답을 맞춘 이력이 있기 때문에 "already solved" 메세지가 떳다.

SQL 쿼리를 실행하는 부분에서 랜덤 값 1~5를 통해 5가지 쿼리문을 통해 랜덤하게 실행하도록 되어있는데, 어차피 한번쯤은 1이 나올테니까 위 이미지처럼 injection을 시도하고 정답이 아니라고 하면 새로고침을 연타 하다보면 정답이라고 뜰 것이다.

728x90
반응형