본문 바로가기
WEB HACKING/웹 해킹[실습]

Php로 웹 개발하기 : 식별 - 인증 Case 별 로그인

by madevth 2021. 10. 23.
반응형

[SQL Injection : 로그인 Case 별 인증 우회] : [모의해킹_이론] - SQL Injection : 로그인 Case 별 인증 우회

 

<모의해킹_이론> 파트의 [SQL Injection : 로그인 Case 별 인증 우회] 포스팅에서는 식별과 인증 과정에 따른 로그인 Case 5가지를 알아보았고, 그에 따른 SQL Injection 방식도 살펴보았다.

이번 실습 포스팅에서는 5가지 인증 과정을 직접 구현해보자.

 

 

① 식별 - 인증 동시

<?php
    if(isset($_POST['id']) && isset($_POST['pw'])){
        $username = $_POST['id'];
        $password = $_POST['pw'];

        $conn = mysqli_connect('localhost', 'ID', 'PW', 'DBname');
        $sql = "SELECT * FROM login where login_id = '$username' and login_pw = '$password';";
        
        if($result = mysqli_fetch_array(mysqli_query($conn, $sql))){
            session_start();
            $_SESSION['id'] = $username;
            header('Location: mainpage.php');
        } else{
            echo "<script>alert('등록되지 않은 사용자입니다.')</script>";
            echo "<script>window.location.href='index.html';</script>";
        }
        mysqli_close($conn);
    } else{
        echo "<script>alert('아이디와 비밀번호를 입력해주세요.')</script>";
        echo "<script>window.location.href='index.html';</script>";
    }
?>

기존 포스팅에서 사용한 방식이 바로 이 식별 - 인증 동시 방식이다.

 

 

② 식별 - 인증 분리

<?php
    if(isset($_POST['id']) && isset($_POST['pw'])){
        $username = $_POST['id'];
        $password = $_POST['pw'];

        $conn = mysqli_connect('localhost', 'ID', 'PW', 'DBname');
        $sql = "SELECT login_pw FROM login where login_id = '$username';";
        $result = mysqli_fetch_array(mysqli_query($conn, $sql));

        if($result[0] == $password){
            session_start();
            $_SESSION['id'] = $username;
            header('Location: mainpage.php');
        } else{
            echo "<script>alert('등록되지 않은 사용자입니다.')</script>";
            echo "<script>window.location.href='index.html';</script>";
        }
        mysqli_close($conn);
    } else{
        echo "<script>alert('아이디와 비밀번호를 입력해주세요.')</script>";
        echo "<script>window.location.href='index.html';</script>";
    }
?>

mysqli_fetch_array는 배열을 return 하기 때문에 $result의 0번째 인덱스 값이 pw와 일치하는지 확인해준다.

1번 케이스와는 다르게 사용자가 입력한 ID값과 일치하는 행에서 PW를 가져온 후 비교하는 과정을 거친다.

 

 

③ 식별 - 인증 동시 with Hash

sha256 hash를 사용하여 인증 코드를 짜기 위해 확인용으로 DB에 Hash 된 비밀번호를 가진 hash_pw Column을 추가해주었다. SQL에서 sha256은 sha2('변환할 문장', 256)으로 사용할 수 있다.

ALTER TABLE tbname ADD hash_pw varchar(256) NOT NULL DEFAULT 0;

우선 Default값 0으로 hash_pw Column을 추가해준 후, 값을 hash값으로 update 해준다.

UPDATE tbname SET hash_pw = sha2('pw', 256) where login_pw = 'pw';

결과 화면

<?php
    if(isset($_POST['id']) && isset($_POST['pw'])){
        $username = $_POST['id'];
        $password = $_POST['pw'];

        $conn = mysqli_connect('localhost', 'ID', 'PW', 'DBname');
        $sql = "SELECT * FROM login where login_id = '$username' and hash_pw = sha2('$password', 256);";
        
        if($result = mysqli_fetch_array(mysqli_query($conn, $sql))){
            session_start();
            $_SESSION['id'] = $username;
            header('Location: mainpage.php');
        } else{
            echo "<script>alert('등록되지 않은 사용자입니다.')</script>";
            echo "<script>window.location.href='index.html';</script>";
        }
        mysqli_close($conn);
    } else{
        echo "<script>alert('아이디와 비밀번호를 입력해주세요.')</script>";
        echo "<script>window.location.href='index.html';</script>";
    }
?>

 

 

④ 식별 - 인증 분리 with Hash

<?php
    if(isset($_POST['id']) && isset($_POST['pw'])){
        $username = $_POST['id'];
        $password = $_POST['pw'];

        $conn = mysqli_connect('localhost', 'ID', 'PW', 'DBname');
        $sql = "SELECT hash_pw FROM login where login_id = '$username';";
        $result = mysqli_fetch_array(mysqli_query($conn, $sql));

        if($result[0] == hash("sha256", $password)){
            session_start();
            $_SESSION['id'] = $username;
            header('Location: mainpage.php');
        } else{
            echo "<script>alert('등록되지 않은 사용자입니다.')</script>";
            echo "<script>window.location.href='index.html';</script>";
        }
        mysqli_close($conn);
    } else{
        echo "<script>alert('아이디와 비밀번호를 입력해주세요.')</script>";
        echo "<script>window.location.href='index.html';</script>";
    }
?>

마찬가지로 2번 case에서 Hash만 적용해주면 된다.

 

 

⑤ 식별 - 인증 동시 with Enter

<?php
    if(isset($_POST['id']) && isset($_POST['pw'])){
        $username = $_POST['id'];
        $password = $_POST['pw'];

        $conn = mysqli_connect('localhost', 'ID', 'PW', 'DBname');
        $sql = "SELECT * FROM login where login_id = '$username'
        and login_pw = '$password';";
        
        if($result = mysqli_fetch_array(mysqli_query($conn, $sql))){
            session_start();
            $_SESSION['id'] = $username;
            header('Location: mainpage.php');
        } else{
            echo "<script>alert('등록되지 않은 사용자입니다.')</script>";
            echo "<script>window.location.href='index.html';</script>";
        }
        mysqli_close($conn);
    } else{
        echo "<script>alert('아이디와 비밀번호를 입력해주세요.')</script>";
        echo "<script>window.location.href='index.html';</script>";
    }
?>

1번 case에서 and 앞에서 enter만 쳐주면 된다.

1번 case에서는 ID: ' or 1 = 1; # 로 로그인이 잘 되었는데, 5번 case에서는 enter로 주석이 적용되지 않아 로그인이 안되는 것을 확인할 수 있었다.

반응형

댓글