4840 - Pentesting OPC UA

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

Basic Information

OPC UA, standing for Open Platform Communications Unified Access, ๋Š” ์ œ์กฐ, ์—๋„ˆ์ง€, ํ•ญ๊ณต์šฐ์ฃผ ๋ฐ ๋ฐฉ์œ„ ๋“ฑ ๋‹ค์–‘ํ•œ ์‚ฐ์—…์—์„œ ๋ฐ์ดํ„ฐ ๊ตํ™˜๊ณผ ์žฅ๋น„ ์ œ์–ด์— ์‚ฌ์šฉ๋˜๋Š” ์ค‘์š”ํ•œ ์˜คํ”ˆ ์†Œ์Šค ํ”„๋กœํ† ์ฝœ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ PLC๋ฅผ ํฌํ•จํ•œ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฒค๋”์˜ ์žฅ๋น„๋“ค์ด ์ƒํ˜ธ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

๊ตฌ์„ฑ์ƒ ๊ฐ•๋ ฅํ•œ ๋ณด์•ˆ ์กฐ์น˜๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ข…์ข… ๊ตฌํ˜• ์žฅ์น˜์™€์˜ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ๋ณด์•ˆ์ด ์™„ํ™”๋˜์–ด ์‹œ์Šคํ…œ์ด ์œ„ํ—˜์— ๋…ธ์ถœ๋˜๊ณค ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ OPC UA ์„œ๋น„์Šค๋Š” ๋น„ํ‘œ์ค€ ํฌํŠธ์—์„œ ๋™์ž‘ํ•  ๊ฒฝ์šฐ ๋„คํŠธ์›Œํฌ ์Šค์บ๋„ˆ๊ฐ€ ํƒ์ง€ํ•˜์ง€ ๋ชปํ•ด ์ฐพ๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Default port: 4840 (binary opc.tcp). ๋งŽ์€ ๋ฒค๋”๊ฐ€ ๋ณ„๋„์˜ discovery ์—”๋“œํฌ์ธํŠธ(/discovery), HTTPS ๋ฐ”์ธ๋”ฉ(4843/443), ๋˜๋Š” 49320 (KepServerEX), 62541 (OPC Foundation reference stack), 48050 (UaGateway) ๊ฐ™์€ ๋ฒค๋”๋ณ„ ๋ฆฌ์Šค๋„ˆ ํฌํŠธ๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ํ˜ธ์ŠคํŠธ๋‹น ์—ฌ๋Ÿฌ ์—”๋“œํฌ์ธํŠธ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐ ์—”๋“œํฌ์ธํŠธ๋Š” ์ „์†ก ํ”„๋กœํ•„, ๋ณด์•ˆ ์ •์ฑ… ๋ฐ user-token ์ง€์›์„ ๊ด‘๊ณ ํ•ฉ๋‹ˆ๋‹ค.

Built-in NodeIdWhy it matters
i=2253 (0:Server)ServerArray, ๋ฒค๋”/์ œํ’ˆ ๋ฌธ์ž์—ด ๋ฐ ๋„ค์ž„์ŠคํŽ˜์ด์Šค URI๋ฅผ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.
i=2256 (ServerStatus)๊ฐ€๋™ ์‹œ๊ฐ„(uptime), ํ˜„์žฌ ์ƒํƒœ ๋ฐ ์„ ํƒ์ ์œผ๋กœ ๋นŒ๋“œ ์ •๋ณด๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
i=2267 (ServerDiagnosticsSummary)์„ธ์…˜ ์ˆ˜, ์ค‘๋‹จ๋œ ์š”์ฒญ ๋“ฑ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋ธŒ๋ฃจํŠธํฌ์Šค ์‹œ๋„ ์ง€๋ฌธํ™”์— ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
i=85 (ObjectsFolder)๋…ธ์ถœ๋œ ์žฅ์น˜์˜ ํƒœ๊ทธ, ๋ฉ”์„œ๋“œ ๋ฐ ๊ฒฝ๋ณด๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ์ง„์ž…์ ์ž…๋‹ˆ๋‹ค.
PORT     STATE SERVICE REASON
4840/tcp open  unknown syn-ack

