해킹당했습니다.
본문
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만 관리자 페이지에 접근할 수 있도록 제한.
<Directory "/path/to/admin">
Require ip 12.34.56.78
</Directory>
★ 아래는 관리자 페이지 접근, brute force 공격 등에 대응하여
제시하신 소스를 수정한 예시입니다.
<?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
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시간)
// 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;
}
// 로그 기록 함수
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);
}
// 실패 시도 기록 및 차단 처리
function block_ip($ip) {
$failed_attempts = is_file(FAILED_ATTEMPTS_FILE) ? json_decode(file_get_contents(FAILED_ATTEMPTS_FILE), true) : [];
$current_time = time();
if (!isset($failed_attempts[$ip])) {
$failed_attempts[$ip] = ['count' => 0, 'last_attempt' => $current_time];
}
$failed_attempts[$ip]['count']++;
$failed_attempts[$ip]['last_attempt'] = $current_time;
// 차단 처리
if ($failed_attempts[$ip]['count'] > MAX_LOGIN_ATTEMPTS && ($current_time - $failed_attempts[$ip]['last_attempt'] < BLOCK_DURATION)) {
exit('Your IP has been temporarily blocked.');
}
file_put_contents(FAILED_ATTEMPTS_FILE, json_encode($failed_attempts));
}
// 관리자 접근 제한 함수
function admin_access() {
global $is_admin;
$allowed_ips = [
'12.34.56.78', // 단일 IP
'192.168.1.0/24', // CIDR 대역
];
$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;
// 실패 시도 감지 및 차단
block_ip($user_ip);
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.');
}
// 성공 로그
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);
// 차단 처리
block_ip($user_ip);
exit('Unauthorized access.');
}
}
// admin_access 함수 호출
admin_access();
?>
!-->!-->
1. 관리자 계정이 털렸다는 건 어떻게 아신건지요 ?
$log_file = '/var/www/html/admin.log'; 에서 확인하셨나요?
아니면, 저기에는 아무런 내용이 없는 건가요 ?
만약 저기에 내용이 기록이 되어있다면, 아이피 + 2차 인증 같은걸 고민해보셔야 합니다.
그래야 조금 더 보안적으로 좋을 듯 합니다.
그렇지만, 저기에 기록이 없다면... ? 무슨 내용을 확인하신 건지 조금 궁금하네요
2. 최신 버전이 아니네요 항상 최신 버전을 유지하시는 게 좋습니다.
그누보드로는 해킹방어에 구조상 한계가 있습니다.
특히나, 플러그인 및 공개되어 있는 소스들의 짜집기라면...
그중 하나는 비집고 해킹할 부분이 존재한다고 봐야겠죠.
전문가와 상의하세요.
관리자 계정이 털렸다는게
타 아이디로 관리자 권한 탈취 인가요.
아니면 순수 관리자 계정이 털렸다는건가요?
명확하게 현재 상황을 적어주셔야 합니다.
후자라면
$is_admin 변수로 하지 마시고 $member['mb_level'] 로 채크 하세요.
패스워드는 가급적 길게 영문 숫자 특수문자 조합으로 재설정 하시구요
그리고 해당 PC 가 털린건 아닌지도 채크해보시구요