πŸ–₯️ μ„œλ¬΄PC μ›κ²©μ œμ–΄ μ›Œν¬ν”Œλ‘œμš°

2026-06-27 v3.0 톡합 4개 μŠ€ν‚¬ β†’ 1개 umbrella μ†Œμž₯λ‹˜ "μ„œλ¬΄PC" λͺ…λ Ή β†’ μžλ™ 가동

곡무(Linux) β†’ μ„œλ¬΄PC(Windows 192.168.0.50) 톡합 원격 μ œμ–΄. SSH 노크 β†’ WOL 깨우기 β†’ Flask Agent β†’ 토큰 인증 β†’ 35+ μ—”λ“œν¬μΈνŠΈ.

πŸ“Š ν˜„μž¬ μ„œλ¬΄PC μƒνƒœ (2026-06-27 14:08 KST 검증)

SSH 접속
βœ… OK
Flask Agent
βœ… :5000 ν™œμ„±
ν˜„μž¬ 토큰
25802580
Agent PID
20944
Agent μ„Έμ…˜
Session 1 (Console)
ν™œμ„± μœˆλ„μš°
308개
μ—μ΄μ „νŠΈ 폴더
C:\Users\lee\hermes_kakao\
μ†ŒμŠ€ 파일
agent.py
Python 경둜
C:\Users\lee\AppData\Local\Programs\Python\Python312\python.exe
MAC μ£Όμ†Œ
9C:6B:00:0B:3B:C2
πŸ”„ 토큰 λ³€κ²½ μ•Œλ¦Ό: κΈ°μ‘΄ hermes_seomu_2026 β†’ ν˜„μž¬ 25802580둜 변경됨 (2026-06-27). 이전 토큰 μ‚¬μš© μ‹œ 403 Forbidden λ°˜ν™˜λ¨.

πŸ₯‡ 5단계 μ›Œν¬ν”Œλ‘œμš°

1. SSH 노크
2. WOL 깨우기
3. Flask Agent
4. 토큰 인증
5. μ—”λ“œν¬μΈνŠΈ

1단계: SSH 노크 β€” μ•ˆ 자고 μžˆλ‚˜?

1
ssh -o ConnectTimeout=5 seomu "echo OK"
μ‘λ‹΅μƒνƒœλ‹€μŒ
OKβœ… κΉ¨μ–΄μžˆμŒβ†’ 3단계
Connection refused❌ S3 μ ˆμ „β†’ 2단계 (WOL)
timeout❌ λ„€νŠΈμ›Œν¬ λ˜λŠ” μ ˆμ „β†’ 2단계 (WOL)

2단계: WOL 깨우기 (자고 μžˆμ„ λ•Œλ§Œ)

2
from wakeonlan import send_magic_packet
send_magic_packet('9C:6B:00:0B:3B:C2')

전원/μ ˆμ „ μ„€μ • (κ· ν˜•ν˜• ν”Œλžœ, 2026-06-27 14:23 KST μ‹€μΈ‘):

