2019. 4. 14. 22:26ㆍWeb Hacking/Webhacking.kr
안녕하세요!
오늘은 webhacking.kr에서
250점 문제인
21번 문제를 풀어보도록 하겠습니다!
문제에 들어가니 아래와 같이 나오네요!
대문에 크게
BLIND SQL INJECTION
이라고 광고하고 있네요
뭐 제가 밑에 박스에 값을 넣고
제출 버튼을 누르면
Result에 결과가 뜨겠죠?
BLIND SQL INJECTION = 서버에 요청을 보내어,
서버의 참/거짓 값을 토대로 값을 알아내는 INJECTION 입니다!
기존에 sql injection과 달리 한번에 BAAM!하고
결과가 나오지 않아요 ㅠㅠ
그래서 뭐 일단은 뭐라도 좋으니
a를 입력해 보았습니다!
그랬더니 결과창에
False
"응응 너 틀림 ㅋ"
이라고 뜨네요..?!
근데 신기하게 id랑 pw parameter도 있나보네요!
그리고 위에 url 결과창이 뜨니
당연히 get방식이겠죠?
근데 sql 문제 풀 때 보면,
no는 number를 항상 칭하는 그런
parameter였기 때문에
알파벳이 아닌 숫자를 넣어보기로 했습니다!
그래서 no=1을
넣었더니 아래와 같이 true가 뜨네요!
뭐지? id랑 pw에 아무값도 안줬는데 왜 참이 뜨는거야....?!?!?!?!
일단은 그냥 계속 쭉 다른 숫자 값들을
크기 순서대로 넣어봤습니다!
no=2를 넣고 실행을 하니!
아래와 같이 또 true가 뜨네요!
근데 아무리 봐도
여기서 no는 number가 들어가는 곳이 맞기 때문에!
( sql injection 할 때 no parameter에는 ' 나 "가 들어가지 않았음)
그래서 싱글쿼터 우회를 안하고
그대로 query를 inject 해봤습니다!
no=2 and length(id)>10 #(뒷 부분 주석처리 됨)
그랬더니 이건 False라고 뜨네요!
no=2인 놈의 id길이는 10보다 작거나 같다!
흠...
no=1과 no=2 둘 중 하나에
저희가 원하는 값이 담겨 있을지도?!
제가 일일이 부등호랑 직접 노가다로 대입해서 찾았습니다!
no=2 일때 그 아이디의 길이는 5이다!
혹시나 해서 no=1일때 아이디 길이도 확인해보니!
아이디 길이가 5네요!
이후에 제가 length(id)대신
length(pw)으로 pw길이도 확인해봤는데!
아래의 표와 같았습니다!
그럼 no id pw
1 5자리 5자리
2 5자리 19자리
근데 아무래도 5 자리는 금방할 거 같으니까
19 자리 비밀번호부터 구해봅시다!
"그럼 뭐 저 짓을 계속 할꺼냐?"
"날 샐꺼냐?"
당연히 python으로 풀어야죠!
코드가 좀 난해하게 보여도 그렇게 어렵지 않습니다!
혹시 몰라서 주석까지 적어놨습니다!
웹 해킹할 때 쓰이는 python library는 request입니다!
그래서 import requests라고 일단 선언합니다!
(= request 라이브러리 쓸 꺼야!)
그 다음에 answer라는 변수를 선언합니다!
주석에 적었듯이, 정답을 적을 공간입니다!
일단은 아무것도 없으니 빈칸으로 해놔야 겠죠?
그래서 ""이렇게 더블쿼터를 붙여놨습니다(=빈칸)
그리고 for문을 돌립니다!
형식은 for 변수 in range( 숫자, 숫자): 입니다!
c 언어에서 for문과 거의 유사합니다!
다만 여기서 range가 좀 다릅니다!
제가 밑에 적은 코드를 보시면 range(1,20)이라고 적혀있는데
여기서는 1~20이 아니라!
1~19까지입니다!
왜냐면 비밀번호가 19자리이기 때문에
각 자리마다 맞는 값을 찾아야 하기에!
근데 여기서 for 문을 한번 더 돕니다!
첫 번째 for문은 비밀번호 자리 수 만큼 도는 것이고!
두 번째 for문은 각 자리가 무슨 값인지 확인하기 위해서
브루트포싱하는거죠!
예를 들자면 1번째 글자 a니? b니? c니? d니? e니? f니? .... (찾을 때 까지)
그러다가 첫 번째 글자 찾으면
두 번째 글자로 넘어가서 다시
a니? b니? c니? d니? e니? f니? ... (찾을 때 까지)
그렇게 19번을 하는 거에요!
어 range에 숫자가 다른데요?
왜 range(97,127)에요?
왜냐하면 알파벳 소문자 a가 97부터라서 그래요!
그럼 대문자랑 나머지 문자는요....?
원래는 그런 문자들도 추가했었는데요!
앞에 뽑히는 3,4 글자 보니까 다 소문자길래
그냥 ascii 값 97 (=a)부터
검색하기로 했습니다!
url변수에는 저희가 어디 url로 보낼껀지 적으면 되요!
그래서 url에 있는 webhacking.kr 주소 긁어 오시구요!
그 뒤에 parameter 부분부터는
substring 함수는 단어를 자를 수 있는 함수입니다!
substr( 무엇을 자를꺼냐, 어디서 부터 자를꺼냐, 몇 글자 자를꺼냐)
그래서 아래를 보시면
substr(pw,%d,1)라고 했으니
"pw를 %d 번째 부터 1글자 잘라라!"
실제론 pw를 1번째 부터 1글자 잘라라!
pw를 2번째 부터 1글자 잘라라!
`````
pw를 19번째부터 1글자 잘라라!
이렇게 되겠죠?
한 마디로 각 글자를 추출 하는 거에요!
그래서 추출한 글자를 ascii 값으로 바꿔줄꺼에요!
ascii(문자열) => 문자열을 ascii 표에 해당하는 숫자로 변환시켜줌
그래서 그 값을 %d 와 비교한다는거는
97부터 127사이의 ascii 값과
ascii(substring( ))값을 비교한다는 거에요!
그리고 뒷 부분은 뭐 필요없으니 #를 달아서 주석처리를 합니다!
그리고 url 뒤에 적은 %( i , j )는
각각 %d %d에 순서대로 들어갑니다!
이거랑 똑같다고 보시면 됩니다!
c언어에서 printf("this is number %d",num)
<num변수에는 1이 들어가 있다고 가정>
그 다음에는 간단합니다!
cookies 변수에는 웹사이트에 저희가 어떤 사용자인지
알려주기 위해 쿠키 값을 적습니다!
형식은 다음과 같습니다!
cookies={' 쿠키이름 ': ' 쿠키 값 '}
여기까지 하면 저희가 request할 모든 것들을 세팅했기 때문에!
보내야합니다!
그때 이제 requests에 점을 찍고
method를 정합니다!
request.post인지 request.get인지!
여기서는 get이니
request.get( )!
그리고 get으로 보낼 때 같이 보낼 값들을 적습니다!
get방식으로 어떤 url에 보낼건데?
쿠키는 뭔데?
| |
▼
request.get(url,cookies=cookies)
이렇게 request를 보내면 서버에서 응답이 오겠죠?
True다 아니면 False다
그걸 알기 위해서 res라는 변수에 해당 정보를 담습니다!
그리고 이 응답 값을 text형식으로 바꿉니다!
res => res.text
왜 바꾸냐고요? True인지 False인지 단어 찾아야 하니까요!
그래서 res.text.find('True')
참인 단어를 찾았다!
(단어를 못 찾으면 -1을 반환하는데, -1이 아니니 단어를 찾았다고 조건 준 거에요!)
우리가 원하던 글자니 저장해야겠죠?
answer 변수에?
answer = answer + chr( j )
chr 함수에 대해서는 주석에 적어놓았듯이!
ascii 숫자를 입력하면 그 표에 해당하는 문자로 바꿔주는 함수입니다!
그리고 확인하고 싶어서 그 글자 출력해주고요!
break을 걸어서 루프를 탈출하고
다음 글자 찾으러 갑니다!
만약에 -1이 반환 되어서 못 찾으면
현재 숫자 출력하고
계속 j in range for문 돌리세요!
그리고 for문이 다 돌려지면
here is the answer! 라고 출력하고!
answer에 담겨진 값을 출력합니다!
그러면 아래와 같이
blindsqlinjectionkk라고 나옵니다!
이걸 이제 authentication 페이지가서
인증해주시면
아래와 같이 클리어 메세지가 뜹니다!
고생하셨습니다!
'Web Hacking > Webhacking.kr' 카테고리의 다른 글
[어설픈] webhacking.kr old-56번 문제풀이 (0) | 2020.01.06 |
---|---|
[어설픈] webhacking.kr 18번 문제풀이 (0) | 2019.03.09 |
[어설픈] webhacking.kr 10번 문제풀이 (0) | 2019.03.07 |
[어설픈] webhacking.kr 32번 문제풀이 (1) | 2019.02.28 |
[어설픈] webhacking.kr 36번 문제풀이 (0) | 2019.02.26 |