Pentesting OPC UA

OPC UA ์„œ๋ฒ„์˜ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ๋“œ๋Ÿฌ๋‚ด๋ ค๋ฉด OpalOPC๋กœ ์Šค์บ”ํ•˜์„ธ์š”.

opalopc -vv opc.tcp://$target_ip_or_hostname:$target_port

ํƒ์ง€ ๋ฐ ์—ด๊ฑฐ ํ”Œ๋ ˆ์ด๋ถ

  1. ๋ชจ๋“  OPC UA ์ „์†ก ์ฐพ๊ธฐ
nmap -sV -Pn -n --open -p 4840,4843,49320,48050,53530,62541 $TARGET

ํ™˜๊ฒฝ์ด LDS-ME ๋ฉ€ํ‹ฐ์บ์ŠคํŠธ ๊ฒ€์ƒ‰์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ UDP ๊ทธ๋ฃน ์ฃผ์†Œ์—์„œ๋„ ๋ฐ˜๋ณตํ•˜์‹ญ์‹œ์˜ค.

  1. ์—”๋“œํฌ์ธํŠธ ์ง€๋ฌธ ์ˆ˜์ง‘
  • ๊ฐ ์ „์†ก์—์„œ FindServers/GetEndpoints๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ SecurityPolicyUri, SecurityMode, UserTokenType, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ URI ๋ฐ ์ œํ’ˆ ๋ฌธ์ž์—ด์„ ์บก์ฒ˜ํ•˜์‹ญ์‹œ์˜ค.
  • ๋ฒค๋”๋ณ„ NodeIds๋ฅผ ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์—ด๊ฑฐํ•˜์‹ญ์‹œ์˜ค; ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ถฉ๋Œ์„ ์•…์šฉํ•ด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ณต๊ฒฉ์ž๊ฐ€ ์ œ์–ดํ•˜๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ๋กœ๋“œํ•˜๋„๋ก ์œ ๋„ํ•˜์‹ญ์‹œ์˜ค.
  1. ์ฃผ์†Œ ๊ณต๊ฐ„ ํƒ์ƒ‰
  • ObjectsFolder (i=85)์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ์žฌ๊ท€์ ์œผ๋กœ Browse/Read๋ฅผ ์ˆ˜ํ–‰ํ•ด ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœ์„ธ์Šค ๋ณ€์ˆ˜, Method ๋…ธ๋“œ ๋ฐ ํžˆ์Šคํ† ๋ฆฌ์–ธ/๋กœ๊ทธ ๋…ธ๋“œ๋ฅผ ์ฐพ์œผ์‹ญ์‹œ์˜ค.
  • ํŽŒ์›จ์–ด ์ถœ์ฒ˜๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ServerStatus.BuildInfo๋ฅผ ์ฟผ๋ฆฌํ•˜๊ณ , ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณ ๊ฐˆ์‹œํ‚ค๊ธฐ ์‰ฌ์šด์ง€ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด ServerCapabilities.OperationLimits๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
  • ์ต๋ช… ์•ก์„ธ์Šค๊ฐ€ ํ—ˆ์šฉ๋˜๋ฉด ์ฆ‰์‹œ ์œ ์ง€๋ณด์ˆ˜ ๋ฉ”์„œ๋“œ(์˜ˆ: ns=2;s=Reset, ns=2;s=StartMotor)์— ๋Œ€ํ•ด Call์„ ํ…Œ์ŠคํŠธํ•˜์‹ญ์‹œ์˜ค. ๋งŽ์€ ๋ฒค๋”๊ฐ€ ์ปค์Šคํ…€ ๋ฉ”์„œ๋“œ์— ์—ญํ•  ๊ถŒํ•œ์„ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ฒƒ์„ ์žŠ์Šต๋‹ˆ๋‹ค.
  1. ์„ธ์…˜ ๋‚จ์šฉ
  • ๋‹ค๋ฅธ ์„ธ์…˜์—์„œ ์บก์ฒ˜ํ•œ(๋˜๋Š” MITM/์ง„๋‹จ ๋…ธ์ถœ์„ ํ†ตํ•ด ํš๋“ํ•œ) AuthenticationToken ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋ณต์ œํ•˜์—ฌ ๊ธฐ์กด ๊ตฌ๋…์„ ํƒˆ์ทจํ•˜์‹ญ์‹œ์˜ค.
  • ์ˆ˜์‹ญ ๊ฐœ์˜ ๋น„ํ™œ์„ฑ ์„ธ์…˜์„ ์ƒ์„ฑํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ SessionDiagnostics ํ”Œ๋Ÿฌ๋”ฉ ์ƒํƒœ๋กœ ๋ชฐ์•„๋„ฃ์œผ์‹ญ์‹œ์˜ค; ์ผ๋ถ€ ์Šคํƒ์€ MaxSessionCount ํ•œ๋„๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.