λ‹¨κ³„μ‹œμ λ™μž‘
ν™”λ©΄λ³΄ν˜ΈκΈ°30λΆ„ (ScreenSaveTimeOut=1800)ν™”λ©΄λ³΄ν˜ΈκΈ° ν‘œμ‹œ (ScreenSaveActive=1, 잠금 μ—†μŒ)
ν™”λ©΄ 끄기30λΆ„ (VIDEOIDLE=0x00000708)λͺ¨λ‹ˆν„°λ§Œ 꺼짐
S3 μ ˆμ „40λΆ„ (STANDBYIDLE=0x00000960)SSH/Agent 접속 λΆˆκ°€
μ΅œλŒ€μ ˆμ „λΉ„ν™œμ„± (HIBERNATEIDLE=0)WOL 영ν–₯ μ—†μŒ
ν•˜μ΄λΈŒλ¦¬λ“œ μ ˆμ „ν™œμ„± (HYBRIDSLEEP=1)S3 + hibernation image λ™μ‹œ
πŸ“‹ μ‚¬μš©μž λΆ€μž¬ μ‹œ 흐름:
β€’ 0~30λΆ„: ν™”λ©΄ 정상 ν‘œμ‹œ
β€’ 30λΆ„: ν™”λ©΄λ³΄ν˜ΈκΈ° μ§„μž… (잠금 μ—†μŒ)
β€’ 30λΆ„: λͺ¨λ‹ˆν„° 꺼짐
β€’ 40λΆ„: S3 μ ˆμ „ μ§„μž… β†’ SSH/Agent λŠκΉ€ β†’ WOL ν•„μš”
βœ… μ„€μ • μ™„λ£Œ: ν™”λ©΄λ³΄ν˜ΈκΈ° 30λΆ„ / ν™”λ©΄ 끄기 30λΆ„ / S3 μ ˆμ „ 40λΆ„ (μ†Œμž₯λ‹˜ GUI 직접 μ„€μ • λ˜λŠ” Administrators κΆŒν•œ ν•„μš”)
⚠️ WOL ν›„ 15초 λŒ€κΈ° ν•„μˆ˜ β€” λΆ€νŒ… μ‹œκ°„ ν•„μš”

3단계: Flask Agent μƒνƒœ 확인

3
GET http://192.168.0.50:5000/?token=25802580
β†’ "Windows Kakao Agent v2 (monitor support)"

Agent μ£½μ–΄μžˆμœΌλ©΄ Session 1μ—μ„œ μž¬μ‹€ν–‰:

ssh -o ConnectTimeout=10 seomu "schtasks /run /tn hermes_agent"
sleep 8  # Agent λΆ€νŒ… λŒ€κΈ°
βœ… Session 1 검증 (ν˜„μž¬ PID 20944):
tasklist /fi "PID eq 20944" /v /fo list β†’ Session#: 1
β†’ win32com (Excel COM), SendKeys, GUI μ œμ–΄ λͺ¨λ‘ 정상 μž‘λ™

4단계: 토큰 인증

4

ν˜„μž¬ 토큰: 25802580 (2026-06-27 λ³€κ²½)

호좜 νŒ¨ν„΄ (query string):

import urllib.request
url = "http://192.168.0.50:5000/windows?token=25802580"
req = urllib.request.Request(url)
resp = urllib.request.urlopen(req, timeout=5).read().decode()

호좜 νŒ¨ν„΄ (Bearer header):

import urllib.request, json
TOKEN = "25802580"
req = urllib.request.Request("http://192.168.0.50:5000/exec",
    data=json.dumps({"cmd": "powershell -Command 'Get-Date'"}).encode(),
    headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"},
    method="POST")
urllib.request.urlopen(req, timeout=35).read()
🚨 토큰 λ§ˆμŠ€ν‚Ή 함정 β€” LLM이 토큰을 좜λ ₯ν•˜λ©΄ ***둜 μžλ™ λ§ˆμŠ€ν‚Ήλ¨. Python one-liner에 직접 μ‚½μž…ν•΄μ•Ό λ™μž‘. export TOKEN=... ν›„ $TOKEN μ°Έμ‘° μ‹œ 빈 λ¬Έμžμ—΄λ‘œ μΉ˜ν™˜λ˜μ–΄ 401/403 λ°˜ν™˜.

5단계: μ—”λ“œν¬μΈνŠΈ 호좜 (35+ κ°€μ§€)

πŸ–±οΈ 마우슀 / ν‚€λ³΄λ“œ

GET/click
마우슀 클릭 (?x=&y=&button=)
GET/double_click
더블 클릭
GET/right_click
우클릭
GET/scroll
슀크둀 (?delta=)
GET/move
마우슀 이동
GET/type
ν…μŠ€νŠΈ μž…λ ₯
GET/hotkey
단좕킀 (?keys=)
GET/keypress
단일 ν‚€

πŸ“Έ 캑처 / 정보

