SQL injection/webhacking

webhacking 51번

ys.k 2022. 8. 19. 01:39

포스팅에 앞서 내용이 틀릴 수도 있으며, 해당 부분 지적은 감사히 받겠습니다.
어느덧 웹 해킹 문제들도 거의 다 풀어간다.
51번 문제이다.

admin페이지라고 뜨고 로그인 창이 있다.
소스코드를 먼저 보자.

문제 해결에 필요한 부분만 가져왔다.
이번엔 post 방식으로 id와 pw를 입력받는다.
id에서는 addslashes가 적용되어있으며, pw는 md5로 인코딩하며 16자리까지 나타낸다.
md5() 함수의 인자가 true로 주어졌을 경우 16자리, false일 경우 32자리이며 기본값은 false이다.
db내부에 있는 어떤 id이든 로그인에 성공하면 문제는 해결된다.

하지만 pw 부분이 이상하다.
id는 정상적으로 addslashes를 거친 뒤 검색하지만, pw는 md5로 인코딩 된 값 그대로를 검색한다.
여기서 우리는 sql injection의 where 절 문법의 기초를 확실히 알아야 할 필요성이 있다.

문제의 핵 심상 id보단 pw부분에서 해결방법을 찾아야 한다.
따라서 id는 쉬운 값들로 무수히 많이 들어가 있을 것이라 추측한다.
입력한 pw 값으로 and 이후의 조건문을 참으로 만족시킨 후, id값만 유효한 값을 찾으면 된다.

그리고 이번 문제를 풀다가 db에서의 신기한 비교 연산 공격을 하나 배우게 되었다.
false sql injection다.
false sql injection
ex) select id from table where id='abc'의 결과는 abc 아이디를 출력하지만
ex) select id from table where id=0의 결과는 table에 있는 모든 id를 출력한다는 점에서 시작한다.
ㄴ typecasting 중 문자열을 int형으로 치환 시 0이 되기 때문

ex) pw = 'aaa'='bbb' 이면, pw ='aaa' -> false이고 false(pw='aaa') = 'bbb' -> false = false -> true가 된다.
따라서 pw = true로 인식되어 우회를 할 수 있게 된다.
이것이 false injection이다.
개념이 생소하여 구글에서도 많은 정보를 찾아볼 순 없었다.
필자는 이곳을 참고하였다.
https://blog.pages.kr/1237

False SQL Injection and Advanced Blind SQL Injection

######################################################################### # # # Exploit Title: False SQL injection and advanced blind SQL injection # # Date: 21/12/2011  # # Author: wh1ant  # # #..

blog.pages.kr


다시 문제로 돌아가자.
쿼리 : select id from chall51 where id='{$input_id}' and pw='{$input_pw}'
select id from chall51 where id='{$input_id}' and pw='a문자열'='b문자열' 을 만족시키면 된다.
그러기 위해서는 md5 인코딩 결과가 아무 문자열'='아무 문자열 인 값을 찾으면 된다.

값을 적당히 뽑아낸 후 ctrl + c를 눌러 중단시켰다.
해당 파이썬 코드는 밑 블로그를 참고하였다.
https://dyeonee.tistory.com/89

[Wargame] Webhacking.kr - old 51

문제 화면 - Admin page 를 출력하며, ID와 PW를 입력할 수 있는 폼이 출력된다. - 소스코드를 확인해보도록 하자 ! 소스코드 - id 값에 대하여 addslashes 함수를 적용하고 있으며, - pw의 경우는 md5 함수가

dyeonee.tistory.com

이제 값들 중 아무거나 하나 입력하면 문제가 해결된다.
필자는 마지막 값인 14033705로 진행해보도록 하겠다.


풀리지 않는다.
혹시나 해서 id 값을 admin으로 진행해봤다.

풀리긴 했지만 찝찝하다.
분명 소스코드에선 아무 id나 로그인해도 풀리게 되어있었다.
아마도 그냥 admin page라 admin만 로그인 가능하게 해 둔 것 같다.
문제 해결


하지만 여기서 반드시 알고 넘어가야 할 디테일이 있다.
바로 인코딩 값이 '='숫자 형태로 오는 i의 값은 pw로 넣어도 문제가 풀리지 않는다.
그 이유는 typecasting을 할 때 문자열의 가장 앞의 값이 숫자면 그 값으로 치환되는 것 같다.
ㄴ 맨 앞의 값이 1-9이면 true를 반환 0, 그 이외의 문자면 false를 반환한다.
한번 해당 값인 2632003으로 실험해보자.

사실 스크린 샷으로는 증명해줄 방법이 없지만, 이 문제를 푸는 사람들은 한 번씩 꼭 테스트해봤으면 좋겠다.

시행착오
1. 3개의 다른 문자열을 같다고 비교하면 true 값이 나온다. ex) 'a'='b'='c' -> true
ㄴ 1. 'a'='b' -> false
2. false(0)='c'(false) -> true
2. 별개로 pw = 0을 넣어도 참값이 나온다
ㄴ pw 역시 문자열이기 때문에 0과 비교 도중 typecasting이 일어나고 0=0 -> 1이기 때문이다.
3. '='숫자 형식의 값은 우회에 실패한다.