-
[Renewal] webhacking.kr old-9 [900]$ 웹 해킹 $/webhacking.kr 2019. 12. 3. 23:17
문제를 살펴보면 1 2 3 이라는 링크가 존재합니다.
↑ ?no=1 일때 출력되는 화면
↑ ?no=2 일때 출력되는 화면
↑ ?no=3 일때 출력되는 화면
?no=3 일때의 출력되는 화면을 살펴 보면 칼럼은 id와 no가 있고, no=3의 id가 password이다 라고 적혀 있습니다.
칼럼이 주어지고 no=3인 레코드에서 id를 추출해야 하는 문제이므로 Blind SQL Injection 이라고 할 수 있습니다.
URL에 파라미터 값으로 아래와 같은 쿼리를 줘 보겠습니다.
해당 쿼리문은 맨앞 1자리인 조건문이 참이면 3을 반환, 거짓이면 1을 반환하는 쿼리입니다.
1은 참을 의미하므로, no=3이라는 값이 완성되어서 출력시에 ?no=3 의 화면이 출력이 됩니다.
if문의 조건문 자리에 1대신 substr과 같은 함수를 이용해서 id의 값을 하나하나 뽑아내는 작업을 해보면 될 것 같습니다.
하지만 숨겨진 필터링이 존재합니다. 필터링에 걸렸을때는 아래와 같이 Access Denied가 출력이 됩니다.
필터링 되는 값 : =, %20, or, and 등등
아래와 같은 쿼리문을 넣으면 참으로 no=3이 반환이 됩니다.
하지만 아래의 쿼리문을 넣으면 참도 거짓도 아무런 값이 나오지않은 화면이 출력이 됩니다.
위와 같이 그냥 Password : [버튼] 의 화면만 출력이 됩니다.
이게 어떻게 된일일 까요?
첫번째 문자열은 a라는 값이 출력이 되지만 2,3,4... 의 문자열들은 아무런 값을 출력하지 않습니다.
또한 Renewal 전의 webhacking.kr 9번문제 에서는 아무런 생각없이 참과 거짓의 반환값을 3,0 으로 주어주고 쉽게 id를 추출해서 Clear를 했었습니다.
일단 먼저 반환값을 3,0으로 해서 id를 출력하는 코드를 작성해 보겠습니다.
코드를 실행해 보면 아래와 같이 출력이 됩니다.
이렇게 쉽게 비밀번호를 찾을 수 있었습니다.
하지만 앞서 참거짓의 값을 3,1으로 넣으면 값이 안나왔었습니다.
그 이유를 한번 한번 알아 보는 시간을 가져보겠습니다.
9번문제에 존재하는 데이터 베이스 명 및 테이블 구조를 뽑아보려고 했으나 스키마 관련 문자열들이 전부 필터링에 막혀 있었습니다.
그래서 가상으로 이렇게 되어있다. 라고 가설을 세워보고 진행을 해봤습니다. ( 해당 가설로 세운 테이블 구조가 맞아 떨어져서 실제로 이런 구조를 띌 것이다 라고 생각을 하게 되었습니다. )
no 칼럼은 1 2 3 으로 되어 있을 것 으로 생각이 되며, id의 값은 apple를 시작으로 banana, alsrkswhaql 로 되어있을 것이라고 가설을 세우고 진행을 했습니다. 먼저 참과 거짓이 될 수 있는 수의 경우의 수를 세워서 자동화 코드를 이용해서 id의 값이 잘 나오는지 안나오는지를 먼저 확인해 보겠습니다.
상식적으로 보면 참이 1일때의 경우의 수가 전부 apple 이 출력이 되는데 당연한 결과 라고 생각이 되지만 참의 반환 값이 2일때 부터 이해가 되지 않는 부분이 발생하게 됩니다.
먼저 아래의 쿼리문을 보내서 결과를 확인해 보겠습니다.
id의 첫글자가 0x61("a")이여서 참의 값이나와서 no=3 인 레코드가 출력이 되었다고 이야기 할수도 있겠지만!
no=1 인 레코드에 존재하는 id의 값의 첫번째 글자도 0x61인 a입니다.
왜 no=3 인 레코드만 출력이 되는 것일까요 ?
그리고 그다음 쿼리문을 넣어보겠습니다.
3,1 에서는 첫번째 글자만 a로 출력이 되었습니다.
2번째 문자열도 뽑아 보겠습니다.
2개의 레코드가 출력이 됩니다.
2개의 레코드가 반환이 되서 no={ } <- 값에 이상한 값이 들어가서 위에서 봤던것처럼 Password 입력 버튼만 있었던것 같습니다.
위의 2가지의 예시를 분석해 보면 아래의 방식으로 데이터를 반환 하고 있었습니다.
첫번째 글자에서 no=3만 출력되는 이유는 아래와 같습니다.
id의 첫번째 글자가 a인지 비교를 하는데 no=1 부터 no=3 까지 총 3번을 비교합니다.
no=1의 레코드를 보면 id=apple 이기 때문에 3이라는 값을 반환을 합니다.
하지만 no=1과 no=3 즉, 1 != 3 이기 때문에 no=1의 레코드 값이 반환 되지 않습니다.
no=2의 레코드를 보면 id=banana 이기 때문에 1이라는 값을 반환하는데 이것도 위의 예시처럼 no=1을 반환하지만 no=2 와 같지 않기 때문에 반환을 하지 않는 것이였습니다.
마지막으로 no=3의 레코드를 보면 id=alsrkswhaql 였고 3이라는 값을 반환하기 때문에 no=3과 반환값인 no=3과 같은지 보고 같기 때문에 no=3의 레코드만 출력이 되는 것이였습니다.
id의 두번째 글자도 l이랑 비교를 해보면 아래와 같습니다.
no=1의 레코드의 apple 과 비교했을때 false 이기 때문에 1을 반환하는데 no의 값이 같기 때문에 no=1 레코드 출력!
no=2의 레코드의 banana 와 비교했을때 false 이기 때문에 1을 반환하지만 no의 값이 다르기 때문에 스킵!
no=3의 레코드의 alsrkswhaql 와 비교했을 때 true 이기 때문에 3을 반환해서 no의 값과 같기에 no=3 레코드를 출력하게 됩니다.
그렇기 때문에 2개의 레코드가 반환이 되어서 ?no=1 도 아니고 ?no=3도 아닌 페이지가 출력이 되는 것입니다.
3줄요약을 해보면 아래와 같습니다.
1. 조건절은 DB 레코드 하나마다 처리가된다.
2. 조건절은 1개 이상의 조건문으로 이루어져있다.
3. column 에 if문을 붙혀 사용할 때, if 안의 조건문이 참인지 거짓인지에 대해 해당 레코드와 column 값이 일치할 때 해당 column 내용을 반환한다.
다시 문제로 돌아오면 password 입력하는 곳에 alsrkswhaql를 입력하면 Clear!
'$ 웹 해킹 $ > webhacking.kr' 카테고리의 다른 글
[Renewal] webhacking.kr old-4 [300] (0) 2019.12.05 [Renewal] webhacking.kr old-10 [250] (0) 2019.12.04 [Renewal] webhacking.kr old-8 [350] (0) 2019.12.03 [Renewal] webhacking.kr old-7 [300] (0) 2019.12.03 [Renewal] webhacking.kr old-6 [100] (0) 2019.12.03