GET/screenshot
ν™”λ©΄ PNG 캑처
GET/windows
ν™œμ„± μœˆλ„μš° λͺ©λ‘ (ν˜„μž¬ 308개)
GET/foreground
ν˜„μž¬ ν™œμ„± μ°½
GET/processes
μ‹€ν–‰ 쀑인 ν”„λ‘œμ„ΈμŠ€
GET/monitors
λ“€μ–Ό λͺ¨λ‹ˆν„° 정보
GET/sysinfo
μ‹œμŠ€ν…œ 정보

πŸͺŸ μœˆλ„μš° μ œμ–΄

GET/close_hwnd
WM_CLOSE (μš°μ•„ μ’…λ£Œ)
GET/minimize_hwnd
μ΅œμ†Œν™”
GET/maximize_hwnd
μ΅œλŒ€ν™”
GET/restore_hwnd
볡원
GET/hide_hwnd
숨기기
GET/show_hwnd
ν‘œμ‹œ
GET/focus_hwnd
포컀슀
GET/move_hwnd
SetWindowPos
GET/find_hwnd
제λͺ©μœΌλ‘œ HWND 검색

βš™οΈ ν”„λ‘œμ„ΈμŠ€ / μ‹œμŠ€ν…œ

GET/kill_pid
PID둜 taskkill /F
GET/kill_name
이미지λͺ…μœΌλ‘œ μ’…λ£Œ
GET/run
ν”„λ‘œμ„ΈμŠ€ μ‹€ν–‰
GET/run_wait
μ‹€ν–‰ + κ²°κ³Ό λŒ€κΈ°
GET/sleep
μ ˆμ „ λͺ¨λ“œ
GET/reboot
μž¬λΆ€νŒ…
GET/shutdown
μ‹œμŠ€ν…œ μ’…λ£Œ
GET/cancel_shutdown
μ’…λ£Œ μ·¨μ†Œ
GET/toast
Windows ν† μŠ€νŠΈ μ•Œλ¦Ό
GET/kakao
μΉ΄μΉ΄μ˜€ν†‘ κ΄€λ ¨
GET/clipboard/get
ν΄λ¦½λ³΄λ“œ 읽기
GET/clipboard/set
ν΄λ¦½λ³΄λ“œ μ“°κΈ°

πŸ“Š Excel 원격 μ œμ–΄ (검증됨)

λ“€μ–Ό λͺ¨λ‹ˆν„° 함정 β€” κ°€μž₯ μ€‘μš”!

🚨 Excel κΈ°λ³Έ 2번 λͺ¨λ‹ˆν„°(Xβ‰₯1920)에 ν‘œμ‹œλ¨ β€” μžλ™ν™” μ‹œ 1번 λͺ¨λ‹ˆν„°λ‘œ κ°•μ œ 이동 ν•„μˆ˜
import ctypes, time
user32 = ctypes.windll.user32

EXCEL_HWND = 1247082  # μ‹€μ œ PID/PowerShellμ—μ„œ 확인
SWP_SHOWWINDOW = 0x0040
SWP_NOZORDER = 0x0004

# βœ… κ²€μ¦λœ νŒ¨ν„΄ (1번 λͺ¨λ‹ˆν„° λ‚΄λΆ€ μ’Œν‘œ λͺ…μ‹œ)
user32.SetWindowPos(EXCEL_HWND, 0, 100, 100, 1700, 1000,
                    SWP_SHOWWINDOW | SWP_NOZORDER)
time.sleep(0.5)
user32.ShowWindow(EXCEL_HWND, 3)  # SW_MAXIMIZE

μ…€ μž…λ ₯ + λ„ν˜• μ‚½μž…

