해킹당했습니다. 채택완료
1. 그누보드 5.3.3.3 사용중입니다.
2. 아미나 사용중입니다.
서버는 안털린 거 같은데, 관리자 계정이 털렸습니다.
집 말고 관리자 로그인 한 적 없구요.
<?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
// 세션이 시작되지 않았다면 세션 시작
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
function admin_access() {
global $is_admin;
// 허용된 IP 주소 목록 (IPv4 및 IPv6 포함)
$allowed_ips = [
'12.34.56.78',
];
// 로그 파일 경로
$log_file = '/var/www/html/admin.log';
// 현재 사용자 IP
$user_ip = $_SERVER['REMOTE_ADDR'];
// 브라우저 정보
$user_browser = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Unknown';
// 로그 기록 함수
function write_log($message, $log_file) {
$date = date('Y-m-d H:i:s');
$log_entry = "[$date] $message\n";
file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
}
// 세션 변수 이름 정의
$session_success_log = 'admin_login_success_logged';
$session_failure_log = 'admin_login_failure_logged';
if ($is_admin) {
// 로그인 성공 로그가 아직 기록되지 않았다면
if (!isset($_SESSION[$session_success_log])) {
if (in_array($user_ip, $allowed_ips)) {
// 어드민 접속 성공 로그
$message = "LOGIN_SUCCESS - IP: $user_ip - Browser: $user_browser";
write_log($message, $log_file);
// 세션에 로그 기록 완료 표시
$_SESSION[$session_success_log] = true;
} else {
// 어드민 접속 실패 로그
$message = "LOGIN_FAILURE - IP: $user_ip - Browser: $user_browser";
write_log($message, $log_file);
// 실패 로그 기록 완료 표시 (필요 시)
$_SESSION[$session_failure_log] = true;
exit('비밀번호가 맞지 않습니다.');
}
}
} else {
// 관리자 권한이 없을 때 (로그인 시도 중일 가능성이 있음)
// 여기서는 로그인 시도 페이지에서만 로그를 기록하도록 설정할 수 있음
// 예시: 로그인 페이지일 경우에만 실패 로그 기록
// 로그인 페이지를 식별하는 조건을 추가해야 함 (예: 특정 GET/POST 파라미터 확인)
// 아래는 단순 예시입니다.
// 예를 들어, 로그인 시도 시 'login_attempt' 파라미터가 있을 때만 기록
if (isset($_POST['login_attempt']) && $_POST['login_attempt'] === '1') {
// 로그인 실패 로그가 아직 기록되지 않았다면
if (!isset($_SESSION[$session_failure_log])) {
$message = "LOGIN_FAILURE - IP: $user_ip - Browser: $user_browser";
write_log($message, $log_file);
// 세션에 실패 로그 기록 완료 표시
$_SESSION[$session_failure_log] = true;
}
}
}
}
// admin_access 함수 호출
admin_access();
?>
해당 소스 사용해서 등록된 아이피가 아니면 로그인이 안되게도 세팅해뒀습니다.
이유를 모르겠는데, 혹시 경험 많으신분, 짐작가는 이유가 있으신지 궁금합니다.
추가로 어디를 봐야하는지 조언 주시면 감사하겠습니다...
답변 5개
"""짐작가는 이유가 있으신지 궁금합니다 """
IP 기반 접근 제한을 구현하기 전에 또는 코드가 작동하지 않았을 때,
공격자가 관리자 계정에 접근했을 수 있으며,
또한 권한 설정이 잘못되어 관리자 계정 정보가 포함된 설정 파일이나
세션 정보가 노출 되었을 수 있으며,
그누보드의 구조는 익히 알려져 있기에,
'IP 스푸핑'이나 'brute force' 공격을 당했을 가능성도 있습니다.
세션 로그아웃 이나 비밀번호 변경은 하셨을 것같고,
현재 IP 제한 코드의 정상 동작 여부를 확인하셨나요?
- 관리자 계정이 아닌 상태에서, 허용되지 않은 IP에서 관리자 페이지에 접속을 시도,
- 서버가 파일 캐시를 사용하는 경우, IP 제한 코드가 반영되지 않았을 가능성이 있으니,
서버 캐시를 삭제하거나 재시작,
- IPv4와 IPv6 환경이 샤용되는 경우,
코드가 IPv6 주소를 제대로 처리하지 못할 수 있으니, IPv6 주소도 테스트 등을 하여 보세요.
♠ 해결 방안
*관리자 경로를 예측하기 어려운 이름으로 변경(예: /admin-asdgshrtjkk345678wrg).
*.htaccess(apache) 또는 서버 설정에서 특정 IP만 관리자 페이지에 접근할 수 있도록 제한.
</p>
<p><Directory "/path/to/admin">
Require ip 12.34.56.78
</Directory></p>
<p>
★ 아래는 관리자 페이지 접근, brute force 공격 등에 대응하여
제시하신 소스를 수정한 예시입니다.
</p>
<p><?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가</p>
<p>if (session_status() == PHP_SESSION_NONE) {
session_start();
}</p>
<p>define('ADMIN_LOG_FILE', '/var/log/admin_access.log');
define('FAILED_ATTEMPTS_FILE', '/var/log/failed_attempts.json');
define('MAX_LOGIN_ATTEMPTS', 5);
define('BLOCK_DURATION', 3600); // 차단 시간 (1시간)</p>
<p>// IP 검증 함수 (CIDR 지원)
function ip_in_allowed_range($ip, $allowed_ips) {
foreach ($allowed_ips as $allowed_ip) {
if (strpos($allowed_ip, '/') === false) {
// 단일 IP 비교
if ($ip === $allowed_ip) return true;
} else {
// CIDR 대역 비교
[$subnet, $bits] = explode('/', $allowed_ip);
$subnet_binary = ip2long($subnet);
$ip_binary = ip2long($ip);
$mask = -1 << (32 - $bits);
if (($ip_binary & $mask) === ($subnet_binary & $mask)) return true;
}
}
return false;
}</p>
<p>// 로그 기록 함수
function write_log($message) {
$date = date('Y-m-d H:i:s');
$log_entry = "[$date] $message\n";
file_put_contents(ADMIN_LOG_FILE, $log_entry, FILE_APPEND | LOCK_EX);
}</p>
<p>// 실패 시도 기록 및 차단 처리
function block_ip($ip) {
$failed_attempts = is_file(FAILED_ATTEMPTS_FILE) ? json_decode(file_get_contents(FAILED_ATTEMPTS_FILE), true) : [];
$current_time = time();</p>
<p> if (!isset($failed_attempts[$ip])) {
$failed_attempts[$ip] = ['count' => 0, 'last_attempt' => $current_time];
}</p>
<p> $failed_attempts[$ip]['count']++;
$failed_attempts[$ip]['last_attempt'] = $current_time;</p>
<p> // 차단 처리
if ($failed_attempts[$ip]['count'] > MAX_LOGIN_ATTEMPTS && ($current_time - $failed_attempts[$ip]['last_attempt'] < BLOCK_DURATION)) {
exit('Your IP has been temporarily blocked.');
}</p>
<p> file_put_contents(FAILED_ATTEMPTS_FILE, json_encode($failed_attempts));
}</p>
<p>// 관리자 접근 제한 함수
function admin_access() {
global $is_admin;</p>
<p> $allowed_ips = [
'12.34.56.78', // 단일 IP
'192.168.1.0/24', // CIDR 대역
];</p>
<p> $user_ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'];
$user_browser = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
$session_success_log = 'admin_login_success_logged_' . $user_ip;</p>
<p> // 실패 시도 감지 및 차단
block_ip($user_ip);</p>
<p> if ($is_admin && ip_in_allowed_range($user_ip, $allowed_ips)) {
// 세션 IP 바인딩
if (!isset($_SESSION['user_ip'])) {
$_SESSION['user_ip'] = $user_ip;
} elseif ($_SESSION['user_ip'] !== $user_ip) {
session_destroy();
exit('Session invalid due to IP mismatch.');
}</p>
<p> // 성공 로그
if (!isset($_SESSION[$session_success_log])) {
$message = "LOGIN_SUCCESS - IP: $user_ip - Browser: $user_browser";
write_log($message);
$_SESSION[$session_success_log] = true;
}
} else {
// 실패 로그
$request_method = $_SERVER['REQUEST_METHOD'];
$request_uri = $_SERVER['REQUEST_URI'];
$message = "LOGIN_FAILURE - IP: $user_ip - Browser: $user_browser - Method: $request_method - URI: $request_uri";
write_log($message);</p>
<p> // 차단 처리
block_ip($user_ip);</p>
<p> exit('Unauthorized access.');
}
}</p>
<p>// admin_access 함수 호출
admin_access();
?></p>
<p>
댓글을 작성하려면 로그인이 필요합니다.
관리자 계정이 털렸다는게
타 아이디로 관리자 권한 탈취 인가요.
아니면 순수 관리자 계정이 털렸다는건가요?
명확하게 현재 상황을 적어주셔야 합니다.
후자라면
$is_admin 변수로 하지 마시고 $member['mb_level'] 로 채크 하세요.
패스워드는 가급적 길게 영문 숫자 특수문자 조합으로 재설정 하시구요
그리고 해당 PC 가 털린건 아닌지도 채크해보시구요
댓글을 작성하려면 로그인이 필요합니다.
그누보드로는 해킹방어에 구조상 한계가 있습니다.
특히나, 플러그인 및 공개되어 있는 소스들의 짜집기라면...
그중 하나는 비집고 해킹할 부분이 존재한다고 봐야겠죠.
전문가와 상의하세요.
댓글을 작성하려면 로그인이 필요합니다.
1. 관리자 계정이 털렸다는 건 어떻게 아신건지요 ?
$log_file = '/var/www/html/admin.log'; 에서 확인하셨나요?
아니면, 저기에는 아무런 내용이 없는 건가요 ?
만약 저기에 내용이 기록이 되어있다면, 아이피 + 2차 인증 같은걸 고민해보셔야 합니다.
그래야 조금 더 보안적으로 좋을 듯 합니다.
그렇지만, 저기에 기록이 없다면... ? 무슨 내용을 확인하신 건지 조금 궁금하네요
2. 최신 버전이 아니네요 항상 최신 버전을 유지하시는 게 좋습니다.
답변에 대한 댓글 3개
그 단적인 예로 애초에 로그인이 막혔는데 글이 등록되었다면,
글 등록 관련을 조사(?)해야 할 것 같구요
mysql 같은 디비 비밀번호가 열린 건 아닌지 확인해보셔야 합니다.
혹시라도 서버에 비정상적인 파일이 없는지 새롭게 추가된 파일은 없는지도 한번 확인해보세요
2. 아미나 사용자가 아니라 정확한 답변은 아니지만, 애초에 "그누보드 기반"이라서, 그누보드 업데이트 부분만 패치 하면 될텐데요 ?
댓글을 작성하려면 로그인이 필요합니다.
답변에 대한 댓글 1개
댓글을 작성하려면 로그인이 필요합니다.
답변을 작성하려면 로그인이 필요합니다.
로그인
2. 아미나를 사용중이라 버전업이 어렵네요 ㅠㅠ