OpalOPC๋ฅผ ์‚ฌ์šฉํ•œ ์ž๋™ ํ‰๊ฐ€

  • ์Šค์บ๋„ˆ๋Š” ๋Œ€ํ™”ํ˜• ๋˜๋Š” ํ—ค๋“œ๋ฆฌ์Šค๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด CI/CD ์Šคํƒ€์ผ OT ๋ฒ ์ด์Šค๋ผ์ธ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๊ณ„ ํŒ๋… ๊ฐ€๋Šฅํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํฌํŒ… ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ํŒŒ์ดํ”„ํ•˜์—ฌ ๋ช‡ ๋ถ„ ๋‚ด์— ์ต๋ช… ๋กœ๊ทธ์ธ, ์ทจ์•ฝํ•œ ์ •์ฑ…, ์ธ์ฆ์„œ ๊ฒ€์ฆ ์˜ค๋ฅ˜ ๋ฐ ์“ฐ๊ธฐ ๊ฐ€๋Šฅํ•œ ๋ณ€์ˆ˜๋ฅผ ๊ฐ•์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • OpalOPC ์ถœ๋ ฅ์„ ์ˆ˜๋™ ํƒ์ƒ‰๊ณผ ๊ฒฐํ•ฉํ•˜์‹ญ์‹œ์˜ค: ๋ฐœ๊ฒฌ๋œ ์—”๋“œํฌ์ธํŠธ ๋ชฉ๋ก์„ ์‚ฌ์šฉ์ž ๋„๊ตฌ์— ๋‹ค์‹œ ๊ณต๊ธ‰ํ•œ ๋‹ค์Œ ์˜ํ–ฅ์ด ํฐ ๋…ธ๋“œ(์˜ˆ: MotorControl/StartStop, RecipeManager/Upload)๋ฅผ ์„ ํƒ์ ์œผ๋กœ ๋ฌด๊ธฐํ™”ํ•˜์‹ญ์‹œ์˜ค.

