불충분한 인가
중요 기능 또는 데이터에 접근 시 사용자 권한에 따른 접근 통제를 두지 않은 취약점입니다. 접근 권한에 대한 인증 프로세스 및 올바른 접근 통제 로직이 구현되지 않아 다른 사용자의 민감한 정보나 인가되지 않은 페이지에 접근할 수 있습니다.
1. 공격 실습
No. |
실습 위치 |
비고 |
1 |
게시판 목록 기능 |
2. 게시판 php 코드
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
session_start();
$session_username = $_SESSION['username'];
if( is_null($session_username)) {
header( 'Location: ../login.php' );
}
header('Content-Type: text/html; charset=utf-8'); // utf-8인코딩
$db = new mysqli("DB주소","DB사용자ID","DB패스워드","테이블명");
$db->set_charset("utf8");
function mq($sql)
{
global $db;
return $db->query($sql);
}
?>
<!doctype html>
<head>
<meta charset="utf-8">
<title>HOME</title>
<link rel="stylesheet" href="/css/loginstyle.css">
<link rel="stylesheet" type="text/css" href="/css/style.css"/>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<link rel="stylesheet" href="/css/gallery.css">
</head>
<body class="loggedin">
<!-- Nav Bar -->
<nav class="navtop">
<div>
<h1>My Website</h1>
<a href="../home"><i class="fas fa-home"></i>Home</a>
<a href="../profile.php"><i class="fas fa-user-circle"></i>Profile</a>
<a href="/member/logout.php"><i class="fas fa-sign-out-alt"></i>Logout</a>
</div>
</nav>
<div class="container mt-3">
<div class="row">
<div class="col-sm-12 col-md-3 col-lg-2 p-2">
<!-- Sidebar -->
<nav id="sidebar" class="border-top border-secondary">
<div class="list-group">
<a class="rounded-0 list-group-item list-group-item-action list-group-item-light " href="/freeboard/index">자유게시판</a>
<a class="rounded-0 list-group-item list-group-item-action list-group-item-light " href="/login/report">버그및건의</a>
</div>
</nav>
</div>
<div class="col-sm-12 col-md-9 col-lg-10 p-2">
<div class="content">
<div id="board_area">
<h2>자유게시판</h2>
<?php
echo "<p>{$_SESSION['username']} 님 환영합니다.</p>";
?>
<p>자유롭게 글을 쓸 수 있는 게시판입니다.</p>
<form method ="post" action="order.php">
<input style='float:right;' type="submit" value="선택"/>
<select style='float:right;' name="order" >
<option value="">정렬 방법 선택</option>
<option value="title">제목 (가나다 순)</option>
<option value="name">글쓴이 (가나다 순)</option>
<option value="date">작성일 (최신 순)</option>
<option value="hit">조회수 (높은 순)</option>
</select>
</form>
<table class="table table-hover" style="border: 1px solid;">
<thead class="thead-dark">
<tr>
<th scope="col" width="70">번호</th>
<th width="500">제목</th>
<th width="120">글쓴이</th>
<th width="100">작성일</th>
<th width="100">조회수</th>
</tr>
</thead>
<?php
if(isset($_GET['page'])){
$page = $_GET['page'];
}else{
$page = 1;
}
$sql = mq("select * from freeboard");
$row_num = mysqli_num_rows($sql);
$list = 10; //한 페이지에 보여줄 개수
$block_ct = 5; //블록당 보여줄 페이지 개수
$block_num = ceil($page/$block_ct); // 현재 페이지 블록 구하기
$block_start = (($block_num - 1) * $block_ct) + 1; // 블록의 시작번호
$block_end = $block_start + $block_ct - 1; //블록 마지막 번호
$total_page = ceil($row_num / $list); // 페이징한 페이지 수 구하기
if($block_end > $total_page) {
$block_end = $total_page; //만약 블록의 마지박 번호가 페이지수보다 많다면 마지박번호는 페이지 수
}
$total_block = ceil($total_page/$block_ct); //블럭 총 개수
$start_num = ($page-1) * $list; //시작번호 (page-1)에서 $list를 곱한다.
$sql2 = mq("select * from freeboard order by idx desc limit $start_num, $list");
// board테이블에서 idx를 기준으로 내림차순해서 5개까지 표시
$sql3 = mq("select * from freeboard order by idx desc limit $start_num, $list");
while($board = $sql3->fetch_array())
{
//title변수에 DB에서 가져온 title을 선택
$title=$board["title"];
if(strlen($title)>30)
{
//title이 30을 넘어서면 ...표시
$title=str_replace($board["title"],mb_substr($board["title"],0,30,"utf-8")."...",$board["title"]);
}
?>
<tbody>
<tr>
<td width="70"><?php echo $board['idx']; ?></td>
<td width="500"><a href="/freeboard/read?idx=<?php echo $board["idx"];?>"><?php echo $title;?></a></td>
<td width="120"><?php echo $board['name']?></td>
<td width="100"><?php echo $board['date']?></td>
<td width="100"><?php echo $board['hit']; ?></td>
</tr>
</tbody>
<?php } ?>
</table>
<div id="page_num">
<ul>
<?php
if($page <= 1)
{
echo "<li class='fo_re'>처음</li>";
}else{
echo "<li><a href='?page=1'>처음</a></li>";
}
if($page <= 1)
{
}
else{
$pre = $page-1;
echo "<li><a href='?page=$pre'>이전</a></li>";
}
for($i=$block_start; $i<=$block_end; $i++){
if($page == $i){
echo "<li class='fo_re'>[$i]</li>";
}else{
echo "<li><a href='?page=$i'>[$i]</a></li>";
}
}
if($page >= $total_page){
}else{
$next = $page + 1;
echo "<li><a href='?page=$next'>다음</a></li>";
}
if($page >= $total_page){
echo "<li class='fo_re'>마지막</li>";
}else{
echo "<li><a href='?page=$total_page'>마지막</a><li>";
}
?>
</ul>
</div>
<hr>
<body>
<br>
<div id="search_box">
<form action="search.php" method="get">
<select name="menu">
<option value="title">제목</option>
<option value="name">글쓴이</option>
</select>
<input type="text" name="search" size="40" required="required" /> <button>검색</button>
</form>
</div>
<div id="write_btn">
<a href="/freeboard/write.html" class="btn btn-outline-info float-right">글쓰기</a>
</div>
</div>
<footer class="footer">
<div class="container mt-3">
<span class="text-muted">©2021 • ParkDohyeon</span>
<div class="float-right small"><a href=#>개인정보취급방침</a></div>
</div>
</footer>
<script src="/js/jquery-3.4.1.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</html>
</body>
</html>
3. 공격 실습
Step1:게시판 기능은 로그인 이후에 사용할 수 있는 기능입니다. 하지만 회원 정보 없이 URL로 직접 게시판에 접근이 가능합니다.
정상 접근 과정 |
login – home - freeboard |
비 정상 접근 과정 |
freeboard/index |
중요 기능 또는 데이터 접근 시 2차 인증 프로세스를 구현하고, 사용자 접근 통제 로직이 구현되지 않았다면 세션 관리 로직을 통해 사용자 권한을 식별하고 인가된 사용자 요청을 관리합니다. 페이지 별 권한 메트릭스를 작성하여, 페이지에 부여된 권한의 타당성을 체크 후에 권한 매트릭스를 기준으로 하여 전 페이지에서 권한 체크가 이루어지도록 구현해야 합니다.
반응형
'Security > WEB' 카테고리의 다른 글
[모의해킹 실습] 정보누출 취약 페이지 구현 및 공격 실습 (0) | 2021.08.02 |
---|---|
[Angular]설치 및 시작하기 (0) | 2021.07.31 |
[모의해킹 실습] 불충분한 인증 페이지 구현 및 공격 실습 (0) | 2021.07.27 |
[모의해킹 실습] 자동화공격 취약 페이지 구현 및 공격 실습 (0) | 2021.07.24 |
[모의해킹 실습] CSRF 취약 페이지 구현 및 공격 실습 (0) | 2021.07.22 |