본문 바로가기

Webhacking/Webhacking.kr

[Webhacking.kr] old-09번 문제 풀이

728x90
반응형

9번 문제는 1, 2, 3번 버튼 그리고 password 입력 버튼이 있다.
하나씩 눌러보았다.

1번은 Apple이

2번은 Banana가

3번에는 Secret이라고 나타난다. 하지만 추가적인 정보가 더 공개되어있다.

  1. Table의 컬럼명은 id, no이다
  2. 3번의 id는 password이다

컬럼명을 알려주는 것을 통해 확실히 알 수 있는 것은, 이 문제가 SQL Injection 문제라는 것이다.
그래서 인젝션을 몇차례 시도하다보니 아래와 같은 문자들이 필터링 되어있음을 확인할 수 있었다.

  • =, <, >, +, -  등의 연산자
  • %20, %09, %0a 등의 공백
  • ', " 와 같은 쿼터
  • substring, left, binary, ascii, hex 등의 sql function
  • or, and, &&, ||

기초적인 구문으로 인젝션은 할 수 없게 만들어둔 것 같다. (역시 900점인가...)
그래서 아래처럼 우회를 시도했다.

  • 공백 : 괄호
  • 문자열 슬라이싱 : right
  • = : like
  • 쿼터(', ") : hex값 사용

결과적으로 위와같이 공격 payload를 완성했다.
여기서 가장 중요한것은 바로 no가 3일때의 id값을 얻기위해서는 if문의 조건이 true일때 무조건 3이어야 한다는 것이다. 
그렇지 않으면 정상적인 결과가 나오지 않는다. 이유는 간단하다.

if 문에 있는 조건은 최소한 3번 검증한다. no가 1일때 2일때 3일때 각각 말이다.
만약 조건에 성립하는 id가 no 3번에 대한 id라고 가정했을때, true값이 3이 아닌 다른값이 된다면,
if문을 통해 조회한 데이터의 no는 3인데, 쿼리의 조건은 no가 2일 때의 값을 불러오기에 아무것도 조회되지 않는다.
즉 비교가 2번 이루어지기 때문에, 찾고자 하는 no를 if의 true문에 넣어야한다는 것이다.

아무리 쉽게쓸래도 쉽게 쓸수가 없어서 이걸 정리하자면 아래 두개 조건은 동일하다고 생각하면 된다.

  • no=(if(right(id,1)like(0x45),3,200))
  • no=3 and right(id,1)like(0x45)

이걸 알지 못하면 아무리 시도해도 문제가 풀리지 않는다.
그래서 900점 짜리가 아닌가 싶다.

하여튼 열심히 풀이를 위한 blind sql injection 스크립트를 제작하여 역시나 Github에 올려두었다.
like를 사용했기에 이진탐색과 같은 빠른 탐색방법 사용이 불가하여, 순차탐색을 그대로 진행했다.
참고하고자 하는 사람은 참고하면 되겠다.
(최적화, 효율성을 고려한 코드는 아니다.)

Github 주소 : github.com/KwonHyeonJun/Wargame_POC/tree/main/1.%20webhacking.kr/old-09

여기서 또 중요한 것. 스크립트 실행 결과는 현재 소문자로 나왔지만, 사실 이 문제는 대소문자를 완벽하게 구분할 수 없다.
ascii, ord, binary 등의 함수를 모두 필터링 해두었기에, 대 소문자를 구별할 수 있는 방법이 없다.
(mysql은 기본적으로 대 소문자를 구별하지 않음)

그래서 스크립트는 hex값으로 비교하면, 먼저 나오는 대문자로 값을 뽑아내는데,
pw로 검증해보니 대문자가 아닌 소문자임을 확인하여 소문자로 답을 뽑아내도록 코드를 수정했다.
참고 바란다.

풀었다!

이번문제는 사실 푸는건 진작에 풀었는데, 대 소문자를 명확히 구분하고 싶어서 삽질을 이틀이나 했다.
하지만 다른 풀이를 보아도 따로 대소문자를 구별하는 사람은 없는것 같다. 그래서 이 문제는 좀 아쉬웠다. 완벽한 풀이가 불가해서...
(혹시나 대소문자 구별방법이 있다면 고수님들 댓글로 알려주세요...)

728x90
반응형