๊ตฌํ˜• ๋ณด์•ˆ ์ •์ฑ… ๊ณต๊ฒฉ (Basic128Rsa15)

  • Bleichenbacher-style oracle: ์•„์ง ์‚ฌ์šฉ๋˜๋Š” Basic128Rsa15 ์ •์ฑ…(์ข…์ข… CMPOPCUASTACK_ALLOW_SHA1_BASED_SECURITY ๊ฐ™์€ ๋นŒ๋“œ ํ”Œ๋ž˜๊ทธ๋กœ ํ™œ์„ฑํ™”๋จ)์„ ํ—ˆ์šฉํ•˜๋Š” ์‹œ์Šคํ…œ์€ ํŒจ๋”ฉ ๊ฒ€์ฆ ์ฐจ์ด๋ฅผ leak ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์•…์šฉํ•ด ์กฐ์ž‘๋œ PKCS#1 v1.5 ๋ธ”๋กญ์œผ๋กœ CreateSession / OpenSecureChannel ํ•ธ๋“œ์…ฐ์ดํฌ๋ฅผ ๋Œ€๋Ÿ‰์œผ๋กœ ๋ณด๋‚ด ์„œ๋ฒ„ ์ธ์ฆ์„œ์˜ private key๋ฅผ ๋ณต๊ตฌํ•œ ๋’ค ์„œ๋ฒ„๋ฅผ ๊ฐ€์žฅํ•˜๊ฑฐ๋‚˜ ํŠธ๋ž˜ํ”ฝ์„ ๋ณตํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Authentication bypass: OPC Foundation์˜ .NET Standard ์Šคํƒ(1.5.374.158 ์ด์ „, CVE-2024-42512) ๋ฐ ์ข…์† ์ œํ’ˆ์€ ์ธ์ฆ๋˜์ง€ ์•Š์€ ๊ณต๊ฒฉ์ž๊ฐ€ ํ•ด๋‹น ๋ ˆ๊ฑฐ์‹œ ์ •์ฑ…์„ ๊ฐ•์ œ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ํ•˜๊ณ  ๊ทธ ์ดํ›„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜์ค€ ์ธ์ฆ์„ ๊ฑด๋„ˆ๋›ฐ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋‹จ ํ‚ค ์ž๋ฃŒ๋ฅผ ํš๋“ํ•˜๋ฉด ์ž„์˜์˜ UserIdentityTokens๋ฅผ ์ œ์‹œํ•˜๊ณ  ์„œ๋ช…๋œ ActivateSession ์š”์ฒญ์„ ์žฌ์ƒํ•˜์—ฌ ์‹ ๋ขฐ๋œ ์—”์ง€๋‹ˆ์–ด๋ง ์›Œํฌ์Šคํ…Œ์ด์…˜์ฒ˜๋Ÿผ ๊ณต์žฅ์„ ์šด์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์šด์˜ ์›Œํฌํ”Œ๋กœ์šฐ:
  1. GetEndpoints๋กœ ์ •์ฑ…์„ ์—ด๊ฑฐํ•˜๊ณ  Basic128Rsa15 ํ•ญ๋ชฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  2. CreateSession์—์„œ ํ•ด๋‹น ์ •์ฑ…(SecurityPolicyUri)์„ ๋ช…์‹œ์ ์œผ๋กœ ํ˜‘์ƒํ•œ ๋’ค ์˜ค๋ผํด ๋ฃจํ”„๋ฅผ ์‹คํ–‰ํ•ด ํ‚ค๋ฅผ ๋ณต๊ตฌํ•ฉ๋‹ˆ๋‹ค.
  3. ํ‚ค๋ฅผ ๋‚จ์šฉํ•ด ๊ณ ๊ถŒํ•œ ์„ธ์…˜์„ ์œ„์กฐํ•˜๊ฑฐ๋‚˜ ์—ญํ• ์„ ์ „ํ™˜ํ•˜๊ฑฐ๋‚˜, ์•…์„ฑ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ๋กœ ๋™์ž‘ํ•ด ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์€๋ฐ€ํžˆ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œํ•ฉ๋‹ˆ๋‹ค.
  • **CODESYS Runtime Toolkit (<3.5.21.0)**๋Š” ํ†ตํ•ฉ์ž๊ฐ€ CMPOPCUASTACK_ALLOW_SHA1_BASED_SECURITY๋กœ ์ปดํŒŒ์ผํ•  ๋•Œ๋งˆ๋‹ค Basic128Rsa15๋ฅผ ์žฌํ™œ์„ฑํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ”Œ๋ž˜๊ทธ๋ฅผ ์ „ํ™˜ํ•˜๊ณ  ์œ„์˜ ์˜ค๋ผํด ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•˜๋ฉด ๋Ÿฐํƒ€์ž„์˜ private key๋ฅผ leakํ•˜์—ฌ ํŒจ์น˜ ์ˆ˜์ค€ 3.5.21.0 ์ด์ƒ์ด ๋ฐฐํฌ๋  ๋•Œ๊นŒ์ง€ ์‹ ๋ขฐ๋œ ์—”์ง€๋‹ˆ์–ด๋ง ์›Œํฌ์Šคํ…Œ์ด์…˜์„ ๊ฐ€์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • OPC Foundation์€ ๋™์‹œ์— HTTPS ๋ฐ”์ธ๋”ฉ์— ๋Œ€ํ•ด CVE-2024-42513์„ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์ƒ์ด TLS๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ฃผ์žฅํ•˜๋”๋ผ๋„ ํ”„๋ก์‹œ ๋’ค์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ์ „์†ก์ด Basic128Rsa15๋กœ ์กฐ์šฉํžˆ ํด๋ฐฑ๋˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