import win32com.client, pythoncom
pythoncom.CoInitialize()
try:
    excel = win32com.client.Dispatch("Excel.Application")
    excel.Visible = True
    wb = excel.Workbooks.Open(r"C:\Users\lee\Desktop\hermes_test.xlsx")
    ws = wb.Worksheets(1)

    # 병합 ν•΄μ œ ν›„ μ΄ˆκΈ°ν™”
    ws.UsedRange.UnMerge()
    ws.Cells.Clear()
    while ws.Shapes.Count > 0:
        ws.Shapes(1).Delete()

    # μ…€ μž…λ ₯
    ws.Range("A1").Value = "ν…μŠ€νŠΈ"

    # λ„ν˜• (별)
    cell = ws.Range("E5")
    shape = ws.Shapes.AddShape(12, cell.Left, cell.Top, cell.Width, cell.Height)
    shape.Fill.ForeColor.RGB = 65535  # λ…Έλž€μƒ‰
    shape.TextFrame.Characters().Text = "별"

    wb.Save()
finally:
    pythoncom.CoUninitialize()

xlsxwriter (Excel μΈμŠ€ν„΄μŠ€ 없이)

πŸ’‘ μ–Έμ œ μ‚¬μš©: μ’€λΉ„ Excel λ•Œλ¬Έμ— win32com SaveAs μ‹€νŒ¨ν•  λ•Œ λŒ€μ•ˆ
import xlsxwriter

wb = xlsxwriter.Workbook(r"E:\OneDrive\Telegram\report.xlsx")

# ⚠️ xlsxwriterλŠ” hex λ¬Έμžμ—΄ μƒ‰μƒλ§Œ!
def _hex(n):
    return "#{:06X}".format(n & 0xFFFFFF)

fmt_title = wb.add_format({
    "bold": True, "font_size": 18,
    "bg_color": _hex(4474445),  # μ§„ν•œ 청둝
    "font_color": "#FFFFFF",
    "align": "center", "valign": "vcenter",
})

ws = wb.add_worksheet("κ°œμš”")
ws.merge_range("B2:D2", "πŸ—οΈ λ³΄κ³ μ„œ 제λͺ©", fmt_title)
wb.close()

πŸ—οΈ CADian 원격 μ œμ–΄ (μ œν•œμ )

⚠️ CADian λΉ„ν‘œμ€€ UI β€” 자체 UI ν”„λ ˆμž„μ›Œν¬(ObjectARX 기반)둜 Excelκ³Ό μ™„μ „νžˆ 닀름:

βœ… ꢌμž₯: .scr 슀크립트 (HWND 무관)

# demo.scr
_-LAYER
N
MyLayer
C
7
S
MyLayer
_-LINE
0,0
100,0
100,100
0,100
0,0
_-QSAVE

κ·œμΉ™: _ = μ˜μ–΄ λͺ…λ Ή κ°•μ œ, - = CLI λͺ¨λ“œ (λ‹€μ΄μ–Όλ‘œκ·Έ νšŒν”Ό)

κ²€μ¦λœ CADian 단좕킀

λ™μž‘λ‹¨μΆ•ν‚€
μƒˆ 파일Alt+N λ˜λŠ” Alt+O
μ €μž₯Ctrl+S
λ‹€λ₯Έ 이름 μ €μž₯Ctrl+Shift+S
인쇄Ctrl+P
μ‹€ν–‰ μ·¨μ†ŒCtrl+Z
파일 메뉴Alt+F
λ‹«κΈ°Alt+F4

πŸ’» PowerShell / λͺ…λ Ή μ‹€ν–‰

SSH 직접 μ‹€ν–‰

ssh seomu 'powershell -NoProfile -Command "Get-Date"'

Flask Agent /exec

import urllib.request, json, base64
TOKEN = "25802580"

cmd = '"C:/Users/lee/AppData/Local/Programs/Python/Python312/python.exe" "C:/path/script.py" > "C:/path/out.txt" 2>&1'

req = urllib.request.Request("http://192.168.0.50:5000/exec",
    data=json.dumps({"cmd": cmd, "timeout": 60}).encode(),
    headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"},
    method="POST")
urllib.request.urlopen(req, timeout=65).read()
⚠️ Python 경둜 β€” μ ˆλŒ€ 경둜 ν•„μˆ˜!
κ²½λ‘œμƒνƒœ
C:\Python312\python.exe❌ μ—†μŒ
C:\Python311\python.exe❌ μ—†μŒ
C:\Users\lee\AppData\Local\Programs\Python\Python312\python.exeβœ… μœ μΌν•œ ν™œμ„±

