webhacking.kr 2번 문제

Gwon SeolHyeong·2021년 1월 6일
1

Webhacking 2번

Blind SQL Injection

이번 문제를 풀기에 앞서 보안 책과 안드로이드 모의해킹 책을 공부하고 있는 중이라서 벨로그 자체에 소홀해졌다.

그런 의미로 후에 CTF도 준비할 겸 webhacking(old) 문제를 풀며 기록해보는 시간을 갖기로 함.

너무 간단한 문제는 넘어갈 수 있다는 점을 말씀드리고 싶습니다.

첫 화면에 나오는 것은 저게 끝이다..

우선 Burf Suite를 이용해서 프록시를 잡아보도록 한다.

특별한 점은 쿠키 값으로 time이 잡혀있는 것을 확인할 수 있었다.

뒤로 계속 넘겨주면

우선 url에 admin.php를 붙이면 admin 페이지로 넘어간다는 것을 예측할 수 있었다.

역시 그냥 나와줄 리가 없었다.. pw를 찾아내야 하는 것이 시작이었다.

테스트 삼아서 아무 문자나 입력해보자.

별 다른 특별한 점은 없었다.

혹시나 SQLi 문제일거란 생각에 ' or 1=1 -- 과 같은 참 값을 대입해봤지만 같은 반응이었다.

여기서 힌트가 더 이상 보이지 않기 때문에 앞쪽으로 다시 이동해서 분석하던 중 주석 값이 눈에 띄었다.

시간이 나와있는 값은 기존 현재 시각을 가리키고 있었지만, time 값을 1로 변경 후 프록시를 넘긴 결과 위와 같은 형태로 나타나는 것을 알 수 있었다.

또한, 각종 수식을 넣어본 결과 참일 경우 09:00:01 / 거짓일 경우 09:00:00 으로 나타나는 것을 볼 수 있었다.

여기서 Blind SQL Injection이 적용될 수 있다고 생각을 할 수 있었다.

처음에는 Python3를 이용해서 스크립트를 만들어 볼 생각을 했으나.. 아직 실력이 부족하기도 하고 라이브러리에서 가져온 스크립트가 에러가 나서 조금 무식하지만 수작업을 실시하기로 했다.

먼저 해당 위치에 있는 DB 내의 테이블 개수가 몇 개인지 파악하기 위해 count 구문을 사용

(select count(table_name) from information_schema.tables where table_schema=database());

time 값에 해당 구문을 넣고 프록시를 넘기면 다음과 같은 값이 나오는 것을 알 수 있다.

2로 값이 나오는 것을 보고 해당 DB에는 테이블이 2개라는 것이다.

다음으로는 첫 번째 테이블 이름의 길이를 알아보는 작업을 실시한다.

(select length(table_name) from information_schema.tables where table_schema=database() limit 0,1);

여기서는 길이를 알기 위한 length문을 사용하도 뒤의 limit을 이용하여 첫 번째 테이블 이름만을 대상으로 하는 구문을 작성한다.

그렇게 작성한 이후 나오는 화면은

길이는 13자리라는 것을 알 수 있었다. 두 번째 테이블 이름의 길이도 마찬가지로 알아낼 수 있다(limit 1,1) 로 설정하면 가능.

다음은 첫 번째 테이블 이름의 첫 번째 문자를 알아내는 구문을 작성한다.

여기서는 문자열을 숫자로 나타내기 위한 ascii 와 substr 구문을 사용한다.

(select ascii(substr(table_name, 1, 1)) from information_schema.tables where table_schema=database() limit 0, 1);

1분 37초가 나왔는데 이것을 초로 계산하면 97이다. 여기서 아스키 코드 표를 참고하여 문자를 13자리 하나하나 계산해서 조합한다. (table_name, n, 1) => n = 1~13

조합하게 되면, admin_area_pw 라는 테이블 명이 나오는 것을 알 수 있다.

pw가 들어가는 것을 보니 이 테이블에 pw가 존재할 것이라고 생각되었다.

테이블 내에 컬럼의 개수를 알아보기 위해 column 구문을 이용하여 구성한다.

(select count(column_name) from information_schema.columns where table_name="admin_area_pw");

컬럼 개수가 한 개인 것으로 나오는 것을 알 수 있다.

이제 컬럼의 이름 길이를 알아보자.

(select length(column_name) from information_schema.columns where table_name="admin_area_pw");

길이는 두 글자이다. 이제 마찬가지로 테이블 명을 알아내던 것 처럼 아스키코드를 이용하여 알아낸다.

(select ascii(substr(column_name, 1, 1)) from information_schema.columns where table_name="admin_area_pw");

1분 52초를 초로 계산하면 112로 아스키 값을 비교하면 p라는 것을 알 수 있었다.

마찬가지로 남은 문자 하나도 알아보면 w로 두 문자를 조합하면 'pw'라는 문자가 조합된다.

마지막으로 컬럼 내 값의 길이를 알기 위해서 구문을 조합한다.

(select length(pw) from admin_area_pw);

pw의 값의 길이는 17글자다.. 자동화 스크립트를 못 짠 댓가로 노가다를 시작한다..

(select ascii(substr(pw, 1, 1) from admin_area_pw);

이 구문에서 1,1 을 17, 1까지 실행시킨다..

첫 번째 1,1 을 실행시키면 107이 나온다. 아스키코드 값을 보면 k가 나온다.

마찬가지로 전부 다 실행시킨다면 패스워드는 원하는 값이 나오는 것을 알 수 있다.
(혹시나 문제를 푸시는 분들이 계시다면 직접 해보는 게 좋을거라고 생각하기 때문에 답은 적지 않겠습니다.)

값을 입력하면 나오는 결과 값을 보고 성공한 것을 알 수 있었다.

필자 또한 Blind SQL Injection을 처음 접했기 때문에 구글링을 꽤나 많이 했고 참고한 사이트도 많았다. 복사 붙여넣기가 아닌 직접 작성하며 왜 이런 구문이 발생하나 생각하며 분석하니 이해에 도움이 된 것 같다.

이 글을 보고 참고를 하는 사람도 필자와 같은 방법으로 하면 분명 도움이 될 것이다.

profile
정보보안 공부

0개의 댓글