2024-2025 ์ต์Šคํ”Œ๋กœ์ž‡ ๊ฐ์‹œ ๋ชฉ๋ก

  • open62541 fuzz_binary_decode (CVE-2024-53429): ๊ณผ๋„ํ•˜๊ฒŒ ํฐ ExtensionObject ๋ณธ๋ฌธ์„ ์„ ์–ธํ•˜๋Š” SecureChannel ์ฒญํฌ๊ฐ€ ๋””์ฝ”๋”๋กœ ํ•˜์—ฌ๊ธˆ ํ•ด์ œ๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์—ญ์ฐธ์กฐํ•˜๊ฒŒ ๋งŒ๋“ค๋ฏ€๋กœ, ์‚ฌ์ „ ์ธ์ฆ ๊ณต๊ฒฉ์ž๊ฐ€ open62541 โ‰ค1.4.6์„ ํฌํ•จํ•œ UA ์„œ๋ฒ„๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ํฌ๋ž˜์‹œ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Claroty ์ฝ”ํผ์Šค(opcua_message_boofuzz_db)๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ž์ฒด Boofuzz ํ•˜๋„ค์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ณ€ํ˜•๋œ OpenSecureChannel ์š”์ฒญ์„ ์ŠคํŒธํ•˜๋ฉด ์›Œ์น˜๋…์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ์ข…๋ฃŒํ•  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•˜๊ณ , ์žฌ๋ถ€ํŒ… ํ›„ ๋งŽ์€ ํ†ตํ•ฉ์ž๊ฐ€ ์ต๋ช… ๋ชจ๋“œ๋กœ ํด๋ฐฑํ•˜๋ฏ€๋กœ ์žฌ์—ด๊ฑฐํ•˜์‹ญ์‹œ์˜ค.
  • Softing OPC UA C++ SDK / edgeConnector / edgeAggregator (CVE-2025-7390): TLS ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ ํŒŒ์ดํ”„๋ผ์ธ์ด ์‹ ๋ขฐ๋œ Common Name์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ์–ด๋–ค ์ธ์ฆ์„œ๋“  ์ˆ˜์šฉํ•˜๋ฏ€๋กœ, ์ž„์‹œ ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰ํ•˜๊ณ  ํ”Œ๋žœํŠธ ์—”์ง€๋‹ˆ์–ด์˜ CN์„ ๋ณต์‚ฌํ•ด ์ž„์˜์˜ UserNameIdentityToken ๋˜๋Š” IssuedIdentityToken ๋ฐ์ดํ„ฐ๋กœ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ Basic128Rsa15๋กœ์˜ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ์™€ ๊ฒฐํ•ฉํ•˜๋ฉด ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์‹ ๋ขฐ ๋ชฉ๋ก์ด ์žฌ๊ตฌ์„ฑ๋  ๋•Œ๊นŒ์ง€ ์šด์˜์ž๋ฅผ ์ง€์†์ ์œผ๋กœ ๊ฐ€์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•…์šฉ์„ ์œ„ํ•œ OPC UA ํด๋ผ์ด์–ธํŠธ ์ œ์ž‘

  • Custom clients: drop-in ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(python-opcua/asyncua, node-opcua, open62541)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ต์Šคํ”Œ๋กœ์ž‡ ๋กœ์ง์„ ์ง์ ‘ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒค๋”๊ฐ€ ํŽŒ์›จ์–ด ์—…๋ฐ์ดํŠธ ํ›„ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์žฌ์ •๋ ฌํ•  ๋•Œ ์šฐ๋ฐœ์ ์ธ ํฌ๋กœ์Šค-๋„ค์ž„์ŠคํŽ˜์ด์Šค ์“ฐ๊ธฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ํ•ญ์ƒ ๋Œ€์ƒ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์ธ๋ฑ์Šค๋ฅผ ๊ฐ•์ œํ•˜์‹ญ์‹œ์˜ค.
  • ๋…ธ๋“œ ์•…์šฉ ์ฒดํฌ๋ฆฌ์ŠคํŠธ:
  • HistoryRead๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœ๋•์…˜ ํƒœ๊ทธ์˜ ๋…์  ๋ ˆ์‹œํ”ผ๋ฅผ ์Šค๋ƒ…์ƒทํ•ฉ๋‹ˆ๋‹ค.
  • TranslateBrowsePathsToNodeIds๋กœ ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ž์‚ฐ ์ด๋ฆ„์„ NodeIds๋กœ ํ•ด์„ํ•ด Claroty ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐ™์€ ๋„๊ตฌ์— ๊ณต๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.
  • Call + Method ๋…ธ๋“œ๋ฅผ ์ด์šฉํ•ด ์œ ์ง€๋ณด์ˆ˜ ์ž‘์—…(ํŽŒ์›จ์–ด ์—…๋กœ๋“œ, ๊ต์ •, ์žฅ์น˜ ์žฌ๋ถ€ํŒ…)์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  • RegisterNodes๋ฅผ ์˜ค์šฉํ•ด ์ž์ฃผ ์•ก์„ธ์Šค๋˜๋Š” ๋…ธ๋“œ๋ฅผ ๊ณ ์ •ํ•˜๊ณ  ํ•ธ๋“ค์„ ํ•ด์ œํ•˜์ง€ ์•Š์•„ ์ •๋‹นํ•œ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ธฐ์•„ ์ƒํƒœ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ์„ธ์…˜ ํ•˜๋“œ๋‹ ํ…Œ์ŠคํŠธ: ๋งค์šฐ ๋‚ฎ์€ ๋ฐœํ–‰ ๊ฐ„๊ฒฉ(50 ms ์ดํ•˜)๊ณผ ๊ณผ๋„ํ•œ ๋ชจ๋‹ˆํ„ฐ๋ง-์•„์ดํ…œ ํ๋ฅผ ์‚ฌ์šฉํ•ด ์ˆ˜์‹ญ ๊ฐœ์˜ ๊ตฌ๋…์„ ๋ฐ”์ธ๋”ฉํ•ด ๋ณด์‹ญ์‹œ์˜ค. ๋งŽ์€ ์Šคํƒ์ด RevisedPublishingInterval์„ ์ž˜๋ชป ๊ณ„์‚ฐํ•ด ์Šค์ผ€์ค„๋Ÿฌ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋กœ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.