🚨 Session 0 vs Session 1 (핡심!)

μ„Έμ…˜win32com (Excel)GUI μ œμ–΄SendKeys
Session 0 (Services)❌ WebView2 κΆŒν•œ 였λ₯˜βŒ Session 1 μ°½ μ ‘κ·Ό λΆˆκ°€βŒ Session 1 μ°½ 도달 λΆˆκ°€
Session 1 (Console)βœ… μ •μƒβœ… μ •μƒβœ… 정상

Session 1 검증 νŒ¨ν„΄

AGENT_PID=$(curl -s "http://192.168.0.50:5000/sysinfo?token=25802580" | python3 -c "import json,sys; print(json.load(sys.stdin)['pid'])")
ssh -o ConnectTimeout=10 seomu "tasklist /fi \"PID eq $AGENT_PID\" /v /fo list | findstr \"Session#:\""

# Session#: 1 β†’ 정상
# Session#: 0 β†’ μž¬μ‹€ν–‰ ν•„μš”:
ssh seomu "taskkill /f /im python.exe"
ssh seomu "schtasks /run /tn hermes_agent"
sleep 8

πŸ”„ 톡합 μ „ν›„ (2026-06-27)

μƒνƒœμŠ€ν‚¬μ—­ν• 
❌ 톡합 μ „ (4개) seomu-agent-http
seomu-excel-control
seomu-wol-wake
cross-platform-delegation
λΆ„μ‚° 관리, 호좜 μ‹œ 4개 skill_view ν•„μš”, λ©”λͺ¨λ¦¬ 쀑볡
βœ… 톡합 ν›„ (1개) seomu-remote-connect 단일 umbrella μŠ€ν‚¬, "μ„œλ¬΄PC" ν‚€μ›Œλ“œλ‘œ μžλ™ 가동, λ©”λͺ¨λ¦¬ μ ˆμ•½

πŸ”§ λΉ λ₯Έ 진단 λͺ…λ Ήμ–΄

# SSH 접속 확인
ssh -o ConnectTimeout=5 seomu "echo OK"

# Python ν”„λ‘œμ„ΈμŠ€ + μ„Έμ…˜ 확인
ssh seomu 'tasklist /fi "imagename eq python.exe" /v /fo list'

# Flask Agent μƒνƒœ
curl -s "http://192.168.0.50:5000/sysinfo?token=25802580" | python3 -m json.tool

# ν™œμ„± μœˆλ„μš° λͺ©λ‘
curl -s "http://192.168.0.50:5000/windows?token=25802580" | python3 -m json.tool | head -50

# quser (μ‚¬μš©μž 둜그인 확인)
ssh seomu 'quser'

# ν™”λ©΄λ³΄ν˜ΈκΈ° μƒνƒœ
ssh seomu 'powershell -NoProfile -Command "Get-ItemProperty -Path ''HKCU:\Control Panel\Desktop'' | Select ScreenSaveActive, ScreenSaverIsSecure"'

# μ ˆμ „ μ„€μ •
ssh seomu 'powercfg /getactivescheme'

πŸ“‘ 호슀트 정보 μš”μ•½

ν•­λͺ©κ°’
호슀트DESKTOP-2DTT7CO
MAC9C:6B:00:0B:3B:C2
IP192.168.0.50
SSH μ‚¬μš©μžlee
SSH aliasseomu
Flask Agenthttp://192.168.0.50:5000
토큰25802580 (2026-06-27 λ³€κ²½)
PythonC:\Users\lee\AppData\Local\Programs\Python\Python312\python.exe
μ—μ΄μ „νŠΈ 폴더C:\Users\lee\hermes_kakao\
Flask Agent μ†ŒμŠ€C:\Users\lee\hermes_kakao\agent.py
μž‘μ—… 폴더C:\Users\lee\AppData\Local\Temp\
🏠 ν™ˆμœΌλ‘œ πŸ“š Hermes μœ„ν‚€