webhacking/sql, sql injection

webhacking.kr 2번

qkqhxla1 2014. 8. 11. 16:01

2번은 추측과 서브쿼리에 관한 지식이 필요합니다.

1. 소스를 보면 /admin이라는 관리자 페이지 발견.

/admin페이지에 들어가서 소스를 보면 폼 이름이 admin과 텍스트상자 이름이 password라는걸로

테이블명은 admin, 컬럼은 password라는걸로 추측..

2. /bbs/index.php 라는 곳에서 비밀글 발견. FreeB0aRd 라는 대문에 있는 문자열과

폼 텍스트박스 이름이 마찬가지로 password라는걸로 테이블명 FreeB0aRd, 컬럼명

password추측. (솔직히 조금 오바같아요.)

3. 쿠키에 time이라는 이름의 쿠키와 1407736636라는 이상한 값 발견.

값 뒤에 and 1=1같이 아무 값이나 인젝션했을때 메인 페이지 소스에서 시간 값 변경 발견..


기술보다는 엄청나게 추측이 요구되는 문제네요.... 

3.에서 참일시 (1407736636 and 1=1같은 값을 넣으면) <!--2070-01-01 09:00:01--> 라는 

시간값이, 거짓일시 (1407736636 and 1=0같은 값을 넣으면) <!--2070-01-01 09:00:00-->

이라는 시간값으로 참 거짓을 판별할수 있습니다. 이제 sql 인젝션에서 가장 자주 쓰이는 구문..

ascii(substr(컬럼,n,1))=1~127 이 구문으로 뽑아올 수 있습니다.

함수설명.

mysql에서 substr함수는 글자를 뽑아오는 함수.

substr(컬럼,시작위치,뽑아올갯수) 시작위치는 1부터 시작(0이 아님)하며 뽑아올갯수만큼 글자를 

뽑아옴. 인젝션시 일반적으로 하나씩 뽑아옴.

ex)

첫번째 결과는 전체 결과. 두번째는 첫번째 한글자만 뽑은 결과(substr(EMPNAME,1,1)) h만 뽑히고,

세번째는 두번째 한글자만 뽑은 결과. 두번째글자인 a가 출력된걸 알수 있습니다.

ascii함수는 해당 컬럼의 가장 왼쪽의 글자를 아스키코드 숫자로 출력합니다.

ex)


위와 같은데 ascii함수만 한번 더 씌웠습니다. h의 아스키코드값인 104와 a의 아스키코드값인 97이

출력되는걸 확인할수 있습니다.


그리고 서브쿼리. 위에서 time=1234567 and 1=1이런식으로 쿠키에 대입해보면 맞다는 시간이

나오는데 쿼리가 이런식으로 구성되있다고 추측할 수 있습니다.

select * from 테이블 where time=1234567 where부분이 참이면 어떤 동작을 해서 주석의

시간이 참인 시간을 출력하게 되죠. 거짓이면 거짓인 시간을 출력하고요.

그런데 여기서 time=1234567부분에 저희가 변경이 가능하죠. 이 부분에 또다른 쿼리를 넣을수

있습니다. and(select ascii(substr(password,1,1)) from admin)=97


이런식의 쿼리를 삽입하면 전체적으로 이런식의 쿼리가 될겁니다.

select * from 테이블 where time=1234567 and(select ascii(substr(password,1,1)) from admin)=97

해석해보면 time=1234567이고, admin테이블의 password컬럼에서 제일 앞글자 하나를

뽑아왔을시에 그 글자 아스키코드값이 97이면서(a이면) 시간값이 1234567이면 참,

아니면 거짓을 출력입니다. 시간값은 원래 참이니 admin테이블의 password컬럼에서

뽑은 첫번째 값의 아스키값이 맞아야겠죠? 표현 가능한 아스키코드값은

1~127까지이기에 대부분 끝자리에 포문으로 1~127까지 돌려가면서 참 거짓 판별을

합니다. 이렇게 끝까지 자리까지 뽑아내면 됩니다. 


그런데 몇개를 뽑아내야 될까요?

length라는 길이를 출력하는 함수가 있습니다.


hacker의 길이인 6을 출력합니다. 위의 쿼리에서도 이걸 응용하면 됩니다.

password의 길이를 알려면 time=1234567 and (select length(password) from admin)<20

이런식으로 검사를 해주면 됩니다. admin테이블에서 password컬럼의 길이를 가져와서

20미만이면 참이되겠죠? 그러면 참인 시간이 출력될겁니다. 이런식으로 숫자를 조금씩

줄이면 time=1234567 and (select length(password) from admin)=10을 했을때

참이 나옵니다. 길이가 10글자라는 소리죠. 위의 ascii(substr(password,n,1))로

10번 반복하면 됩니다.

코딩을 하면 끝납니다.

and(select ascii(substr(password,i,1)) from admin)=j

이런식으로 만들고, i는 1~10까지 10글자, j는 1~127까지 반복하면서 맞는지 판별하는

코드를 짜면 됩니다.


이걸로 비밀번호를 뽑아내고, FreeB0aRd 에서도 위와 똑같이 숫자만 바꾸어서 비밀번호를 

뽑아낸 후 조합하면 클리어입니다...

'webhacking > sql, sql injection' 카테고리의 다른 글

webhacking.kr 7번 소스코드  (0) 2014.08.19
webhacking.kr 7번  (0) 2014.08.19
rubiya님의 문서  (2) 2014.08.15
webhacking.kr 8번  (0) 2014.08.10
webhacking.kr 2번 소스코드  (0) 2014.08.10