ํผ์ง• ๋ฐ ์ต์Šคํ”Œ๋กœ์ž‡ ๊ฐœ๋ฐœ ๋„๊ตฌ

Claroty Team82๋Š” ๋‹ค๋…„๊ฐ„์˜ Pwn2Own ๊ธ‰ ์—ฐ๊ตฌ๋ฅผ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“ˆ๋กœ ํŒจํ‚ค์ง•ํ•œ ์˜คํ”ˆ์†Œ์Šค opcua-exploit-framework๋ฅผ ๊ณต๊ฐœํ–ˆ์Šต๋‹ˆ๋‹ค:

  • Modes: sanity (๊ฐ€๋ฒผ์šด ์ฝ๊ธฐ/๋ธŒ๋ผ์šฐ์ฆˆ), attacks (์˜ˆ: ์Šค๋ ˆ๋“œ ํ’€ ๊ณ ๊ฐˆ, ํŒŒ์ผ ์—…๋กœ๋“œ DoS), corpus (๋ฆฌํ”Œ๋ ˆ์ด ํผ์ง• ํŽ˜์ด๋กœ๋“œ), server (ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ฐฑ๋„์–ดํ•˜๊ธฐ ์œ„ํ•œ ์•…์„ฑ OPC UA ์„œ๋ฒ„).
  • ์‚ฌ์šฉ ์˜ˆ์‹œ:
