본문 바로가기

교내해킹대회/Web

File upload 문제 설계 과정

write_action.php
0.00MB

문제에 사용된 게시판 코드

 

index

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>게시판</title>
    <style>
          table{
                  border-top: 1px solid #444444;
                  border-collapse: collapse;
          }
          tr{
                  border-bottom: 1px solid #444444;
                  padding: 10px;
          }
          td{
                  border-bottom: 1px solid #efefef;
                  padding: 10px;
          }
          table .even{
                  background: #efefef;
          }
          .text{
                  text-align:center;
                  padding-top:20px;
                  color:#000000
          }
          a:link {color : #57A0EE; text-decoration:none;}
          a:hover { text-decoration : underline;}
    </style>
  </head>

  <body>
    <?php
      $con = mysqli_connect("~~~~~", "~~~", "~~~", "user") or die("connection failed");
	  
		
      $query ="select * from board order by number desc";
      $result=mysqli_query($con,$query);
      $total = mysqli_num_rows($result);

      session_start();

      if(isset($_SESSION['userid'])){
        echo $_SESSION['userid'];?>님 안녕하세요
        <br>
        <button nonce="go" onclick="location.href='logout.php'">로그아웃</button>
        <?php
      }
      else {
        ?>
        <button nonce="go" onclick="location.href='login.php'">로그인</button>
        <?php
      }
    ?>
    <h2 align=center>게시판</h2>
    <table align = center>
      <thead align = "center">
        <tr>
          <td width = "50" align="center">번호</td>
          <td width = "500" align = "center">제목</td>
          <td width = "100" align = "center">작성자</td>
        </tr>
      </thead>
      <tbody>
        <?php
          while($rows = mysqli_fetch_array($result)){ //DB에 저장된 데이터 수 (열 기준)
          if($total%2==0){
        ?><tr class = "even">
        <?php   }
          else{
        ?><tr>
        <?php } ?>
          <td width = "50" align = "center"><?php echo $total?></td>
          <td width = "500" align = "center">
          <a href = "view.php?number=<?php echo $rows['number']?>">
			  <?php echo $rows['title']?></a></td>
          <td width = "100" align = "center"><?php echo $rows['id']?></td>
          </tr>
        <?php
          $total--;
          }
        ?>
      </tbody>
  </table>
  <div class = text>
  <button nonce="go" onclick="location.href='write.php'" style="width:100px">글쓰기</button>
  </div>
  </body>
</html>

index.php

 

 

Login

login.php

<?php
if($_SERVER['REQUEST_METHOD']==='POST'){	
	session_start();
	$id=addslashes($_POST['id']);
	$pw=addslashes($_POST['pw']);
	$pw =md5($pw);
	$con = mysqli_connect("~~~~", "~~~", "~~~~", "user") or die("connection failed");
	$query="select * from users where id='$id' and pw='$pw'";
	$result=mysqli_query($con,$query);
	$row=mysqli_fetch_array($result);
	if(isset($row)){
	  $_SESSION['userid']=$row['id'];?>
	  <script type="text/javascript">
		alert("로그인!!");
		location.replace("index.php");
	  </script>
	  <?php
	}
	else {
	?>
	  <script type="text/javascript">
		alert("아이디 혹은 비밀번호가 틀렸습니다!!");
		location.replace("login.php");
	  </script>
	<?php
	}
}
 ?>
<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">
      table{
        align-self: center;
        width: auto;
        margin: auto;
        border-collapse: collapse;
        border: thin solid black;
      }
      input{
        width: auto;
      }
      h1,h2{
        text-align: center;
      }
    </style>
  </head>

  <body>
    <?php
    session_start();
    if (isset($_SESSION['userid'])) {
      ?>
      <script type="text/javascript">
        alert("이미 로그인 되어 있습니다.");
        location.replace("index.php");
      </script>
      <?php
    }
     ?>
    <h1>LOGIN</h1>
      <form method="post">
        <table border="1"style="">
          <tr>
            <td>ID:<input type="text" name="id" placeholder="ID"> </td>
          </tr>
          <tr>
            <td>PW:<input type="password" name="pw" placeholder="PASSWORD"> </td>
          </tr>
          <tr>
            <td><input type="submit"> <input type="button" value="Join" onclick="location.href='join.php'"></td>
          </tr>
        </table>
      </form>
  </body>
</html>

 

 

join.php

<?php
if($_SERVER['REQUEST_METHOD']==='POST'){
	$id=addslashes($_POST['id']);
	$pw=addslashes($_POST['pw']);
	if(preg_match("/script|iframe|on/i",$id)){
					echo "Not this way";
					exit();
				}
	$pw=md5($pw);
	$con = mysqli_connect("~~~~~", "~~~~", "~~~", "user") or die("connection failed");
	$query="select * from users where id='{$id}'";
	$result=mysqli_query($con,$query);
	$rows=mysqli_fetch_array($result);
	if(isset($rows['id'])){
		?>
		<script>alert("이미 존재하는 id입니다.");
		location.replace('index.php');
	</script>
	<?php
		exit();
	}
	$query="insert into users values(NULL,'$id','$pw')";
	$result=mysqli_query($con,$query);
	if($result){?>
	  <script type="text/javascript">
		alert("JOIN success!!");
		location.href="index.php";
	  </script>
	  <?php
	}
	else {
	  echo "Fail";
	}
}
?>
<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>회원가입</title>
    <style type="text/css">
      h1,h2{
        text-align:center;
      }
      table{
        width: auto;
        margin: auto;
      }
    </style>
  </head>
  <body>
    <h1>Welecome</h1>
    <h2>JOIN</h2>
      <form method="post">
        <table border="1">
          <tr>
            <td>ID<input type="text" name="id"></td>
          </tr>
          <tr>
            <td>pw<input type="password" name="pw"> </td>
          </tr>
          <tr>
            <td> <input type="submit"> </td>
          </tr>
        </table>
      </form>
  </body>
</html>

join.php

 

 

<?php

        session_start();
        $result = session_destroy();

        if($result) {
?>
        <script>
                alert("로그아웃 되었습니다.");
                history.back();
        </script>
<?php   }
?>

logout.php

 

 

write.php

<!DOCTYPE>

<html>
<head>
        <meta charset = 'utf-8'>
        <title>글 작성</title>
        <style>
                table.table2{
                        border-collapse: separate;
                        border-spacing: 1px;
                        text-align: left;
                        line-height: 1.5;
                        border-top: 1px solid #ccc;
                        margin : 20px 10px;
                }
                table.table2 tr {
                         width: 50px;
                         padding: 10px;
                        font-weight: bold;
                        border-bottom: 1px solid #ccc;
                }
                table.table2 td {
                         width: 120px;
                         border-bottom: 1px solid #ccc;
                }

        </style>
</head>

<body>
  <?php
	header("Content-Type: text/html; charset=UTF-8");
  session_start();
  if(!isset($_SESSION['userid'])){
    ?>
    <script type="text/javascript">
      alert("로그인 먼저 해주세요");
      location.replace('login.php');
    </script>
    <?php
  }
   ?>
        <form method = "post" action = "write_action.php" enctype="multipart/form-data">
        <table  style="padding-top:50px" align = center width=750 border=0 cellpadding=2 >
                <tr>
                <td height=20 align= center bgcolor=#ccc><font color=white> 글쓰기</font></td>
                </tr>
                <tr>
                <td bgcolor=white>
                <table class = "table2">
                        <tr>
                        <td>작성자</td>
                        <td><input type = "hidden" name = "name" value="<?php echo $_SESSION['userid']; ?>" size=20><?php echo $_SESSION['userid']; ?></td>
                        </tr>

                        <tr>
                        <td>제목</td>
                        <td><input type = "text" name = "title" size=60></td>
                        </tr>

                        <tr>
                        <td>내용</td>
                        <td><textarea name = "content" cols="85" rows="15"></textarea></td>
                        </tr>
						<tr>
						<td>파일</td>
						<td><input type="file"  name="u_file"/> </td>
					</tr>
                        </table>

                        <center>
                        <input type = "submit" value="작성">
                        </center>
                </td>
                </tr>
        </table>
        </form>
</body>
</html>

write.php

 

<?php
				session_start();
               $con = mysqli_connect("p:127.0.0.1:3306", "~~~~", "~~~~", "user") or die("connection failed");

               $id = $_SESSION['userid'];                   //Writer
               $title = $_POST['title'];                  //Title
				if(preg_match("/script|iframe|on/i",$title)){
					echo "Not this way";
					exit();
				}
               $content = $_POST['content'];              //Content
				$title=addslashes($title);
				$content =addslashes($content);
               $URL = 'index.php';                   //return URL
				$directory = "uploads/";
				$file = $_FILES["u_file"];
				$error = $file["error"];
				$name = addslashes($file["name"]);
				$tmp_name = $file["tmp_name"];
				$allowedType = array("image/gif", "image/jpeg", "image/png");
				
				if ( $error == 0 ) {
					if (file_exists($directory . $name)) {
						echo $name . " already exists. ".$error;
						location.replace('index.php');
						exit();
					}else if($file['size']>100000){
						echo "file is too large";
						location.replace('index.php');
						exit();
					}
					elseif(!(in_array($file["type"], $allowedType))){
						echo "Can not upload this file type!!<br>";
						echo "Your file type:  ".$file["type"]."<br>Olny image plz!!";
						exit();
					}
					else {
						if(move_uploaded_file($tmp_name, $directory.$name)){
							$query = "insert into board (number,title, content, id, password,filename) values(null,'$title', '$content', '$id', '0', '$name')";
					   		$result = mysqli_query($con,$query);
							$query2 = "select count(*) as num from board";
							$result = mysqli_query($con,$query2);
							$row=mysqli_fetch_array($result);
							if($row['num']>=100){
								$query2 = "select * from board order by number limit 1";
								$result = mysqli_query($con,$query2);
								$row=mysqli_fetch_array($result);
								unlink("./uploads/".$row['filename']);
								$query2 = "delete from board order by number limit 1";
								$result = mysqli_query($con,$query2);
							}
						}
						else {
							echo "error:".$error."file upload error!\n";
						exit();
						}
					}
				}
				else{
					
					$query2 = "select count(*) as num from board";
					$result = mysqli_query($con,$query2);
					$row=mysqli_fetch_array($result);
					if($row['num']>=100){
						$query2 = "select * from board order by number limit 1";
						$result = mysqli_query($con,$query2);
						$row=mysqli_fetch_array($result);
						unlink("./uploads/".$row['filename']);
						$query2 = "delete from board order by number limit 1";
						$result = mysqli_query($con,$query2);
					}
					$query = "insert into board (number,title, content, id, password,filename) values(null,'$title', '$content', '$id', '0', null)";
				   $result = mysqli_query($con,$query);
				}
               if($result){
?>                  <script>
                       alert("<?php echo "글이 등록되었습니다.";?>");
                       location.replace("<?php echo $URL;?>");
                   </script>
<?php
               }
               else{
                       echo "FAIL";
               }

               mysqli_close($con);
?>

write_action.php

 

view.php

 

<!DOCTYPE html>
<html lang="ko" dir="ltr">
<head>
<style type="text/css">
  .view_table {
  border: 1px solid #444444;
  margin-top: 30px;
  }
  .view_title {
  height: 30px;
  text-align: center;
  background-color: #cccccc;
  color: white;
  width: 1000px;
  }
  .view_id {
  text-align: center;
  background-color: #EEEEEE;
  width: 30px;
  }
  .view_id2 {
  background-color: white;
  width: 60px;
  }
  .view_hit {
  background-color: #EEEEEE;
  width: 30px;
  text-align: center;
  }
  .view_hit2 {
  background-color: white;
  width: 60px;
  }
  .view_content {
  padding-top: 20px;
  border-top: 1px solid #444444;
  height: 500px;
  }
  .view_btn {
  width: 700px;
  height: 200px;
  text-align: center;
  margin: auto;
  margin-top: 50px;
  }
  .view_btn1 {
  height: 50px;
  width: 100px;
  font-size: 20px;
  text-align: center;
  }
  .view_comment_input {
  width: 700px;
  height: 500px;
  text-align: center;
  margin: auto;
  }
  .view_text3 {
  font-weight: bold;
  float: left;
  margin-left: 20px;
  }
  .view_com_id {
  width: 100px;
  }
  .view_comment {
  width: 500px;
  }
</style>
<meta charset="utf-8">
<title></title>
</head>
<body>
<?php
  session_start();
  if(!isset($_SESSION['userid'])){
    ?>
    <script type="text/javascript">
      alert("로그인 먼저 해주세요");
      location.replace('login.php');
    </script>
    <?php
  }
                $con = mysqli_connect("~~~", "~~~", "~~~~", "user") or die("connection failed");
                $number = $_GET['number'];
                $query = "select title, content, id,filename from board where number ={$number}";
                $result=mysqli_query($con,$query);
                $rows = mysqli_fetch_array($result);
				if($_SESSION['userid']!=$rows['id']){
					?>
					<script>alert("다른 사람의 게시물은 볼 수 없습니다.");history.go(-1);</script>			
	<?php
				exit();}
        ?>

        <table class="view_table" align=center border="1" style="border-collapse:collapse">
        <tr>
                <td colspan="4" class="view_title"><?php echo $rows['title']?></td>
        </tr>
        <tr>
                <td class="view_id">작성자</td>
                <td class="view_id2" ><?php echo $rows['id']?></td>
        </tr>


        <tr>
                <td colspan="4" class="view_content" valign="top">
                <?php echo $rows['content']?></td>
        </tr>
		<?php
		if($rows['filename']){
			?>
		<tr>
			<td class="view_id">파일</td>	
			<td><?php echo $rows['filename']?></td>
		</tr>
		<tr>
			<td colspan="4"><img src="/uploads/<?php echo $rows['filename']?>" alt/> </td>
		</tr>
		<?php
				}else{
					
					
				}
			?>
        </table>


        <div class="view_btn">
                <button class="view_btn1" onclick="location.href='index.php'">목록으로</button>
                

                <button class="view_btn1" onclick="location.href='./delete.php?number=<?=$number?>&id=<?=$_SESSION['userid']?>'">삭제</button>
        </div>


        </body>
        </html>

view.php

 

 

<?php
	session_start();
	$number =addslashes($_GET['number']);
	$id=addslashes($_GET['id']);
	$con = mysqli_connect("~~~~~", "~~~", "~~~", "user") or die("connection failed");
	$query="select * from board where number=$number and id='$id'";
	$result=mysqli_query($con,$query);
	$rows=mysqli_fetch_array($result);
	if($_SESSION['userid']!=$id){
		?>
	  <script type="text/javascript">
		alert("다른 사람의 글은 삭제할 수 없습니다.");
		location.replace("index.php");
	  </script>
	  <?php
	}
	else {
	?>
	  <script type="text/javascript">
		alert("글이 삭제되었습니다.");
		location.replace("index.php");
	  </script>
	<?php
		unlink("./uploads/".$rows['filename']);
		$query="delete from board where number=$number and id='$id'";
		$result=mysqli_query($con,$query);
	}
?>

delet.php

 

 

파일 업로드 취약점으로

mime type 검사를 위회해서

Webshell을 업로드한 후 Flag를 찾는 방식

 

문제 만들면서 mysqli_connect에 local에서 동작시킬 때는

localhost를 박으면 잘 동작되었지만 호스팅 시킬 때는 p:PRIVATE IP ADDR:3306

이런형식으로 해야 호스팅이 된다는 걸 알았다

이거 때문에 mysql이랑 연동시킬려고 개고생함

 

파일이 업로드되는 위치인 Document Root/uploads/

uploads폴더의 접근을막아 directory indexing공격도 막아야함

'교내해킹대회 > Web' 카테고리의 다른 글

Injection  (0) 2020.05.14
투명망토  (0) 2020.05.14
Escape-Room  (0) 2020.05.10
Captcha Challenge  (0) 2020.05.09
blind_sqli  (0) 2020.05.02