모의해킹 스터디/Week6

[웹개발] SQL Injection 확인 페이지 개발

protruser 2024. 5. 25. 01:32

login 우회 CTF를 풀 때, 로직을 만족시키는 테이블의 데이터는 어느 것이 있으며, 그 중 어떤 아이디로 로그인이 되는지 눈으로 확인하면서 풀기 위해 row를 출력하는 툴을 만들었다.

 

기존에 진행하였던 웹 개발에서 일부를 변경 및 수정하여 만들었고, css 세팅은 동일하다.

 

아이디와 비밀번호를 입력하면 서버에서 실행되는 query를 먼저 출력하고, 이어서 query를 만족시키는 row를 한줄씩 출력하도록 만들었다.

 

login_page.php

더보기
<?php
  require_once('loginLogic.php');
?>

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="login_css/login.css">
  <title>Login</title>
</head>

<body>
  <form method="post" action="">
    <h2>Login</h2>
    <label>아이디</label>
    <input id="box" type="text" name="id" placeholder="ID" />
    <label>비밀번호</label>
    <input id="box" type="password" name="pass" placeholder="Password" />
    <label class="login_button"><button type="submit">로그인</button></label>
    <a href="register_page.php" class="register">회원가입</a><br>

    <?php
    if ($_SERVER['REQUEST_METHOD']!=='POST') {
      exit();
    }
  ?>
    <table>
      <thead>
        <tr>
          <th width="110">id</th>
          <th width="110">pass</th>
          <th width="110">nick</th>
          <th width="110">email</th>
        </tr>
      </thead>
      <?php
      $id = $_POST['id'];
      $pass = $_POST['pass'];

      $result = query1($id, $pass);
      
      while ($users= mysqli_fetch_assoc($result)) {
        ?>
      <tbody>
        <td width="110"><?php echo $users['id']?></td>
        <td width="110"><?php echo $users['pass']?></td>
        <td width="110"><?php echo $users['nick']?></td>
        <td width="110"><?php echo $users['email']?></td>
      </tbody>


      <?php } ?>
    </table>
  </form>
</body>

</html>

 

 

처음 웹 코드를 실행시킬때, php 코드까지 모두 실행이 되는데, 이때 입력 없이 아래의 코드를 실행시키는 것을 방지하기 위해

    if ($_SERVER['REQUEST_METHOD']!=='POST') {
      exit();
    }

라는 코드를 삽입하였다.

 

처음 login_page.php에 들어오게 되면 post로 전달받은 값이 없기 때문에, 위의 코드에서 exit() 조건에 걸리게 된다.

 

이후 코드는 게시판을 출력하는 코드 형태와 같다.

그리고 많은 데이터가 필요없기 때문에 페이징 기능은 따로 구현하지 않았다.

 

$result = query1($id, $pass);

로그인 로직인query함수를 실행시켜 얻은 result 값을 mysqli_fetch_assoc 함수를 사용하여 각각 한 줄의 row를 출력하였고, 값을 $user에 담아 값을 각각 인덱싱하여 출력했다.

 

 

loginLogic.php

더보기
<?php
  require_once('DB.php');
  function query1($id, $pass) {
    $query = "SELECT * FROM users WHERE id='$id'
    and pass='$pass'";
    print_r($query);
    echo '<br>';
    echo '<br>';
    $result = mysqli_query(DB(), $query);

    return $result;
  }
?>

Login Bypass1 로직을 구현했다.

$id와 $pass를 함수의 파라미터로 입력받으면, 로그인 로직을 진행시키고 얻은 결과 $result 값을 리턴한다.


 

 

아이디와 비밀번호를 입력시 서버에서 실행된 쿼리를 먼저 출력하고, 이어서 id, pass, nick, email 칼럼 위치에 각각 아이디와 비밀번호를 출력한다.

 

SQL 쿼리를 만족시키는 row가 여러개인 경우에 맨 위의 row에 해당하는 아이디와 비밀번호로 로그인이 된다.

(일반적인 로그인의 경우 fetch 함수로 받아서 로그인을 진행시키기 때문에 이와 같이 로그인을 진행한다고 가정했다.)

 

 

위의 로직에서는 doldol 이라는 아이디로 로그인이 될 것이다.