# Run a DoS attack against a Prosys Simulation Server endpoint
python3 main.py prosys 10.10.10.10 53530 /OPCUA/SimulationServer thread_pool_wait_starvation

# Replay an entire Boofuzz corpus against open62541
python3 main.py open62541 192.168.1.50 4840 / opcua_message_boofuzz_db input_corpus_minimized/opcua.db
  • Rogue server ์‹œ๋‚˜๋ฆฌ์˜ค: ๋ฒˆ๋“ค๋œ asyncua ๊ธฐ๋ฐ˜ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•…์„ฑ ์ฃผ์†Œ ๊ณต๊ฐ„์„ ์ œ๊ณตํ•ด ํด๋ผ์ด์–ธํŠธ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ํ‘œ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: UA Expert ํด๋ก ์˜ ํŒŒ์‹ฑ ๋ฒ„๊ทธ๋ฅผ ์œ ๋ฐœํ•˜๋Š” ๊ณผ๋„ํ•œ ExtensionObject ์‘๋‹ต).
  • ๋Œ€์ƒ ์ปค๋ฒ„๋ฆฌ์ง€: ๋‚ด์žฅ๋œ ํ”„๋กœํŒŒ์ผ์ด Kepware, Ignition, Unified Automation, Softing SIS, Triangle Microworks, Node-OPCUA, Python OPC UA, Milo, open62541 ๋“ฑ๊ณผ ๋งคํ•‘๋˜์–ด ์žˆ์–ด ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด ์Šคํƒ ๊ฐ„์— ๋น ๋ฅด๊ฒŒ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ†ตํ•ฉ ํŒ: ์ž์ฒด ํผ์ €์™€ ์—ฐ๊ณ„ํ•˜์‹ญ์‹œ์˜คโ€”๋จผ์ € corpus ํŽ˜์ด๋กœ๋“œ๋ฅผ ์Šคํ”„๋ ˆ์ดํ•œ ๋‹ค์Œ OpalOPC๋กœ ํฌ๋ž˜์‹œ๊ฐ€ ๋ณด์•ˆ์ด ๋А์Šจํ•œ ๊ธฐ๋ณธ๊ฐ’(์ต๋ช… ๋กœ๊ทธ์ธ, ์„ค์ •๊ฐ’ ์“ฐ๊ธฐ ๊ถŒํ•œ ๋“ฑ)์„ ๋ถ€ํ™œ์‹œ์ผฐ๋Š”์ง€ ์žฌ๊ฒ€์ฆํ•˜์„ธ์š”.

์ธ์ฆ ์šฐํšŒ ์ทจ์•ฝ์  ์•…์šฉ

If authentication bypass vulnerabilities are found, you can configure an OPC UA client accordingly and see what you can access. This may allow anything from merely reading process values to actually operating heavy-duty industrial equipment.

์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์žฅ์น˜ ๋‹จ์„œ๋ฅผ ์–ป์œผ๋ ค๋ฉด ์ฃผ์†Œ ๊ณต๊ฐ„์—์„œ โ€œServerStatusโ€ ๋…ธ๋“œ ๊ฐ’์„ ์ฝ๊ณ  ํ•ด๋‹น ์žฅ์น˜์˜ ์‚ฌ์šฉ ์„ค๋ช…์„œ๋ฅผ google์—์„œ ๊ฒ€์ƒ‰ํ•˜์‹ญ์‹œ์˜ค.

Shodan

  • port:4840
  • port:62541 "OPC UA"
  • ssl:"urn:opcua"
  • product:"opc ua"

๊ฒ€์ƒ‰์„ ๋ฒค๋” ๋ฌธ์ž์—ด("Ignition OPC UA", "KepServerEX")์ด๋‚˜ ์ธ์ฆ์„œ("CN=UaServerCert")์™€ ๊ฒฐํ•ฉํ•ด ์นจํˆฌ์„ฑ ํ…Œ์ŠคํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ๊ณ ๊ฐ€์น˜ ์ž์‚ฐ์„ ์šฐ์„ ์ˆœ์œ„๋กœ ์ง€์ •ํ•˜์‹ญ์‹œ์˜ค.

References

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