출시 전부터 쭉 엄청난 인기를 끌고 있는 유명 게임 '배틀그라운드'의 핵으로 위장, 국내 게이머를 타겟팅한 악성코드를 분석했습니다.
[분석 보고서 - PDF]
PDF 보고서가 보이지 않는다면 아래의 '분석 보고서 열기' 버튼을 클릭하여 열람하시기 바랍니다.
0. 샘플 확보
[그림 1. 악성코드를 유포 중인 블로그]
게임 핵으로 위장한 악성코드를 분석해보자는 생각이 들어서 초록 검색창에 ‘배틀그라운드 핵 다운’ 이라고 검색하여 딱 봐도 수상해 보이는 블로그 포스트에서 수상해 보이는 압축 파일을 다운받았습니다. 비밀번호까지 걸려있는 걸로 봐선 악성코드임이 거의 확실해 보여서 분석에 들어갔습니다.
[그림 2. 압축파일 내부]
내부에는 EXE로 보이는 파일 하나 뿐이고, 압축파일의 비밀번호는 블로그에 적힌 대로 ‘PUBGH‘ 였습니다. 하나밖에 없으니 대상을 고를 것도 없이 바로 분석에 들어갑니다.
1. 정적 분석
1-1. PUBG H.exe 정적 분석
파일명 |
PUBG H.exe |
파일 크기 |
983,040 Bytes (960 KB) |
파일 타입 |
PE32 executable for MS Windows (GUI) Intel 80386 32-bit |
||
MD5 |
4798e8d2c49da4910e98396a797d1e49 |
||
SHA1 |
22374fb785f248170af795fd3a0b2ebf20633a74 |
||
SHA256 |
c9d804dc50a0c61671586c344bcc7cb79add5faafb5b29cdde857f5c299e77e4 |
||
SSDeep |
24576:RNLszWsxyDHIWJnpZ3JtCht3+bgkX6fDBAZU4G4y3:HGWPtZ3JC3+bBXe3 |
우선 분석할 대상 파일 자체는 아이콘조차 없는 평범한 Win32 PE 파일입니다.
[그림 3. PUBG H.exe Exeinfo PE]
Exeinfo PE라는 툴을 이용하여 분석 대상을 조사해본 결과 Safeengine Shielden 2.3.9.0 버전으로 패킹되어 있는 것을 확인할 수 있었습니다. 실제 IDA로 열어 보면 라이브러리나 함수 섹션보다 파싱하지 못한 데이터 영역이 매우 크고, EntryPoint 지점의 함수가 xor 연산으로 끝나는 것을 확인할 수 있습니다. 내부에서 언패킹 후 실제 PE파일을 실행시키는 부분이 있는 것으로 예측이 가능합니다. 패킹된 상태로 정적 분석은 불가능에 가까우므로 PE Tools를 이용하여 언패킹된 바이너리를 덤프합니다.
[그림 4. PUBG H.exe PE Tools Dump]
PE Tools를 실행한 후 대상 파일을 실행시키고, 생성된 프로세스를 그대로 풀 덤핑합니다. 악성코드가 실제로 실행되는 것이므로 VM 내에서 진행하며 미리 스냅샷을 찍어 덤프 전 상태로 돌아갈 수 있도록 합니다. 여기서 덤프된 파일을 Dumped_PUBG_H.exe 라고 부르겠습니다.
1-2. Dumped_PUBG_H.exe 정적 분석
파일명 |
Dumped_PUBG_H.exe |
파일 크기 |
1,040,384 Bytes (1,016 KB) |
파일 타입 |
PE32 executable for MS Windows (GUI) Intel 80386 32-bit Mono/.Net assembly |
||
MD5 |
c59c63b2615ba11670cfd68cbc55d4f1 |
||
SHA1 |
6acd1cbe2a4fe1ec9d6d48901a84b91892d18548 |
||
SHA256 |
b773e38d9579f7cb6f8efa8d33ea3a44695707824c8ec7e17ce953e651d8deac |
||
SSDeep |
24576:IApf+jWSxyGwDIJnpZ3JtCht3+bgkX6fDBAZU4G4fM:IAAjWVgZ3JC3+bBXDM |
언패킹 전인 PUBG H.exe 파일보다 크기가 좀 더 커졌고, 파일 타입이 .NET 으로 바뀐 것을 볼 수 있습니다. .NET 실행 파일의 경우 Reflector나 Jetbrain사의 dotpeek을 이용하여 쉽게 디컴파일이 가능하므로 dotpeek으로 시도해 보았습니다.
[그림 5. Dumped_PUBG_H.exe dotpeek 디컴파일]
무려 프로젝트명부터 ‘NanoCore Client’로 네이밍되어 있는 것을 확인할 수 있습니다. NanoCore는 해외에서 개발된 오픈소스 악성 프로그램으로, NanoCore의 개발자는 이것을 합법적이라고 주장했지만 결국 2017년 7월에 유죄를 선고받았습니다. (기사: https://www.thedailybeast.com/nanocore-coder-pleads-guilty-to-aiding-and-abetting-hackers) NanoCore는 RAT(Remote Access Trojan)으로, 감염된 PC를 외부에서 원격조작하여 중요 정보를 탈취하거나, 추가로 악성 프로그램, 스크립트를 내려 받아 실행하게 하거나, DDoS 공격을 수행하도록 할 수도 있습니다.
소스코드 내부에 드래그하여 표시해둔 부분을
보면 변수명이 무려 ‘#=qzDzg9a$HVGG1G5cdhqbdwO3OG_SFijGXN8Towa37$TQ=’ (으악) 인 것을 볼 수 있습니다. 이 변수 뿐만 아니라 거의 모든 변수와
함수, 클래스명이 위와 같은 형태로 난독화되어 있기 때문에 코드 분석이 무척이나 까다롭습니다. 정적으로 계속 분석하기 위해서는 난독화를 해제할 필요성이 있고, 이를
해결하기 위해 de4dot이라고
하는 프로그램을 사용했습니다. (Github: https://github.com/0xd4d/de4dot)
[그림 6. Deobfuscate Dumped_PUBG_H.exe]
de4dot의 난독화 해제 기능을 이용해 본 결과 Eazfuscator.Net 3.3 버전을 사용하여 난독화된 것을 확인할 수 있었습니다. 난독화 해제된 파일을 Deobfuscated_PUBG_H.exe 라고 부르겠습니다.
[그림 7. Obfuscated vs Deobfuscated]
왼쪽이 난독화가 적용된 상태의 샘플, 오른쪽은 난독화가 해제된 상태의 샘플입니다. 확실히 읽고 분석하기 편해진 것을 볼 수 있습니다. 이제 난독화 해제된 파일을 분석할 차례입니다.
1-3. Deobfuscated_PUBG_H.exe 정적 분석
파일명 |
Deobfuscated_PUBG_H.exe |
파일 크기 |
1,112,576 Bytes (1,087 KB) |
파일 타입 |
PE32 executable for MS Windows (GUI) Intel 80386 32-bit Mono/.Net assembly |
||
MD5 |
349f8045814c4f41316204d54d412b19 |
||
SHA1 |
946d41c8cb9fd865a2c6b4007f84700a4c038289 |
||
SHA256 |
e4f4fe44814e7b35ef96f54c3ff6a50470d1343686e3efb1e77c2c56108e23b4 |
||
SSDeep |
24576:AApf+jWSxyGwDIJnpZ3JtCht3+bgkX6fDBAZU4G4fm/Ye:AAAjWVgZ3JC3+bBXDQ |
.NET 디컴파일 툴은 reflector와 dotpeek 두 개가 대표적이고, 둘 모두 VS Project로 디컴파일한 소스를 export할 수 있는 기능을 갖추고 있습니다. dotpeek을 이용하여 VS Project로 내보내어 Visual Studio를 이용해 IDA의 Hex-rays 기능을 이용하듯이 하나하나 이름을 변경해가며 분석하면 그냥 소스만 보고 분석하는 것보다 훨씬 이해하기 쉽게 분석이 가능합니다.
[그림 8. Main Function]
Main 함수를 찾아보면 바로 아래 ClientLoaderForm_Shown 함수 내에서 Class8의 정적 멤버 함수인 RunMalware를 실행하는 모습이 보입니다. 원래는 Class8.smethod_8() 이지만 보기 쉽도록 직접 코드를 분석하면서 함수 네이밍을 어느 정도 다시 해 뒀습니다. 그 위에서는 실행된 것이 보이지 않도록 Visible을 False로 설정하는 부분도 있으며, Form이 닫힐 경우 자동적으로 악성 행위에 사용한 각종 설정 값들을 저장하는 부분도 존재합니다.
[그림 9. RunMalware Function]
앞서 언급했다시피 함수 네이밍을 어느 정도 해둔 상태이기 때문에 이제 함수 명만 보고도 어느정도는 행위를 파악하는게 가능합니다. 코드를 피킹해 둔 부분을 보면 Exception이 발생했을 때 이를 전부 로깅하는 코드가 존재함을 알 수 있습니다. 코드를 분석하면서 알게 된 점은 이 프로그램은 악성코드이지만 익셉션 핸들링이나 로깅 등이 매우 충실히 잘 이루어지고 있는 상당히 수준 높은 구조를 가지고 있다는 것입니다.
[그림 10. Decrypt Resource]
코드 길이가 상당히 방대하고 이를 하나하나 다 짚으면서 보고서를 쓰면 끝이 없기 때문에 가장 중요한 부분만 작성하기로 했습니다. 이 파일은 리소스 영역에 딱 하나의 리소스를 가지고 있는데, 이 리소스는 암호화되어 있기 때문에 복호화를 해야 읽을 수 있고 사용 가능한 데이터가 나타납니다.
[그림 11. Save Resource to Dict]
복호화 루틴을 지나면서 복호화가 완료된 데이터는 함수 내에서 클래스 멤버 변수인 dictionary_1에 뽑아낸 키와 값으로 각각 저장됩니다. 내부에 저장된 데이터는 Key와 Value값을 가진 Json Object 형태의 데이터일 것이라고 예상이 가능합니다.
[그림 12. GetValueWithKey Function]
dictionary_1에서 Key를 이용해 Value를 받아오는 함수가 존재하여 GetValueWithKey라고 이름 붙이고 사용되는 부분을 모두 찾아보았더니 Key값들의 이름이 Timeout이나 Delay, Server 주소 등 Configuration과 관련된 내용들인 것을 확인할 수 있었습니다. 이 리소스를 복호화하는 것이 가능하다면 이 악성코드가 어떻게 동작할지 예측하는 것이 가능할 것입니다.
[그림 13. 리소스 첫 부분 복호화]
복호화 루틴을 살펴보면 리소스 영역을 한번에 전부 복호화하는 것이 아니라 첫 4바이트를 읽고, 그 값만큼을 다시 읽어와서 특정 키를 이용하여 먼저 복호화한 후 그 값을 나머지 리소스 영역 복호화를 위한 Initialization Vector와 Key값으로 사용하는 것을 알 수 있습니다. DES 암호화를 사용하며, IV를 사용하는 것에서도 알 수 있듯이 64비트 크기의 블록 암호입니다.
[그림 14. 리소스 첫 부분 복호화 키 루틴]
리소스 복호화 루틴의 경우 모두 코드 형태로 존재하였기에 새로 C# 프로젝트를 생성하고 코드를 그대로 가져다가 완성하였지만, C#에 대한 이해가 부족하여 그림 13, 및 그림 14에서 Class8.DecryptBuffer 함수의 두 번째 인자로 들어가는 Guid 값의 경우 똑같이 작성해도 복호화 도중 익셉션이 발생하는 문제가 있었습니다.
[그림 15. CustomAttribute Guid]
GetCustomAttributes의 어감에서도 추측할 수 있듯이 코드 내부 어딘가에 Guid값이 Set 되어 있을 것이라고 보고 파일들을 뒤져가며 찾아보니 지정된 Guid 문자열을 발견할 수 있었습니다.
[그림 16. Set Decrypt Key]
발견한 값으로 Guid를 만들어서 같은 복호화 루틴에 Key로 설정해 둔 코드입니다. 이후 복호화 루틴을 돌려서 나온 결과를 Dictionary 자료형에 담게 되는데, 이 변수를 Json으로 덤프하면 다음과 같은 결과를 볼 수 있습니다. (복호화에 사용한 .NET 소스코드는 블로그 포스트에 첨부하였습니다)
{
"BuildTime": "2018-02-08T03:06:08.3425287Z",
"Version": {
"Major": 1,
"Minor": 2,
"Build": 2,
"Revision": 0,
"MajorRevision": 0,
"MinorRevision": 0
},
"Mutex": "19d9428a-7d48-4c41-b850-2e92448ad594",
"DefaultGroup": "Default",
"PrimaryConnectionHost": "TestZb.Ze.Am",
"BackupConnectionHost": "TestZb.Ze.Am",
"ConnectionPort": 54984,
"RunOnStartup": true,
"RequestElevation": false,
"BypassUserAccountControl": false,
"ClearZoneIdentifier": true,
"ClearAccessControl": false,
"SetCriticalProcess": false,
"PreventSystemSleep": true,
"ActivateAwayMode": false,
"EnableDebugMode": false,
"RunDelay": 0,
"ConnectDelay": 4000,
"RestartDelay": 5000,
"TimeoutInterval": 5000,
"KeepAliveTimeout": 30000,
"MutexTimeout": 5000,
"LanTimeout": 2500,
"WanTimeout": 8000,
"BufferSize": 65535,
"MaxPacketSize": 10485760,
"GCThreshold": 10485760,
"UseCustomDnsServer": true,
"PrimaryDnsServer": "8.8.8.8",
"BackupDnsServer": "8.8.4.4"
}
중요하다고 생각되는 데이터에는 볼드 + 붉은 색 처리를 하였습니다. 접속을 시도하는 서버 도메인과 그 포트, 자동 실행 프로그램으로 등록 여부, UAC 우회 여부 등 여러 옵션을 선택할 수 있는 것을 알 수 있습니다. 아무래도 TestZb.Ze.Am:54984로 접속 시도를 할 것으로 보입니다.
[그림 17. 도메인 VirusTotal 조회 결과]
접속하는 서버의 메인 도메인에 대한 정보를 알아보기 위해 VirusTotal에 조회 및 직접 접속해 보니 2018년 2월 7일까지 URL Shortener 서비스를 운영한 한국인의 도메인인 것으로 추정되었습니다. 서브 도메인을 확인해 보니 다음과 같았습니다.
spr17.ze.am |
youcy111.ze.am |
www.hasangwook.ze.am |
spr1.ze.am |
www.xn----qz5e7tr56dq9g2qdzxr3ue56g.ze.am |
www.xn----rz5e7t44s3tj2ik5nc1ummty2pj.ze.am |
spr18.ze.am |
unlocker.ze.am |
video.ze.am |
shyyset.ze.am |
xn--o39az1zdmbpa021j2ufp8f.ze.am |
excel.ze.am |
ekfak15.ze.am |
spr39.ze.am |
deim.ze.am |
sgddos.ze.am |
www.xn----c28e37pwzi89ex7av7h7zzdtdxyc.ze.am |
www.play21.ze.am |
coca-cola.ze.am |
cuzz.ze.am |
fileup.ze.am |
lillllili.ze.am |
compcomp.ze.am |
njj.ze.am |
minoo.ze.am |
mj.ze.am |
zombie24.ze.am |
hdream.ze.am |
deabakgam.ze.am |
daumpotlncoder.ze.am |
agwgsdgd.ze.am |
spectre.ze.am |
lmj.ze.am |
val.ze.am |
naverddos.ze.am |
ktv.ze.am |
www.agwgsdgd.ze.am |
hwalang0929.ze.am |
kisa5323.ze.am |
spynote.ze.am |
ddosattack.ze.am |
teeluk.ze.am |
sel.ze.am |
ysc3514.ze.am |
xink.ze.am |
bggonline.ze.am |
djtmdgh5517.ze.am |
adminwww.ze.am |
web.dkfate.ze.am |
batmanblog.ze.am |
nutri999.ze.am |
enal153.ze.am |
ssul5.ze.am |
4shared.ze.am |
www.dbns.ze.am |
spr99.ze.am |
spr.25.ze.am |
qer.ze.am |
gooddoctor.ze.am |
mingkey.ze.am |
nutrino20.ze.am |
xn--299ayym43bd2d8zctu1ay7f.ze.am |
dbns.ze.am |
dinte.ze.am |
spr68.ze.am |
zb.ze.am |
dkssudak11.ze.am |
www.iam.ze.am |
swoo.ze.am |
pora.ze.am |
soulms.ze.am |
netbot.ze.am |
godofwarv502.ze.am |
xn--lg3bujr1jg5w.ze.am |
|
djchoice.ze.am |
bfz.ze.am |
|
nutrino19.ze.am |
spr40.ze.am |
|
ipzero123.ze.am |
dltjwns.ze.am |
|
VirusTotal에 등록된 서브 도메인만 총 99개이며, 개중에는 ddos, naverddos, netbot, zombie24 등 노골적으로 악성임을 드러내는 이름이 다수 존재했습니다. 도메인 서비스의 계정을 탈취당해 해커에 의해 서브 도메인이 다수 만들어지고, 해커의 서버 혹은 탈취된 다른 서버로 연결된 것으로 보입니다.
[그림 18. 서버에서 받은 데이터 처리]
서버에 연결하여 받아온 데이터는 그림 18의 함수에 인자로 넘어가며, 리소스를 복호화 할 때 사용한 함수와 같은 함수를 사용하여 데이터를 복호화하고 파싱합니다.
[그림 19. 파싱된 데이터 값 처리]
파싱된 데이터는 여러 개의 switch 문을 거치면서 값에 따라 다른 명령을 처리하는데, 대표적인 타입이 그림 19에 나타난 FileCommand 입니다. 네 번째 인자는 타입 내의 구체적인 명령 Offset, 다섯 번째 인자는 해당 명령에 대한 인자로 보입니다.
[그림 20. Command Type]
그림 20에 나타나 있듯이 이 악성코드에는 현재 BaseCommand, FileCommand, PluginCommand의 세 가지 타입이 존재하며 서버에서 받아온 값에 따라 저 중에서 명령을 선택적으로 수행합니다. PluginCommand라는 타입에서 유추할 수 있듯이 이 악성코드는 플러그인을 이용해 선택적으로 특정 명령을 추가 및 제거할 수 있습니다. 서버에 연결하여 명령어를 받아와 실행하는 것을 보면 RAT(Remote Access Trojan)이며 상당히 고도화되어 있음을 알 수 있습니다.
2. 동적 분석
일반적으로 패킹이나 난독화는 동적 분석의 결과에 영향을 미치지 않으므로 처음 다운받은 샘플 그대로 VM 내의 Cuckoo 자동분석시스템에 넣고 돌려봤습니다.
[그림 21. 실행 후 스크린샷]
정적분석에서 예상했던 대로 Visible 값이 False가 되어있기 때문에 스크린샷에는 아무런 창도 나타나지 않았습니다.
[그림 22. 네트워크 분석]
눈에 띄는 DNS 주소는 리소스 복호화를 통해 알아낸 TestZb.Ze.Am 입니다. DNS 조회를 통해 1.241.72.196이라는 IP 주소를 알아냈습니다. 하지만 TCP 연결 목록에는 눈에 띄지 않았고, Cuckoo 특성상 접속 실패의 경우 TCP 탭에 표시하지 않으므로 접속 시도는 했으나 성공하지 못한 것으로 예상할 수 있습니다.
[그림 23. 네트워크 pcap 분석]
pcap 파일을 직접 다운로드 받아서 분석해 본 결과 해당 IP와 리소스 내에서 찾아낸 54984 포트로 접속을 시도하기 위해 SYN 패킷을 계속 발신하지만 응답은 RST/SYN으로 해당 포트는 닫혀 있는 것을 확인할 수 있습니다. 현재는 악성코드 서버가 동작하지 않고 있다는 의미입니다.
[그림 24. GeoIP 결과]
GeoIP를 이용하여 IP 주소를 가진 서버의 위치를 확인해 보니 국내에 위치한 서버였습니다. Whois 조회에서는 SK Broadband에 할당되었다고 합니다.
[그림 25. 드랍한 버퍼]
버퍼 내에서 드랍한 세 파일 중 두 파일은 VirusTotal에서 결과가 존재했으며 둘 모두 NanoCore Client에서 사용되는 .NET 기반 DLL 파일인 것으로 확인되었습니다.
3. 결론 & 자동 탐지 방안
‘PUBG H.exe’ 파일은 대한민국 최대 포털 사이트의 블로그를 통해 유포되고 있었으며, 공격에 사용된 해커의 서버 또한 접속되지는 않았지만 국내에 위치한 서버였습니다. 유포할 때 포스트 제목을 유명 게임인 배틀그라운드 핵을 공유하는 것처럼 위장한 것으로 보아 국내 게이머들을 타겟팅 한 것으로 보입니다. 언패킹된 샘플이 .NET 기반이며 NanoCore Client 라는 네이밍이 되어 있고, 실제 NanoCore가 사용하는 DLL과 플러그인을 사용하며 특정 서버로의 접속을 시도하고 받아온 값에 따라 정의된 명령을 수행하는 것으로 보아 오픈소스인 NanoCore의 소스를 이용하여 제작한 RAT(Remote Access Trojan)로 분류할 수 있습니다.
이 샘플은 컴파일 이후 난독화와 패킹 과정을 거치면서 본래 .NET 기반 실행 파일이었던 사실까지 알아채기 힘들게 변형된 후 배포되고 있었습니다. 따라서 언패킹을 하지 않는 이상 정적으로는 시그니쳐 방식을 제외하고는 탐지하기 어려울 것으로 보입니다. 또한 네트워크 상에서도 암호화된 리소스 영역을 복호화한 후 그 내부에 미리 설정된 값들을 로드하여 접속할 서버, 포트 등을 정해 악성 행위를 수행하기 때문에 접속하는 서버와 포트는 샘플마다 쉽게 변경될 수 있고, 패킷 송/수신에도 암호화를 사용하여 탐지하기 상당히 어렵습니다. 남은 것은 동적 행위 분석 뿐인데, 다행인 것은 C&C 서버와의 통신이나 따로 악성 행위를 하지 않아도 '%APPDATA%\<Guid>\run.dat’ 파일을 생성하고, 이 파일의 크기는 항상 8바이트라는 점입니다. run.dat 파일은 준비 과정에서 존재하지 않을 경우 생성하여 현재 Datetime을 구하고 이를 저장하도록 되어 있습니다. 그 외에도 행위가 수행되면 catalog.dat, storage.dat, task.dat, settings.bin 중 일부 파일들이 위 경로에 드랍되며 이를 탐지 지표로 사용할 수 있겠습니다. 또한 실행 후 메모리 상에서 언팩이 완료된 후에는 NanoCore나 NanoCore.ClientPlugin 등의 문자열이 드러나기도 합니다.
요약하면, 이 샘플은 .NET 기반 오픈소스인 NanoCore를 이용하여 제작한 RAT이고 유명 게임 배틀그라운드의 핵으로 위장하여 국내 게이머들을 타겟팅하였으며 난독화와 패킹을 통해 휴리스틱, 패턴 기반 탐지를 우회하고자 하였습니다. 따라서 동적 분석으로 드랍되는 파일과 메모리에서 발견되는 문자열 등을 통해 악성 여부를 판단할 수 있겠습니다.
아래 첨부파일은 악성코드 내부의 리소스를 복호화하는 데에 사용했던 C# 프로젝트 소스코드입니다.
필요하신 분은 다운받아서 참고하여 사용해주시면 되겠습니다.
'Analysis > Malware' 카테고리의 다른 글
PyCL 랜섬웨어 복호화 툴 (0) | 2018.11.27 |
---|---|
PyCL 랜섬웨어 분석 및 복호화 방법 (1) | 2018.11.27 |
RTF 파일 Stack기반 BOF를 이용한 CVE-2010-3333 분석 (0) | 2018.05.24 |
배틀그라운드를 플레이하면 파일을 복호화해주는 PUBG 랜섬웨어 분석 (0) | 2018.04.20 |
2017년 5월, 큰 파장을 불러온 WannaCry 랜섬웨어 분석 (0) | 2018.04.12 |
__미니__
E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?