Lord of sql injection - orc 풀이 |
los 4번 orc에 대한 풀이 포스팅입니다.
이전 문제들과 다르게 쿼리문이 두개가 존재한다는 것을 볼 수 있습니다.
문제 접근
제가 색칠한 라인을 살펴보면, 한마디로 정의해서 이 문제는 admin계정의 password를 알아내는 문제입니다. 이전의 문제들과 다르게 단순히 쿼리문으로 조건문을 우회하는 것이 아닌 직접 admin에 대한 password를 알아내야하므로 python requests 모듈을 사용해서 해결해야합니다.
https://docs.python-requests.org/en/master/user/quickstart/
python requests 모듈을 사용해서 다음과 같은 순서로 문제를 해결합니다.
1. length() 함수를 이용해서 password의 길이를 구합니다.
2. substr() 함수를 이용해서 password를 이루고있는 문자를 구합니다.
<?php include "./config.php"; login_chk(); $db = dbconnect(); if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); $query = "select id from prob_orc where id='admin' and pw='{$_GET[pw]}'"; echo "<hr>query : <strong>{$query}</strong><hr><br>"; $result = @mysqli_fetch_array(mysqli_query($db,$query)); if($result['id']) echo "<h2>Hello admin</h2>"; $_GET[pw] = addslashes($_GET[pw]); $query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'"; $result = @mysqli_fetch_array(mysqli_query($db,$query)); if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc"); highlight_file(__FILE__); ?> |
풀이 1. password의 길이구하기
먼저 위의 쿼리문을 살펴보겠습니다. id가 존재한다면, Hello admin이 출력됩니다.
$query = "select id from prob_orc where id='admin' and pw='{$_GET[pw]}'"; echo "<hr>query : <strong>{$query}</strong><hr><br>"; $result = @mysqli_fetch_array(mysqli_query($db,$query)); if($result['id']) echo "<h2>Hello admin</h2>"; |
따라서 위의 쿼리문에 ?pw=' or id='admin' and length(pw)<10 %23을 입력하면
$query = "select id from prob_orc where |
앞의 admin에 대한 판별은 날려버리고 or 로 뒤의 조건 판별을 수행하게 합니다. 따라서 admin 계정의 비밀번호의 길이가 10보다 작다면 true가 되고, select로 admin 아이디를 select할 수 있게됩니다.
Hello admin이 출력된 것으로 admin의 password의 길이가 10보다 작다는 사실을 알았습니다. 이 과정을 반복해서 길이를 특정할 수 있습니다. 하지만 패스워드의 길이가 매우 길다면 힘든 노동이 될것이기때문에 앞에서 언급한 python requests 모듈을 이용해서 간단하게 구할 수 있습니다.
쿼리문을 1부터 30까지의 길이에 맞게 하나씩 대입해보면서, 응답 텍스트에 Hello admin이 존재한다면 길이를 출력하는 코드입니다. 이때 requests 모듈이 설치되어있지않은경우 설치한 뒤에 실행해주어야합니다.
위의 코드를 실행한 결과, password의 길이가 8인것을 구했습니다.
풀이 2. 완전한 password를 구하기
먼저 substr( ) 함수를 사용한다고 했기때문에 substr 함수에 대해서 짧게 알아보겠습니다.
substr(string, start_index, length) string : 추출의 대상이 되는 문자열 start_index : 추출을 시작하는 위치 length : 인덱스로 부터 추출할 문자의 개수 ( 값이 없으면 문자열의 끝까지 추출) |
예를 들어 substr('abcdefg',3,1)의 경우 인덱스 3부터 1개의 문자를 추출합니다. 즉 d입니다.
이 substr함수를 가지고, 길이가 8인 password를 구하는것입니다. 이 작업을 수동으로 한다면
0부터 7까지 인덱스에 해당하는 각각의 인덱스마다
아스키코드 48부터 127번까지 해당하는 문자를 하나씩 대입합니다.
몇번의 노가다 끝에 첫번째 문자는 우연히 얻어냈습니다.
?pw=' or id='admin' and substr(pw,0,1)=0%23%27 이렇게 password의 첫번째 문자가 0인지 대입하였더니 아래처럼
Hello admin이 출력됩니다. 하지만 길이가 100인 패스워드의 경우 이렇게 하나하나씩 대입하는것은 너무나 힘든 노동이 될 것입니다. 따라서 python module을 활용해서 마찬가지로 해결해보겠습니다.
파이썬을 이용해서 자동화한 코드입니다.
8글자 자리의 password = XXXX XXXX 인덱스 1부터 8까지를 바깥포문으로 돌리고,
각 자리마다 아스키코드상 문자 47부터 123까지 대입해서 비교해서 출력합니다.
그 결과 password는 095a9852 였고 password를 입력하면 orc문제는 해결됩니다.
'개인 공부 > WEB' 카테고리의 다른 글
[웹해킹] LOS 7 - (Orge) (0) | 2021.05.30 |
---|---|
[웹해킹] LOS 6 - (Darkelf) (0) | 2021.05.30 |
[웹해킹] LOS 3 - (Goblin) (0) | 2021.05.29 |
[웹해킹] LOS 2 - (Cobolt) (0) | 2021.05.29 |
[웹해킹] LOS 1 - (Gremlin) (0) | 2021.05.29 |
댓글