web2구현
CREATE TABLE users (
idx int(6),
id_param varchar(15),
pw_param varchar(32),
last_login TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
failed_login INT(3),
PRIMARY KEY (idx)
);
mysqli_result::$num_rows -- mysqli_num_rows — 결과 세트의 행 수를 가져옵니다.
mysqli_result::fetch_assoc -- mysqli_fetch_assoc — 결과 집합의 다음 행을 연관 배열로 가져옵니다.
strtotime — 영어 텍스트 날짜/시간 설명을 Unix 타임스탬프로 구문 분석합니다.
타임존 수정
/etc/php/8.3/apache2/php.ini
/etc/php/8.3/fpm/php.ini
date.timezone = Asia/Seoul
systemctl restart apache2
systemctl restart php8.3-fpm
쿠키
쿠키는 종종 사용자를 식별하는 데 사용됩니다.
쿠키는 서버가 이용자의 컴퓨터에 저장하는 작은 파일입니다.
동일한 컴퓨터가 브라우저를 통해 페이지를 요청할 때마다 쿠키도 전송됩니다.
PHP를 사용하면 쿠키 값을 생성하고 검색할 수 있습니다.
세션
응용 프로그램을 사용하여 작업할 때는 응용 프로그램을 열고 몇 가지 변경 사항을 적용한 다음 닫습니다.
이는 세션과 매우 유사합니다. 컴퓨터는 당신이 누구인지 알고 있습니다.
애플리케이션을 시작할 때와 종료할 때를 알고 있습니다.
그러나 인터넷에는 한 가지 문제가 있습니다.
HTTP 주소는 상태를 유지하지 않기 때문에 웹 서버는 귀하가 누구인지,
무엇을 하는지 알지 못합니다.
세션 변수는 여러 페이지에서 사용할 사용자 정보(예: 사용자 이름, 선호하는 색상 등)를 저장하여 이 문제를 해결합니다.
기본적으로 세션 변수는 사용자가 브라우저를 닫을 때까지 지속됩니다.
그래서; 세션 변수는 단일 사용자에 대한 정보를 보유하며 하나의 애플리케이션의 모든 페이지에서 사용할 수 있습니다
로그인 페이지 코드 분석
id와 pw를 get방식으로 얻어옴
$id_param = $_GET['id_param'];
$pw_param = $_GET['pw_param'];
디폴트 변수 선언
$total_failed_login=3;
$lockout_time=3; //3분을 의미함
$account_locked=false;
//기본 틀(mysqli_를 이용한 함수 구현 : SQL 인젝션 공격 가능)
$sql = "select failed_login, last_login from users where id_param='$id_param'"
위 정보를 result에 담아서 쿼리 보내기
$result = mysqli_query($conn,$sql);
데이터가 있으면 OK 없으면 NO 비교값은 num_rows로 얻어오고 0과 비교
if(mysqli_num_rows($result) > 0) {
echo "OK"."
"; #OK
} else{
echo "NO"."
배열로 가져옴
$row = mysqli_fetch_assoc($result);
*mysqli_fetch_assoc — 결과 집합의 다음 행을 연관 배열로 가져옵니다.
값이 있으면 -> 로그인 실패와 디폴트 변수인 로그인 실패 횟수를 비교하여 코드를 실행
타임아웃 시간중 재시도하면 마지막 접속에 추가 시간을 더함
현재 시간과 타임아웃 시간을 비교하여 코드를 실행
if((mysqli_num_rows($result) > 0) && $row['failed_login'] > $total_failed_login) {
$last_login = $row['last_login'];
$timeout = strtotime($last_login)+($lockout_time*60);
$timenow = time();
if($timenow < $timeout) {
$account_locked = true;
echo "현재 타임존 ". date_default_timezone_get() ."
";
echo "타입아웃시간 : " . date("Y-m-d H:i:s",$timeout)."
";
echo "현재시간 : " . date("Y-m-d H:i:s",$timenow)."
";
echo "<.script>alert('락상태입니다.');";
exit;
} else {
$account_locked = false;
echo "현재 타임존 ". date_default_timezone_get() ."
";
echo "타입아웃시간 : " . date("Y-m-d H:i:s",$timeout)."
";
echo "현재시간 : " . date("Y-m-d H:i:s",$timenow)."
";
echo "<.script>alert('락해제상태입니다');";
}
}
쿠키와 세션 설정
아이디와 비밀번호를 확인하여서 sql 쿼리 작성
타임아웃 이후 시간에 로그인 성공시 몇번의 공격시도가 있었는지 알려주는 설정
로그인 성공하면 카운터 초기화 작동
로그인 실패하면 로그인 실패+1 (시간은 위에서 추가됨)
$sql = "select * from users where id_param='$id_param' and pw_param='$pw_param'";
echo $sql;
$result = mysqli_query($conn,$sql);
if((mysqli_num_rows($result)) > 0 && ($account_locked==false)) {
#쿠키 또는 세션!
# A cookie is often used to identify a user!
echo "로그인 성공";
/*
setcookie("cid_param","admin",time()+(60),"/");
echo $_COOKIE["cid_param"];
//exit;
*/
#세션
# A ssesion is a way to store information(in variable) to be used accros multiple pages
# Unlike a cookie, the information is not stored on the users computer
$row = mysqli_fetch_assoc($result);
$failed_login = $row['failed_login'];
$last_login = $row['last_login'];
if($failed_login > $total_failed_login) {
echo "Brute Force 공격을 받았군요!!"."
";
echo $failed_login."번의 공격시도가 있었습니다.";
}
#카운터 초기화
$sql="update users set failed_login=0 where id_param='admin'";
mysqli_query($conn,$sql);
$_SESSION["sid_param"]="admin";
#echo "<.script>location.href='/index.php';";
} else {
sleep(rand(2,4));
echo rand(2,4);
echo "<.script>alert('로그인실패');";
#카운터 초기화
$sql="update users set failed_login=failed_login+1 where id_param='$id_param'";
mysqli_query($conn,$sql);
}
$sql="update users set last_login = now() where id_param='$id_param'";
mysqli_query($conn,$sql);
mysqli_close($conn);
echo "<.script>location.href='/index.php';";