- ์ ์ฑ์ฝ๋๋ช : TRITON (๋ณ์นญ TRISIS ยท HatMan) โ FireEye๊ฐ TRITON, Dragos๊ฐ TRISIS, ๋ฏธ CISA์ ์ ์ฑ์ฝ๋ ๋ถ์๋ณด๊ณ ์(MAR)๊ฐ HatMan์ด๋ผ๋ ์ด๋ฆ์ ๋ถ์๋ค
- ๋ฑ์ฅ: ์ต์ด ํ์ 2017๋ 6์(๊ณต์ฅ ๋น์ ์ ์ ์ง) โ 8์ ๋ ๋ฒ์งธ ์ ์ง ํ ์กฐ์ฌ โ 2017๋ 12์ ๋์ธ ๊ณต๊ฐ(FireEyeยทDragos)
- ํ์ : ์๋์ด๋ ์ผ๋ ํธ๋ฆญ Triconex ์์ ๊ณ์ฅ์์คํ (SIS)(Tricon ๊ณ์ด ์ปจํธ๋กค๋ฌ) + ์ด๋ฅผ ๊ด๋ฆฌํ๋ ์์ง๋์ด๋ง ์ํฌ์คํ ์ด์ (TriStation 1131 ์ํํธ์จ์ด๊ฐ ์ค์น๋ Windows PC)
- ํผํด ํ์ฅ: ์ฌ์ฐ๋์๋ผ๋น์์ ์์ ํํ ๊ณต์ฅ 1๊ณณ์ผ๋ก ์ง๋ชฉ(๊ณต์ ํ์ธ์ ์ ํ์ )
- ๊ณต๊ฒฉ ์ฃผ์ฒด: Xenotime(Dragos ๋ช ๋ช ) โ FireEye๋ ๋ฌ์์ CNIIHM(์ค์ํํ๊ธฐ๊ณ๊ณผํ์ฐ๊ตฌ์) ์ฐ๊ณ ๊ฐ๋ฅ์ฑ์ ์ ๊ธฐํ๊ณ , 2020-10-23 ๋ฏธ ์ฌ๋ฌด๋ถ OFAC๊ฐ CNIIHM์ ์ ์ฌ ๋์์ผ๋ก ์ง์ ํ๋ฉฐ TRITON ๊ฐ๋ฐ์ ๊ทผ๊ฑฐ๋ก ๋ค์๋ค
- ์ฌ์ฉํ ๊ฒฝ๋ก: ์์ง๋์ด๋ง ์ํฌ์คํ ์ด์ โ SIS ์ปจํธ๋กค๋ฌ ์ฌ์ด์ ์์ง๋์ด๋ง ํ๋กํ ์ฝ TriStation(UDP 1502 ๊ณ์ด) โ IT ๋คํธ์ํฌ์์ OT๋ก ๋์ด์จ ๋ค '์ ์ ๊ด๋ฆฌ ํธ๋ํฝ'์ผ๋ก ์์ฅ
- ๋ณด๊ณ ๋ ๋๊ตฌ ๊ตฌ์ฑ: ๋ฐ์ฒ
trilog.exe+ ํ์ด์ฌ ํ๋ ์์ํฌ ์์ถ๋ณธ(๋ด๋ถtslib๋ชจ๋) +TsLow.dll/TsHi.dll(TriStation ํต์ ๊ณ์ธต) + ์ปจํธ๋กค๋ฌ์ ๊ธฐ๋กํ๋ ํ์ด๋ก๋(inject.bin๊ณ์ด) - ATT&CK for ICS ๋งคํ: Impair Process Control(T0836), Unauthorized Command Message, Program Download/Modify ๋ฑ โ ์ฆ '๋ฐ์ดํฐ ํ์ทจ'๊ฐ ์๋๋ผ ์ ์ดยท์์ ๋ก์ง ์์ฒด์ ๋ณ์กฐ
- ์์: ์ฐ์ ์์ ์์คํ (SIS)์ ๋ชฉํ๋ก ๋ง๋ค์ด์ง ์ต์ด์ ๊ณต๊ฐ ์ฌ๋ก. ๋ฐ์ดํฐ๋ ๋๋ ์๋ ์ธ๋ช ยทํ๊ฒฝ์ ์งํค๋ ๋ง์ง๋ง ๋ฐฉ์ด์ ์ ๊ณต๊ฒฉ ๋์์ผ๋ก ์ผ์๋ค๋ ์ ์์ ICS ์ ์ฑ์ฝ๋ ๊ณ๋ณด์ ๋ถ๊ธฐ์
1. ๋ฐฐ๊ฒฝ/์ญ์ฌ โ 'ํ๊ดด'์์ '์์ ๋ฌด๋ ฅํ'๋ก ๋์ด๊ฐ 2017๋
ICS(์ฐ์ ์ ์ด์์คํ ) ์ ์ฑ์ฝ๋๋ ์ธ๋๋ง๋ค '๋ฌด์์ ๋ ธ๋ฆฌ๋๊ฐ'๊ฐ ๋ฌ๋ผ์ก๋ค. 2010๋ Stuxnet์ ์์ฌ๋ถ๋ฆฌ๊ธฐ๋ฅผ ๋ง๊ฐ๋จ๋ฆฌ๊ธฐ ์ํด PLC ๋ก์ง์ ์กฐ์ํ๋ค. 2015~2016๋ ์ฐํฌ๋ผ์ด๋ ์ ๋ ฅ๋ง ๊ณต๊ฒฉ(BlackEnergy ยท Industroyer)์ ๊ฐํ๊ธฐ ๋ช ๋ น์ ์ง์ ๋งํ๋ ํ๋กํ ์ฝ ์ ์ฑ์ฝ๋์๋ค. ๊ทธ๋ฆฌ๊ณ 2017๋ , ์ธ ๋ฒ์งธ ์ธ๋์ธ TRITON์ ๋ชฉํ๋ฅผ ๋ฐ๊ฟจ๋ค. ํ๊ดด๊ฐ ์๋๋ผ, ํ๊ดด๋ฅผ ๋ง์์ฃผ๋ ์์ ์์คํ ์ ๊บผ๋ฒ๋ฆฌ๋ ๊ฒ์ด๋ค.
๋ฌด๋๋ ์์ ํํ ๊ณต์ฅ์ด์๋ค. ์ด ๊ณต์ฅ์๋ SIS(Safety Instrumented System, ์์ ๊ณ์ฅ์์คํ )๊ฐ ์์๋ค. SIS๋ ์๋ ฅยท์จ๋ยท๋ฐธ๋ธ ์ํ๊ฐ ์ํ ์๊ณ์น๋ฅผ ๋์ผ๋ฉด ์ฌ๋์ด ๊ฐ์ ํ์ง ์์๋ ์๋์ผ๋ก ๊ณต์ ์ ์ ์ง์์ผ ํญ๋ฐยทํ์ฌยท์ธ๋ช ํผํด๋ฅผ ๋ง๋ '๋ง์ง๋ง ์์ ์ฅ์น'๋ค. ์ฌ๊ธฐ์ ์ฐ์ธ ์ฅ๋น๊ฐ ์๋์ด๋ ์ผ๋ ํธ๋ฆญ์ Triconex(Tricon) ๊ณ์ด ์ปจํธ๋กค๋ฌ์๋ค. Tricon์ TMR(Triple Modular Redundant) ๊ตฌ์กฐ๋ก, ์ธ ๊ฐ์ ๋ ๋ฆฝ ์ฑ๋์ด ํฌํ(voting)๋ก ๊ฒฐ๊ณผ๋ฅผ ๊ฒฐ์ ํด ํ๋๊ฐ ๊ณ ์ฅ ๋๋ ์์ ๊ธฐ๋ฅ์ ์ ์งํ๋๋ก ์ค๊ณ๋ ์ฅ๋น๋ค.
2017๋ 6์, ๊ณต์ฅ์ด ์๊ธฐ์น ์๊ฒ ๋ฉ์ท๋ค. ๋น์์ ์์ ์์คํ ์ ๊ธฐ๊ณ์ ๊ฒฐํจ์ผ๋ก ์ฌ๊ฒจ์ก๋ค. 8์ ๋ ๋ฒ์งธ ์ ์ง๊ฐ ์ผ์ด๋์ ์กฐ์ฌ๊ฐ ์์๋๊ณ , ์์ง๋์ด๋ง ์ํฌ์คํ ์ด์ ์์ ์ ์ฒด๋ถ๋ช ์ ์ฝ๋๊ฐ ๋ฐ๊ฒฌ๋๋ค. 12์ FireEye์ Dragos๊ฐ ์ด๋ฅผ TRITON/TRISIS๋ก ๊ณต๊ฐํ๋ฉด์ ์ฌ๊ฑด์ ์ฑ๊ฒฉ์ด ๋๋ฌ๋ฌ๋ค. ๊ณต๊ฒฉ์๋ ๊ณต์ ์ ์กฐ์ํ๋ ค ํ ๊ฒ์ด ์๋๋ผ, SIS๊ฐ ์์ ์ ์ง๋ฅผ ๊ฑธ์ง ๋ชปํ๋๋ก ๋ง๋ค๋ ค ํ๋ค. ์ฆ '์์ '์ ๋๊ณ , ๊ณต์ ์ ์ํ ์ํ๋ก ๋ชฐ์๋ฃ์ผ๋ ค ํ ๊ฒ์ด๋ค.
์ด ์ฌ๊ฑด์ด ์ง๊ธ๋ ํ์๋๋ ์ด์ ๋ ๋จ์ํ๋ค. TRITON์ ์ธ๋ช ํผํด๋ฅผ ๋ชฉ์ ์ผ๋ก ์ค๊ณ๋ ๊ฒ์ผ๋ก ํ๊ฐ๋๋ ์ต์ด์ ๊ณต๊ฐ ์ ์ฑ์ฝ๋์ด๋ฉฐ, ๋์์ IT ๋ณด์์ ์ฌ๊ณ ๋ฐฉ์์ด OT(์ด์๊ธฐ์ ) ํ์ฅ์์ ๊ทธ๋๋ก ํตํ์ง ์๋๋ค๋ ์ฌ์ค์ ๊ฐ์ฅ ๋ผ์ํ๊ฒ ๋ณด์ฌ์ค ์ฌ๋ก๋ค. ์ฌ๊ณ ๋ ๋ฒค๋์ ํจ์น, ๊ตญ๊ฐ ์ฐจ์์ ์ ์ฌ, ๊ท์ ยทํ์ค ๊ฐ์ ์ผ๋ก ์ด์ด์ก๋ค.
2. ๊ฐ์ผยท์ ํ ๊ฒฝ๋ก โ ์๊ธฐ๋ณต์ ๊ฐ ์๋๋ผ '์ ๋ฐ ์นจํฌ'
TRITON์ ์์ด ์๋๋ค. Morris WormยทCode RedยทBlasterยทSQL Slammer์ฒ๋ผ ์ค์ค๋ก ํผ์ง์ง ์๋๋ค. ๋์ ํ ํ์ฅ์ ์ ๋ฐํ๊ฒ ์ฅ์ ํ๊ธฐ ์ํ ํ์ ํ(ํ๊นํ) ํ๋ ์์ํฌ๋ค. ๊ทธ๋์ ์ ํ ๊ฒฝ๋ก๋ '์ธํฐ๋ท ์ ์ฒด'๊ฐ ์๋๋ผ ํ ๊ณต์ฅ์ ๋คํธ์ํฌ ์์์ ์์ฑ๋๋ค.
- โ ์ด๊ธฐ ์นจํฌ(IT โ OT ํผ๋ฒ) โ ๊ณต์ฅ์ IT ๋คํธ์ํฌ(์ฌ๋ฌด๋ง)๋ฅผ ๋จผ์ ์ฅ์ ํ๊ณ , IT์ OT๋ฅผ ์๋ '๋ค๋ฆฌ'๋ฅผ ์ฐพ๋๋ค. ์์ ํ ์์ด๊ฐญ ํ๊ฒฝ์ด ์๋๋ผ, ์ ์ง๋ณด์ยท๋ชจ๋ํฐ๋ง์ ์ํด ์ฐ๊ฒฐ๋ ํต๋ก๊ฐ ๊ณง ์นจํฌ ๊ฒฝ๋ก๊ฐ ๋๋ค.
- โก ์์ง๋์ด๋ง ์ํฌ์คํ ์ด์ (EWS) ์ฅ์ โ ๋ชฉํ๋ SIS ์ปจํธ๋กค๋ฌ๊ฐ ์๋๋ผ, ๊ทธ ์ปจํธ๋กค๋ฌ์ ํฉ๋ฒ์ ์ผ๋ก ๋ช ๋ น์ ๋ด๋ฆด ์ ์๋ Windows PC๋ค. EWS์๋ ์ ํ ์์ง๋์ด๋ง ์ํํธ์จ์ด(TriStation 1131)๊ฐ ๊น๋ ค ์๊ณ , SIS์ ๋ํํ ์ ์๋ ์ ์ผํ ์ ๋ขฐ ๋ ธ๋๋ค. ์ ๋ขฐ๋ ๋ ธ๋๋ฅผ ์ ๋ นํ๋ฉด ํ๋กํ ์ฝ์ ์๋ก ๋ซ์ ํ์๊ฐ ์๋ค.
- โข '์ ์ ํธ๋ํฝ'์ผ๋ก ์์ฅ โ TRITON์ EWS์์ TriStation ํ๋กํ ์ฝ์ ์ง์ ๊ตฌํํด ์ปจํธ๋กค๋ฌ์ ๋ํํ๋ค. ๊ทธ ํธ๋ํฝ์ ๊ด๋ฆฌ์์ ์ ํ ์ํํธ์จ์ด๊ฐ ๋ณด๋ด๋ ๊ฒ๊ณผ ๊ตฌ๋ณํ๊ธฐ ์ด๋ ต๋ค. ๋คํธ์ํฌ IDS ์ ์ฅ์์ '์ค๋๋ ์์ง๋์ด๊ฐ ์ ์ํ๊ตฌ๋' ์ ๋๋ก ๋ณด์ธ๋ค.
- โฃ ๋ฌผ๋ฆฌ ํค์ค์์น๋ผ๋ ๋ง์ง๋ง ๊ด๋ฌธ โ Tricon ์ปจํธ๋กค๋ฌ๋ ๋ฌผ๋ฆฌ ํค์ค์์น(keyswitch)๊ฐ 'ํ๋ก๊ทธ๋จ(PROGRAM)' ์์น์ ์์ด์ผ ํ๋ก๊ทธ๋จ ๋ณ๊ฒฝ์ ๋ฐ์๋ค์ธ๋ค. ์ฆ ์๊ฒฉ๋ง์ผ๋ก๋ ๋ก์ง์ ๋ฐ๊ฟ ์ ์๋ค. ์กฐ์ฌ ๊ฒฐ๊ณผ ์ด ํ์ฅ์์๋ ์ฌ๋ฌ ๋ฌผ๋ฆฌ ํค๊ฐ ์ ๊ทผ ๊ฐ๋ฅํ ์ํ๋ก ๋ฐฉ์น๋ผ ์์๊ณ , ์ด '์ฌ์ํ ์ด์ ์ค์'๊ฐ ๊ณต๊ฒฉ์ ์ฑ๋ฆฝ์ํจ ๊ฒฐ์ ์ ์์ธ ์ค ํ๋๋ก ์ง๋ชฉ๋๋ค.
- โค ์ง์ ์ ๊ทผ๊ณผ ์๋ โ ๊ณต๊ฒฉ์๋ EWS์ ์์ฃผํ๋ฉฐ ์ปจํธ๋กค๋ฌ์ ํ๋ก๊ทธ๋จยทํ์จ์ด ์ ๋ณด๋ฅผ ์ฝ๊ณ , ์ฌ๋ฌ ์ฐจ๋ก ์ฃผ์ ์ ์๋ํ๋ค. ์ ํ ์์ง๋์ด๋ง ์ํํธ์จ์ด ์์์ ์กฐ์ฉํ ๋์ํ๋ ๊ตฌ์กฐ๋ผ, ํธ์คํธ ๊ธฐ๋ฐ ๋ฐฑ์ ยทEDR์ ์์ผ์์๋ ์ฝ๊ฒ ๋๋ฌ๋์ง ์์๋ค.
์ ๋ฆฌํ๋ฉด TRITON์ ๊ฐ์ผ ๊ฒฝ๋ก๋ '์์ด๊ฐญ์ ํ์ โ ์ ์ง๋ณด์์ฉ ๋ค๋ฆฌ โ ์ ๋ขฐ๋ EWS โ ์์ ์ปจํธ๋กค๋ฌ'๋ผ๋ 4๋จ ์ฌ์ฌ์ด๋ค. ํํ ๋์ฌ์จ์ด ์ฌ์ฌ๊ณผ ๊ฒ๋ชจ์ต์ ๋น์ทํ์ง๋ง, ๋ง์ง๋ง ํ์ดํ์ ๋์ฐฉ์ง๊ฐ ์ฌ๋์ ๋ชฉ์จ์ ์งํค๋ ์ฅ์น๋ผ๋ ์ ์ด ๊ทผ๋ณธ์ ์ผ๋ก ๋ค๋ฅด๋ค.
3. ๋์ ์๋ฆฌ ์์ธ ๋ถ์ โ ๋ ๊ฐ์ ์ธ๊ณ, ํ๋์ ํ๋ ์์ํฌ
TRITON์ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ ์ด์ ๋ '์ ์ฑ์ฝ๋๊ฐ ๋ ๊ฐ์ ์๋ก ๋ค๋ฅธ ์ธ๊ณ์์ ๋์์ ์ด์์ผ ํ๋ค'๋ ์ ์ด๋ค. ํ๋๋ x86 Windows ์ธ๊ณ(EWS), ๋ค๋ฅธ ํ๋๋ ์ ์ฉ ์ค์๊ฐ ์ปจํธ๋กค๋ฌ ์ธ๊ณ(Tricon)๋ค. ๊ทธ๋์ TRITON์ ํ๋์ ์คํ ํ์ผ์ด ์๋๋ผ ์ญํ ์ด ๋๋ ํ๋ ์์ํฌ๋ก ๊ตฌ์ฑ๋๋ค๋ ๋ถ์์ด ์ง๋ฐฐ์ ์ด๋ค.
[ ๊ณต์ฅ IT/OT ๋คํธ์ํฌ ]
โ (โ ์ด๊ธฐ ์นจํฌ ยท ITโOT ํผ๋ฒ)
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ์์ง๋์ด๋ง ์ํฌ์คํ
์ด์
(Windows + TriStation 1131) โ
โ โ
โ trilog.exe โ ๋ฐ์ฒ/๋ก๋ โ
โ library.zip โ ํ์ด์ฌ ํ๋ ์์ํฌ โ
โ โ tslib โ TriStation ํ๋กํ ์ฝ์ ๊ตฌํํ ๊ณ์ธต โ
โ TsLow.dll / TsHi.dll โ ์ ์์ค ํต์ DLL โ
โ inject.bin โ ์ปจํธ๋กค๋ฌ์ ๋ฐ์ด ๋ฃ์ ํ์ด๋ก๋ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ (โก TriStation ํ๋กํ ์ฝ, UDP 1502 ๊ณ์ด)
โ โ ์ ํ ์์ง๋์ด๋ง ํด๊ณผ ๊ตฌ๋ณ์ด ์ด๋ ค์
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Triconex SIS ์ปจํธ๋กค๋ฌ (TMR: 3์ค ์ฑ๋ + ํฌํ) โ
โ ยท ํ๋ก๊ทธ๋จ/ํ์จ์ด ์ ์ฐฐ โ
โ ยท ๋ฉ๋ชจ๋ฆฌ ์ฝ๊ธฐ / ์ฐ๊ธฐ โ
โ ยท ํค์ค์์น ์ํ ์กฐํยท์กฐ์ โ
โ ยท โ
์์ ํธ๋ฆฝ(trip) ๋ก์ง์ ๋ฌด๋ ฅํํ๋ ค ์๋ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ์คํจ โ ์ปจํธ๋กค๋ฌ๊ฐ ์์ ์ ์ง/์ฅ์ ์ํ๋ก ์ง์
โ ๊ณต์ ์ ์ง(2017-06 / 2017-08) โ ํผํด์ ์ธก ์กฐ์ฌ ์์
3-1. TriStation์ '์์ง๋์ด๋ง ์ธ์ด'๋ค. TriStation ํ๋กํ ์ฝ์ ์์ง๋์ด๊ฐ ๋ ธํธ๋ถ์์ SIS ์ปจํธ๋กค๋ฌ์ ์ ์ํด ํ๋ก๊ทธ๋จ์ ์ฌ๋ฆฌ๊ณ ๋ด๋ฆฌ๊ณ (๋ค์ด๋ก๋/์ ๋ก๋), ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฝ๊ณ ์ฐ๊ณ , ์ํ๋ฅผ ์กฐํํ๊ธฐ ์ํ ์ฌ๋ด ํ์ค ๋ํ๋ฒ์ด๋ค. ์ฆ ํ์์ ์ผ๋ก ๊ฐ๋ ฅํ ๊ถํ์ ๊ฐ์ง ํต๋ก๋ค. TRITON์ ์ด ๋ํ๋ฒ์ ํ์ด์ฌ์ผ๋ก ๋ค์ ๊ตฌํํด, ์ปจํธ๋กค๋ฌ์๊ฒ๋ '์ ํ ํด์ด ์ ์ํ ๊ฒ'์ฒ๋ผ ๋ณด์ด๊ฒ ๋ง๋ค์๋ค.
3-2. ์ '๋ฉ๋ชจ๋ฆฌ ์ฐ๊ธฐ + ํธ๋ฆฝ ๋ฌด๋ ฅํ'์ธ๊ฐ. SIS๊ฐ ์ํ์ ๊ฐ์งํ๋ฉด ์ปจํธ๋กค๋ฌ๋ ํธ๋ฆฝ(trip)์ ๊ฑธ์ด ๊ณต์ ์ ์์ ์ ์ง์ํจ๋ค. ๊ณต๊ฒฉ์๊ฐ ๋ ธ๋ฆฐ ๊ฒ์ ํธ๋ฆฝ์ด ๊ฑธ๋ฆฌ์ง ์๊ฒ ํ๋ ๊ฒ์ด๋ค. ์ด๋ฅผ ์ํด ์ปจํธ๋กค๋ฌ ๋ฉ๋ชจ๋ฆฌ(์์ ๋ก์ง์ด ์ฌ์ฉํ๋ ์ํยท๋ณ์ ์์ญ)์ ๊ฐ์ ์ฐ๊ฑฐ๋ ํ์ด๋ก๋๋ฅผ ์ฃผ์ ํด, ์ํ ์๊ณ์น๋ฅผ ๋์ด๋ ์ ์ง์ํค์ง ์๋ ์ํ๋ฅผ ๋ง๋ค๋ ค ํ๋ค. ์ด๊ฒ์ด ATT&CK for ICS์ Impair Process Control(T0836) ์ด๋ค. ๋ฐ์ดํฐ๋ฅผ ํ์น๋ ๊ฒ์ด ์๋๋ผ, ๋ฌผ๋ฆฌ ๊ณต์ ์ด '์ํํด๋ ๋ฉ์ถ์ง ์๊ฒ' ๋ง๋๋ ๊ฒ์ด๋ค.
3-3. ๋ฌผ๋ฆฌ ๊ณ์ธต๊ณผ์ ์ถฉ๋. ์๋ฌด๋ฆฌ ํ๋กํ ์ฝ์ ์๋ฒฝํ ํ๋ด ๋ด๋, ์ปจํธ๋กค๋ฌ์ ๋ฌผ๋ฆฌ ํค์ค์์น๊ฐ PROGRAM์ด ์๋๋ฉด ํ๋ก๊ทธ๋จ ๋ณ๊ฒฝ์ ๊ฑฐ๋ถ๋๋ค. ๊ทธ๋์ TRITON์๋ ํค์ค์์น ์ํ๋ฅผ ์กฐํยท์กฐ์ํ๊ณ , ํ์ํ๋ฉด ์์ ๊ธฐ๋ฅ์ ์ฐํํ๋ ค๋ ๋ก์ง์ด ํฌํจ๋ ๊ฒ์ผ๋ก ๋ถ์๋๋ค. ๊ฒฐ๊ตญ ์ด ์ฌ๊ณ ์ ์ฑ๋ฆฝ ์กฐ๊ฑด์ ์ํํธ์จ์ด ์ทจ์ฝ์ + ๋ฌผ๋ฆฌ ํต์ ์คํจ์ ๊ฒฐํฉ์ด์๋ค.
3-4. '์ค์'๊ฐ ๋๋ฌ๋ธ ๊ณต๊ฒฉ. ๊ณต๊ฒฉ์์ ์ฃผ์ ์๋๋ ์ต์ข ์ ์ผ๋ก ์ปจํธ๋กค๋ฌ๋ฅผ ์์ ์ ์ง/์ฅ์ ์ํ๋ก ๋ชฐ์๋ฃ์๋ค. ์๋๋ '๋ฉ์ถ์ง ์๊ฒ' ํ๋ ๊ฒ์ด์์ง๋ง, ๊ฒฐ๊ณผ๋ ๊ณต์ฅ์ด ๋ฉ์ถ๋ ๊ฒ์ด์๋ค. ์ด ์๊ธฐ์น ๋ชปํ ์ ์ง๊ฐ ์๋์๋ค๋ฉด ๊ณต๊ฒฉ์ ํจ์ฌ ์ค๋ ์จ์ด ์์์ ์ ์๋ค. ์ฆ ์ด ์ฌ๊ฑด์ ์ธ์์ ์๋ฆฐ ๊ฒ์ ๋ฐฉ์ด ๊ธฐ์ ์ด ์๋๋ผ ๊ณต๊ฒฉ์์ ์คํจ์๋ค๋ ์ ์ด ๋์ ํ ๊ตํ์ด๋ค.
3-5. ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ '๋ฌด๊ธฐ'๋ผ๋ ์ฑ๊ฒฉ. TRITON์ ํ ํ์ฅ์์๋ง ์ฐ์ด๋๋ก ๋ง๋ค์ด์ง ์ผํ์ฉ ๋๊ตฌ๊ฐ ์๋๋ผ, ๋ค๋ฅธ SIS/ICS๋ก ์ด์ ๊ฐ๋ฅํ ํ๋ ์์ํฌ๋ก ํ๊ฐ๋๋ค. ์ค์ ๋ก ์ดํ ์์ ์์คํ ์ ๋ ธ๋ฆฌ๋ ๊ณต๊ฒฉ ํดํท(๋ชจ๋ํ ICS ๊ณต๊ฒฉ ํ๋ ์์ํฌ)์ ๋ฑ์ฅ ์ ํฉ์ด ๋ณด๊ณ ๋๋ฉด์, 'SIS๋ฅผ ๊ฒจ๋ฅํ๋ ์ํ'์ ์ผํ์ฑ ์ฌ๊ฑด์ด ์๋๋ผ ํ๋์ ๊ณ๋ณด๊ฐ ๋๋ค.
4. ํผํด ๊ท๋ชจ/์ํฅ โ ์ซ์๋ณด๋ค ๋ฌด๊ฑฐ์ด ๊ฒ
- ์ง์ ํผํด: ํ์ธ๋ ํ์ฅ์ ์์ ํํ ๊ณต์ฅ 1๊ณณ, ๊ณต์ ์ ์ง 2ํ(2017๋ 6์, 8์). ์ธ๋ช ํผํดยท๋๊ท๋ชจ ํ๊ฒฝ ์ฌํด๋ ์์์ง๋ง, ์์ ์์คํ ์ด ๋ฌด๋ ฅํ๋ ์ ์์๋ ์ต์ด์ ์ค์ ์ฌ๋ก๋ค.
- ํ์ง ๊ฒฝ์: ์ฒซ ์ ์ง๋ ๊ธฐ๊ณ ๊ฒฐํจ์ผ๋ก ์ค์ธ๋๊ณ , ๋ ๋ฒ์งธ ์ ์ง ํ ์กฐ์ฌ์์์ผ EWS์ ์ฝ๋๊ฐ ๋ฐ๊ฒฌ๋๋ค. ํ์ง๊น์ง ์ฝ 6๊ฐ์์ด ๊ฑธ๋ ธ๋ค.
- ์ ๊ณยท๊ท์ ํ์ฅ: CISA์ ICS ์ ์ฑ์ฝ๋ ๋ถ์๋ณด๊ณ ์(MAR/AR18-352A, 'HatMan')์ ๊ฐ๊ตญ ICS-CERT ๊ถ๊ณ ๊ฐ ๋ฐ๊ฐ๋๊ณ , ๋ฒค๋(์๋์ด๋)๋ Triconex ์ ํ ๋ณด์ ๊ฐํ ์กฐ์น๋ฅผ ๋ด๋จ๋ค. 2021๋ ์๋ Triconex ์ปจํธ๋กค๋ฌ์ '๋น์ ์ ์กฐ๊ฑด ๊ฒ์ฌ ๋ฏธํก(CWE-754)' ์ทจ์ฝ์ ๋ฌถ์(CVE-2021-22742~22747)์ด ๊ณต๊ฐ๋๋ ๋ฑ ํ์จ์ดยท๊ฒ์ฌ ๋ก์ง ๊ฐํ๊ฐ ์ด์ด์ก๋ค.
- ์ ์ฌยท๊ท์: 2020๋ 10์ ๋ฏธ ์ฌ๋ฌด๋ถ OFAC๊ฐ ๋ฌ์์ CNIIHM์ ์ ์ฌํ๋ฉฐ TRITON ๊ฐ๋ฐยทํ์ฉ์ ๊ทผ๊ฑฐ๋ก ์ ์ํ๋ค. ๊ตญ๊ฐ ๋ฐฐํ ์ํ์ผ๋ก ๊ณต์ ๋ฌธ์์ ๋ชป ๋ฐํ ์ฌ๊ฑด์ด ๋๋ค.
- ์ ์ฑ ์ ์ํฅ: ์ด ์ฌ๊ฑด์ 'IT์ OT์ ์ฌ๊ณ ๋ฐฉ์์ด ๋ค๋ฅด๋ค'๋ ๋ช ์ ๋ฅผ ๊ท์ ์ธ์ด๋ก ๋์ด์ฌ๋ ธ๋ค. ๊ธฐ๋ฅ ์์ (์ ์ด๊ฐ ์์ ํ๊ฒ ์คํจํ๊ฒ ๋ง๋๋ ์ค๊ณ)๊ณผ ๋ณด์(์ธ๋ถ ๋ช ๋ น์ด ์ ๋ขฐ๋๋ค๋ ๊ฐ์ ์ ์์ ๋ ์ค๊ณ)์ ๊ฐ์ ์์คํ ์์ ํจ๊ป ๊ณ ๋ฏผํด์ผ ํ๋ค๋ ํ๋ฆ์ด ๋ณธ๊ฒฉํ๋๋ค.
์ ๋ฆฌํ๋ฉด TRITON์ '์ซ์'๋ ์๋ค. ๊ทธ๋ฌ๋ '์๋ฏธ'๋ ์ ์ฑ์ฝ๋ ์ญ์ฌ์์ ๊ฐ์ฅ ๋ฌด๊ฑฐ์ด ์ถ์ ๋ ๋ค. ํผํด ๊ท๋ชจ๊ฐ ์๋๋ผ ํ์ ์ ์ฑ์ง์ด ์ด ์ฌ๊ฑด์ ์ ๋ช ํ๊ฒ ๋ง๋ค์๋ค.
5. PoC (๊ต์ก์ฉ ๋ชจ์ ์ฝ๋ 4์ข )
์๋ ์ฝ๋๋ ๋ชจ๋ ๊ต์ก์ฉ ๋ชจ์(mock) ์ค์ต์ด๋ค. ์ค์ TriStation ํ๋กํ ์ฝ์ ๋ช
๋ น ์ฝ๋ยท์ ์ยทํจํท ํ์์ ์ฐ์ง ์์๊ณ , ์ปจํธ๋กค๋ฌ์ ํ๋ก๊ทธ๋จ์ ๋ด๋ ค๋ณด๋ด๋ ๊ธฐ๋ฅ๋, ์ค์ ์ทจ์ฝ์ ์ ๊ฒจ๋ฅํ๋ ์ต์คํ๋ก์๋ ์๋ค. ๋ชฉ์ ์ "์์ ํธ๋ฆฝ์ ๋๋ ๋ช
๋ น์ด ๊ตฌ์กฐ์ ์ผ๋ก ๋ฌด์์ ํ๋๊ฐ"๋ฅผ ๋์ผ๋ก ํ์ธํ๋ ๊ฒ๋ฟ์ด๋ค. ๋ชจ๋ ์ค์ต์ ์ธํฐ๋ท๊ณผ ๋ถ๋ฆฌ๋ ๊ฐ์ ๋ฉ(/tmp/lab)์์, ์ฌ๋ฌ๋ถ์ด ์ง์ ๋ง๋ ๋ชจ์ ์ปจํธ๋กค๋ฌ๋ฅผ ์๋๋ก๋ง ์ํํ๋ค. ์ค์ ์ค๋นยทํ์ธ์ ์์คํ
์ ๋์์ผ๋ก ํ ์คํ์ ๋ถ๋ฒ์ด๋ค.
PoC 1 โ '๊ฐ์ SIS ์ปจํธ๋กค๋ฌ' ๋ง๋ค๊ธฐ. ์์ ์ ์ง(trip)๊ฐ ๋ฌด์์ ํ๋จํ๋์ง๋ถํฐ ์ฌํํ๋ค.
# PoC 1: ๊ฐ์ SIS ์ปจํธ๋กค๋ฌ โ ์์ ํธ๋ฆฝ์ด '์' ๊ฑธ๋ฆฌ๋์ง ์ดํดํ๋ ๋ชจ์ ์ฝ๋
# ์ค์ Triconex/TriStation๊ณผ ๋ฌด๊ดํ ์์ ๊ต์ก์ฉ ์๋ฎฌ๋ ์ดํฐ. ๋ก์ปฌ ์ถ๋ ฅ๋ง ํ๋ค.
TRIP_LIMIT = 100.0 # ์ํ ์๊ณ์น (์์ง๊ฐ)
TRIP_ENABLED = True # ์์ ๋ก์ง ์ฌ์ฉ ์ฌ๋ถ (์ ์ ์ํ)
def sis_vote(readings):
"""TMR(3์ค ์ฑ๋) ํฌํ๋ฅผ ํ๋ด: ๋ค์๊ฒฐ๋ก ์ํ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ค."""
over = sum(1 for r in readings if r > TRIP_LIMIT)
return over >= 2 # 3์ฑ๋ ์ค 2์ฑ๋ ์ด์์ด ์๊ณ ์ด๊ณผ โ ์ํ
def safety_scan(readings):
global TRIP_ENABLED
risk = sis_vote(readings)
if not TRIP_ENABLED:
return "[!] ์์ ์ ์ง ๊ธฐ๋ฅ์ด ๋นํ์ฑ ์ํ โ ์ํ ์ ํธ๋ฅผ ๋ฌด์ํ๋ค (์ด๊ฒ์ด ๊ณต๊ฒฉ์ ๋ชฉํ)"
return "TRIP: ๊ณต์ ์์ ์ ์ง" if risk else "์ ์ ์ด์ "
if __name__ == "__main__":
print("[์ ์]", safety_scan([80.0, 82.0, 79.0]))
print("[์ํ]", safety_scan([130.0, 128.0, 131.0]))
PoC 2 โ ์์ง๋์ด๋ง ํ๋ ์์ ๊ตฌ์กฐ ์ดํด. ์ค์ ํ๋กํ ์ฝ ๋์ ๊ฐ์ ๋ช ๋ น ์ฝ๋๋ก ์์ฒญ/์๋ต์ ํํํด, EWS๊ฐ ์ปจํธ๋กค๋ฌ์๊ฒ ๋ณด๋ด๋ ๋ํ์ ๋ผ๋๋ฅผ ๋ณธ๋ค.
# PoC 2: ์์ง๋์ด๋ง ์์ฒญ ํ๋ ์์ '๊ตฌ์กฐ'๋ง ์ฌํ (๊ฐ์ opcode โ ์ค์ ๊ฐ๊ณผ ๋ค๋ฆ)
# ์ค์ ์ต์คํ๋ก์ ๋ฐ์ดํธ/์ค์ TriStation ๋ช
๋ น ์ ์๋ ํฌํจํ์ง ์๋๋ค.
FICTIONAL_OPCODES = {
0x01: "READ_STATUS", # ์ปจํธ๋กค๋ฌ ์ํ ์กฐํ
0x02: "READ_MEMORY", # ๋ฉ๋ชจ๋ฆฌ ์ฝ๊ธฐ
0x03: "WRITE_MEMORY", # ๋ฉ๋ชจ๋ฆฌ ์ฐ๊ธฐ โ ๊ณต๊ฒฉ์ด ์
์ฉํ๋ ์ง์
0x04: "GET_KEYSWITCH", # ๋ฌผ๋ฆฌ ํค์ค์์น ์ํ
}
def build_request(op, payload=b""):
"""๊ฐ์ EWSโSIS ์์ฒญ ํ๋ ์. op + ๊ธธ์ด + ํ์ด๋ก๋ ๊ตฌ์กฐ๋ง ๋ณด์ฌ์ค๋ค."""
if op not in FICTIONAL_OPCODES:
raise ValueError("unknown op")
frame = {"op": FICTIONAL_OPCODES[op], "len": len(payload), "data": payload}
print(f"[EWS โ SIS] {frame}")
return frame
def controller_side(frame, keyswitch_program=False):
"""๋ชจ์ ์ปจํธ๋กค๋ฌ: ์ฐ๊ธฐ ์์ฒญ์ ๋ฌผ๋ฆฌ ํค์ค์์น๊ฐ PROGRAM์ผ ๋๋ง ์์ฉํ๋ค."""
if frame["op"] == "WRITE_MEMORY" and not keyswitch_program:
print("[SIS] ์ฐ๊ธฐ ๊ฑฐ๋ถ: ํค์ค์์น๊ฐ PROGRAM ์์น๊ฐ ์๋ (๋ฌผ๋ฆฌ์ ์์ ์ฅ์น)")
return False
print("[SIS] ์์ฒญ ์์ฉ")
return True
if __name__ == "__main__":
f = build_request(0x03, b"<mock-payload>")
controller_side(f, keyswitch_program=False) # ๊ธฐ๋ณธ์ ๊ฑฐ๋ถ โ ์ ์
controller_side(f, keyswitch_program=True) # ํค์ค์์น ๋ฐฉ์น ์ ์์ฉ๋จ
PoC 3 โ 'ํธ๋ฆฝ ๋ฌด๋ ฅํ'๋ฅผ ๋ชจ์ ๋ฉ์์ ์ฌํ. PoC 1์ ๊ฐ์ ์ปจํธ๋กค๋ฌ์ PoC 2์ ์ฐ๊ธฐ ์์ฒญ์ ์ฐ๊ฒฐํด, ์์ ๋ก์ง์ด ๊บผ์ง๋ ๊ณผ์ ์ ๋์ผ๋ก ํ์ธํ๋ค. ์ค์ ์ปจํธ๋กค๋ฌ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์ยทํ์ด๋ก๋๋ ์ผ์ ์ฐ์ง ์๋๋ค.
# PoC 3: ๋ ๋ชจ์ ์ปดํฌ๋ํธ๋ฅผ ์ฐ๊ฒฐ โ '์์ ํธ๋ฆฝ ๋ฌด๋ ฅํ'๊ฐ ๋ฌด์์ ๋ฐ๊พธ๋์ง ํ์ธ
# ๋์์ ์ค์ง ๋ก์ปฌ์์ ์คํํ๋ ๋ชจ์ ์ปจํธ๋กค๋ฌ ๊ฐ์ฒด๋ค.
import importlib.util, sys
# (๊ต์ก์ฉ) PoC 1์ ๋ชจ๋์ sis.py ๋ก ์ ์ฅํด ๋์๋ค๊ณ ๊ฐ์
spec = importlib.util.spec_from_file_location("sis", "/tmp/lab/sis.py")
sis = importlib.util.module_from_spec(spec); spec.loader.exec_module(sis)
def inject_disable_trip(target_module, authorized_keyswitch):
"""'์์ ์ ์ง ๋นํ์ฑํ'๋ผ๋ ํจ๊ณผ๋ง ์ฌํํ๋ค(์ค์ ์ธ์ ์
์๋)."""
if not authorized_keyswitch:
print("[!] ํค์ค์์น๊ฐ PROGRAM ์๋ โ ์ฃผ์
์คํจ (๋ฐฉ์ด ์ฑ๊ณต ์๋๋ฆฌ์ค)")
return False
target_module.TRIP_ENABLED = False
print("[!] ๋ชจ์ ์ปจํธ๋กค๋ฌ์ ์์ ์ ์ง ๊ธฐ๋ฅ์ด ๊บผ์ก๋ค โ ์ดํ ์ํ ์ ํธ๋ฅผ ๋ฌด์ํ๋ค")
return True
if __name__ == "__main__":
print("[์ํ ์ํ ์ง์
]", sis.safety_scan([140.0, 139.0, 141.0]))
inject_disable_trip(sis, authorized_keyswitch=False) # 1) ๋ฐฉ์ด๋๋ ๊ฒฝ์ฐ
inject_disable_trip(sis, authorized_keyswitch=True) # 2) ํค์ค์์น ๋ฐฉ์น โ ์ฑ๊ณต
print("[๊ฐ์ ์ํ ์ํ]", sis.safety_scan([140.0, 139.0, 141.0])) # ์ ์ง๋์ง ์์
PoC 4 โ ๋ฐฉ์ด/ํ์ง ์ฐ์ต. ์ด์ ๊ณต๊ฒฉ์ ๊ด์ ์ด ์๋๋ผ ๋ฐฉ์ด์ ๊ด์ ์ผ๋ก ๋์ด๊ฐ๋ค. ์ ์ ์์ง๋์ด๋ง ์ธ์ ํ๋กํ์ผ์์ ๋ฒ์ด๋ ์ฐ๊ธฐ ์๋๋ฅผ ์ก์๋ด๋ ๋ชจ์ ํ์ง๊ธฐ์, ๋ฌผ๋ฆฌ ํค์ค์์น ํต์ ๋ฅผ ์ฝ๋๋ก ์ ๊ฒํ๋ค.
# PoC 4: ๋ชจ์ ํ์ง ๋ก์ง โ '๋น์ ์ ์์ง๋์ด๋ง ์ฐ๊ธฐ'๋ฅผ ์ก์๋ธ๋ค
NORMAL_WINDOW = ("09:00", "18:00") # ์ ์ ์์ง๋์ด๋ง ์์
์๊ฐ
ALLOWED_OPS = {"READ_STATUS", "READ_MEMORY", "GET_KEYSWITCH"}
def is_anomalous(session):
"""session = {time, host, src_ip, op, keyswitch_program, ticket_id}"""
if session["op"] == "WRITE_MEMORY" and not session["ticket_id"]:
return "์์
ํฐ์ผ ์๋ ๋ฉ๋ชจ๋ฆฌ ์ฐ๊ธฐ (๋ณ๊ฒฝ๊ด๋ฆฌ ์๋ฐ)"
if not (NORMAL_WINDOW[0] <= session["time"] <= NORMAL_WINDOW[1]):
return "์
๋ฌด์๊ฐ ์ธ ์์ง๋์ด๋ง ์ธ์
"
if session["keyswitch_program"] and session["op"] == "WRITE_MEMORY":
return "๊ฐ์ฅ(PROGRAM) ์ํ์์์ ์ฐ๊ธฐ โ ๋ฌผ๋ฆฌ ํต์ ๋ก๊ทธ์ ๋์กฐ ํ์"
return None
def check_keyswitch_policy(policy):
"""๋ฌผ๋ฆฌ ํค ๊ด๋ฆฌ ์ ์ฑ
์ ๊ฐ์ฅ ํํ ์คํจ๋ฅผ ์ฝ๋๋ก ์ ๊ฒํ๋ค."""
bad = [k for k, v in policy.items() if v == "left_in_program"]
return ("[FAIL] PROGRAM ์์น๋ก ๋ฐฉ์น๋ ํค: " + ", ".join(bad)) if bad \
else "[OK] ๋ชจ๋ ํค๊ฐ ํต์ ๋ ์์น์ ์๋ค"
if __name__ == "__main__":
s1 = {"time": "23:40", "host": "EWS-01", "src_ip": "10.10.4.7",
"op": "WRITE_MEMORY", "keyswitch_program": True, "ticket_id": None}
print("ํ์ง:", is_anomalous(s1))
print(check_keyswitch_policy({"SIS-1": "run", "SIS-2": "left_in_program"}))
print(check_keyswitch_policy({"SIS-1": "run", "SIS-2": "run"}))
๋ง์ง๋ง์ผ๋ก, ์ด๋ฐ ์ฝ๋๋ฅผ ์คํํ์ง ์๊ณ ๋คํธ์ํฌ์์ ์ด์ ์งํ๋ฅผ ๋ณด๋ ๊ท์น ์์ด๋์ด(๊ฐ๋ ์์)๋ฅผ ์ ๋ฆฌํด ๋๋ค. ์ค์ ๋ฐฐํฌ ์ ์๋ ๋ฐ๋์ ์๊ธฐ ํ์ฅ ํธ๋ํฝ์ผ๋ก ์คํ์ ์กฐ์ ํด์ผ ํ๋ค.
# ๊ฐ๋
์์(๋ชจ์): '์ ์ ํ๋กํ์ผ ๋ฐ' ์์ง๋์ด๋ง ํธ๋ํฝ ์๋ฆผ ๊ท์น ์ค์ผ์น
# ์ค์ ์๊ทธ๋์ฒ ์ ์/๋ฐ์ดํธ๋ ์๋์ ์ผ๋ก ๋ฃ์ง ์๋๋ค โ ์๊ธฐ ๋ง ํธ๋ํฝ์ผ๋ก ์กฐ์ ํ ๊ฒ.
rule:
name: sis_engineering_out_of_profile
if:
- proto: udp
- dst_port_in: [1502] # ์์ง๋์ด๋ง ํ๋กํ ์ฝ ํฌํธ(๊ฐ๋
)
- src_not_in: [ENG_WORKSTATIONS] # ์น์ธ๋ EWS ๋ชฉ๋ก ๋ฐ์์ ์จ ์์ฒญ
- op_in: [WRITE_MEMORY, PROGRAM_DOWNLOAD]
then:
- alert: "๋น์น์ธ ํธ์คํธ์ SIS ์ฐ๊ธฐ ์๋ โ ์ฆ์ ๋ฌผ๋ฆฌ์ ํ์ธ + ์ธ์
๊ฒฉ๋ฆฌ"
- log_fields: [ts, src_ip, op, keyswitch_state, ticket_id]
6. ๋ฐฉ์ด ๋ฐฉ๋ฒ/๊ตํ โ '๋ง์ง๋ง ์์ ์ฅ์น'๋ฅผ ์ด๋ป๊ฒ ์งํฌ ๊ฒ์ธ๊ฐ
- IT/OT ๋ถ๋ฆฌ์ '๋ค๋ฆฌ' ํต์ โ ์์ด๊ฐญ์ ์ ์ธ์ด ์๋๋ผ ์ด์์ด๋ค. ITโOT ์ฌ์ด์ ๋ชจ๋ ์ฐ๊ฒฐ(์๊ฒฉ ์ ์ง๋ณด์, ๋ชจ๋ํฐ๋ง, VPN, USB)์ ๋ชฉ๋กํํ๊ณ , ์ต์ ๊ถํยทMFAยท์ธ์ ๊ธฐ๋ก์ ์ ์ฉํ๋ค. 'ํธ์๋ฅผ ์ํ ์์ ๊ฐ๋ฐฉ'์ด ๊ฐ์ฅ ํฐ ๊ตฌ๋ฉ์ด๋ค.
- ์์ง๋์ด๋ง ์ํฌ์คํ ์ด์ ํ๋๋ โ EWS๋ ๊ณง SIS์ ๊ด๋ฆฌ์ ๊ถํ์ด๋ค. ์ ์ฉ ์ฅ๋น๋ก ๊ฒฉ๋ฆฌํ๊ณ , ๋ถํ์ํ ์ํํธ์จ์ดยท์ธํฐ๋ทยท์ด๋์ ๋งค์ฒด๋ฅผ ์ฐจ๋จํ๋ฉฐ, ์์ฉ ํ๋ก๊ทธ๋จ ํ์ฉ๋ชฉ๋ก(allowlisting)์ผ๋ก ์ ํ ์์ง๋์ด๋ง ํด ์ธ ์คํ์ ๋ง๋๋ค.
- ๋ฌผ๋ฆฌ ํค์ค์์น = ๋ณด์ ํต์ โ ํค๋ '๊ด๋ฆฌ ํญ๋ชฉ'์ด ์๋๋ผ '๋ณด์ ์ฅ์น'๋ค. ์ฌ์ฉ ํ ์ฆ์ ํต์ ์์น๋ก ๋ณต๊ท, ์ฌ์ฉ ๋ก๊ทธ ๊ธฐ๋ก, ๋ค์ค ์น์ธ ์ ์ฐจ๋ฅผ ๋๋ค. TRITON ์ฌ๊ณ ์ ์ฑ๋ฆฝ ์กฐ๊ฑด์ด ๋ฐ๋ก ์ด ์ง์ ์ด์๋ค.
- ํ๋กํ ์ฝ ํ์ดํธ๋ฆฌ์คํธ์ ํ์ ๋ชจ๋ํฐ๋ง โ ์์ง๋์ด๋ง ํ๋กํ ์ฝ ํธ๋ํฝ์ '์ ์ ๊ด๋ฆฌ ํธ๋ํฝ'์ด๋ผ ์๊ทธ๋์ฒ๋ก ์กํ์ง ์๋๋ค. ๋์ ๋๊ฐ, ์ธ์ , ์ด๋์, ์ด๋ค ๋ช ๋ น์ ๋ณด๋ด๋์ง ํ๋กํ์ผ๋งํ๊ณ , ์น์ธ๋ EWSยท์์ ํฐ์ผยท์ ๋ฌด์๊ฐ์ ๋ฒ์ด๋ ์ฐ๊ธฐ๋ฅผ ์๋ฆผ์ผ๋ก ์ก๋๋ค(๋ณ๊ฒฝ๊ด๋ฆฌ์ ๋ณด์ ๋ชจ๋ํฐ๋ง์ ์ตํฉ).
- SIS ๋ณ๊ฒฝ ๊ฐ์ฌ โ ์ปจํธ๋กค๋ฌ ํ๋ก๊ทธ๋จยทํ์จ์ดยทํค์ค์์น ์ํ์ ๊ธฐ์ค๊ฐ(baseline)์ ์ฃผ๊ธฐ์ ์ผ๋ก ์บก์ฒํ๊ณ , ์คํ๋ผ์ธ ๋์กฐ๋ก ๋ฌด๋จ ๋ณ๊ฒฝ์ ํ์งํ๋ค. ์์ ๋ก์ง์ ๋ฌด๊ฒฐ์ฑ์ ๊ณง ์ธ๋ช ์์ ์ด๋ค.
- ๊ธฐ๋ฅ ์์ ๊ณผ ๋ณด์์ ํตํฉ ์ค๊ณ โ '์ ์ด๊ฐ ์์ ํ๊ฒ ์คํจํ๋ค(fail-safe)'๋ ์์น๊ณผ '์ด๋ค ๋ช ๋ น๋ ์ ๋ขฐํ์ง ์๋๋ค(zero trust)'๋ ์์น์ ๊ฐ์ ์ํคํ ์ฒ์์ ์ค๊ณํ๋ค. ํ์ค(IEC 62443 ๋ฑ)๊ณผ ๋ฒค๋ ๊ถ๊ณ ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ๋ฐ์ํ๋ค.
- ๊ฐ์ ์ ๊ฒํ(์ฒดํฌ๋ฆฌ์คํธ) โ โ SIS์ ๋๋ฌํ๋ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ์๋๊ฐ โก EWS์์ ์ ํ ํด ์ธ ์คํ์ ๋ง์๋๊ฐ โข ๋ฌผ๋ฆฌ ํค๋ ํต์ ๋๋๊ฐ โฃ ์์ง๋์ด๋ง ํธ๋ํฝ์ ํ๋กํ์ผ๋งํ๋๊ฐ โค ์์ ๋ก์ง ๋ณ๊ฒฝ์ ๊ฐ์ฌํ๋๊ฐ. ๋ค์ฏ ์ง๋ฌธ์ ๋ชจ๋ '์'๋ผ๊ณ ๋ตํ์ง ๋ชปํ๋ฉด, ๊ทธ๊ฒ์ด ์ค๋์ ์ฐ์ ์์๋ค.
๊ตํ ํ ์ค. ์์ ์์คํ ์ ๋์งํธ๋ก ์ฐ๊ฒฐํ๋ ์๊ฐ, ๊ทธ ์์ ์์คํ ๋ ๊ณต๊ฒฉ๋ฉด์ด ๋๋ค. ๋ง์ง๋ง ๋ฐฉ์ด์ ์ ์งํค๋ ์ผ์ ๋ฐฉํ๋ฒฝ ํ ๋๊ฐ ์๋๋ผ, ๋ฌผ๋ฆฌ ํต์ ยท ๋ณ๊ฒฝ๊ด๋ฆฌ ยท ํธ๋ํฝ ํ๋กํ์ผ๋ง ยท ํ์ค ์ค์๊ฐ ๊ฒน์ณ์ง ๋ค์ธต ๊ตฌ์กฐ๋ก๋ง ๊ฐ๋ฅํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ์ฌ๊ฑด์ ์ธ์์ ์๋ฆฐ ๊ฒ์ ์๋ฒฝํ ๋ฐฉ์ด๊ฐ ์๋๋ผ ๊ณต๊ฒฉ์ '์ค์'์๋ค๋ ์ฌ์ค์, ์ฐ๋ฆฌ๋ ๋ถํธํ๊ฒ ๊ธฐ์ตํด์ผ ํ๋ค.
์ถ์ฒ
- CISA โ MAR-17-352-01 HatMan โ Safety Instrumented System Attack (TRITON ๊ณต์ ์ ์ฑ์ฝ๋ ๋ถ์๋ณด๊ณ ์) โ cisa.gov/news-events/analysis-reports/ar18-352a
- Mandiant (FireEye) โ Attackers Deploy New ICS Attack Framework "TRITON" (์ต์ด ๊ณต๊ฐ ๋ถ์) โ mandiant.com/resources/blog/attackers-deploy-new-ics-attack-framework-triton
- MITRE ATT&CK โ Triton (Software S1009) ยท Impair Process Control (T0836) โ attack.mitre.org/software/S1009 ยท attack.mitre.org/techniques/T0836
- Dragos โ Xenotime (์ํ ๊ทธ๋ฃน ํ๋กํ ยท TRISIS ๋ช ๋ช ) โ dragos.com/threat/xenotime
- U.S. Department of the Treasury (OFAC) โ ์ ์ฌ ์ง์ (2020-10-23, CNIIHM) โ treasury.gov โ OFAC Enforcement 2020-10-23
- NVD โ CVE-2021-22742 ๋ฑ Triconex ์ปจํธ๋กค๋ฌ '๋น์ ์ ์กฐ๊ฑด ๊ฒ์ฌ ๋ฏธํก(CWE-754)' ์ทจ์ฝ์ (์ฌํ ๊ฐํ ์ฌ๋ก) โ nvd.nist.gov/vuln/detail/CVE-2021-22742
- Wikipedia โ Triton (malware) (ํ์๋ผ์ธยท๊ท์ยท์ํฅ ์ ๋ฆฌ) โ en.wikipedia.org/wiki/Triton_(malware)
- Wikipedia โ Triconex (TMR ๊ตฌ์กฐยทSIS ๊ฐ๋ ) โ en.wikipedia.org/wiki/Triconex
โป ๋ณธ๋ฌธ์ PoC ์ฝ๋๋ ๊ตฌ์กฐ ์ดํด ๋ชฉ์ ์ ๊ต์ก์ฉ ๋ชจ์ ์ฝ๋์ด๋ฉฐ, ์ค์ TriStation ๋ช ๋ น ์ ์ยท์ปจํธ๋กค๋ฌ ํ์ด๋ก๋ยท์ต์คํ๋ก์์ ํฌํจํ์ง ์์ต๋๋ค. ๋ชจ๋ ์ค์ต์ ์ธํฐ๋ท๊ณผ ๋ถ๋ฆฌ๋ ๊ฒฉ๋ฆฌ ๋ฉ(๊ฐ์ ๋๋ ํฐ๋ฆฌ /tmp/lab)์์ '์ง์ ๋ง๋ ๋ชจ์ ์ปจํธ๋กค๋ฌ'๋ฅผ ๋์์ผ๋ก๋ง ์ํํด์ผ ํ๋ฉฐ, ์ค์ ์ค๋น๋ ํ์ธ์ ์ฐ์ ์์คํ ์ ๋์์ผ๋ก ํ ์คํ์ ๋ถ๋ฒ์ ๋๋ค.
ํจ๊ป ์ฝ๊ธฐ: โ๏ธ Stuxnet (2010) โ ์์ฌ๋ถ๋ฆฌ๊ธฐ๋ฅผ ํ๊ดดํ ์ธ๊ณ ์ต์ด์ ์ฌ์ด๋ฒ ๋ฌด๊ธฐ ยท โก Industroyer / CrashOverride โ ์ ๋ ฅ๋ง ํ๋กํ ์ฝ์ ๊ทธ๋๋ก ๋งํ ์ ์ฑ์ฝ๋ ยท ๐ฅ Flame (2012) โ MD5 ์ถฉ๋๋ก MS ์ธ์ฆ์๋ฅผ ์์กฐํ ์คํ์ด ํ๋ซํผ ยท ๐ฆ SolarWinds SUNBURST (2020) โ ๋น๋ ํ์ดํ๋ผ์ธ์ ๊ฐ์ผ์์ผ ์ ๋ขฐ๋ฅผ ๋ฌด๊ธฐ๋ก ์ผ์ ์ฌ๊ฑด ยท โ ๏ธ NotPetya (2017) โ ๊ฐ์ ํด '๊ณต๊ธ๋ง์์ ์์ํด ์ธ๊ณ๋ฅผ ๋ฉ์ถ' ํ๊ดดํ ์์ดํผ