2017년 5월에 등장하여 큰 파장을 불러일으켰던 랜섬웨어 WannaCry를 분석해봤습니다.
PDF 보고서가 보이지 않는다면 아래의 '분석 보고서 열기' 버튼을 클릭하여 열람하시기 바랍니다.
1. 정적 분석
2017년 5월에 등장하여 상당히 큰 파장을 불러왔던 랜섬웨어인 WannaCry를 분석해보고 싶은 생각이 들어 분석을 시작했습니다.
1-1. WannaCry.exe 정적 분석
파일명 |
WannaCry.exe |
파일 크기 |
3,723,264 Bytes (3.55 MB) |
파일 타입 |
PE32 executable for MS Windows (GUI) Intel 80386 32-bit |
||
MD5 |
0c694193ceac8bfb016491ffb534eb7c |
||
SHA1 |
3afa73283d1e17de1bde6cc14e19417e70fc9554 |
||
SHA256 |
dbf3890b782ac04136c3336814eef97e3c0f4133f9592e882c131c179161b27b |
||
SSDeep |
98304:yDqPoBhz1aRxcSUDk36SAEdhvxWa9P593R8yAVp2HI:yDqPe1Cxcxk3ZAEUadzR8yc4HI |
아이콘 없는 평범한 Win32 GUI 프로그램입니다.
[그림 1. WannaCry.exe Exeinfo PE]
Exeinfo PE를 이용하여 분석해본 결과 패킹은 따로 되어 있지 않은 것 같습니다. 이대로 바로 분석이 가능할 것 같아서 일단 IDA로 열어서 분석해봤습니다.
1-1-1. 공통 부분
[그림 2. 특정 도메인 접속 시도]
프로그램이 시작된 직후 특정 도메인(iuqerfsodp9ifjaposdfjhgosurijfaewrwergwea.com)으로 HTTP 접속 요청을 보내는 것을 볼 수 있습니다. 무슨 의도인지는 모르겠지만 이후 아무것도 하지 않습니다.
[그림 3. 인자 확인 및 분기]
그림 2에서 가장 밑에 있는 sub_408090 함수 내에서 argc를 확인하여 인자가 존재할 경우 및 존재하지 않을 경우를 판단한 후 서로 다른 동작을 합니다. 인자가 존재하는 경우부터 우선 확인하도록 하겠습니다.
1-1-2. 인자가 존재할 경우
그림 3을 확인해 보면 “mssecsvc2.0”이라는 서비스를 열어서 특정 함수의 인자로 넘기고, ServiceStartTable의 lpServiceProc에 다른 함수를 등록한 뒤 StartServiceCtrlDispatcherA함수를 호출하여 해당 함수를 실행시키는 것을 볼 수 있습니다.
[그림 4. SERVICE_CONFIG_FAILURE_ACTION 설정]
위에서 넘어간 특정 함수는 서비스가 특정 상황일 때 어떤 동작을 할 지를 설정하는 부분입니다. 여기에는 ChangeServiceConfig2라는 API가 사용되는데, 이 API의 세번째 인자는 두번째 인자에 따라 달라지며, 현재 그림 5에서 보이는 2는 서비스가 SERVICE_CONFIG_FAILURE_ACTIONS, 즉 서비스가 실행 도중 실패할 때를 나타냅니다.
[그림 5. SERVICE_FAILURE_ACTIONS 구조체]
세번째 인자인 SERVICE_FAILURE_ACTIONS 구조체의 lpsaActions 멤버를 보면 특정 상황일 때 어떤 Action을 취할 지 설정할 수 있습니다. 그림 4에서 scAction.Type에 1을 지정하는 것은 SC_ACTION_RESTART이므로 서비스를 재시작하는 것이라고 볼 수 있으며, 1000 * delaySec으로 실행 딜레이를 지정하는데 60이 인자로 넘어왔으므로 서비스가 실행 도중 실패할 경우 60초 후 서비스를 재시작하도록 설정하는 것이라고 볼 수 있습니다.
[그림 6. SMB Exploit Thread]
그림 3에서 StartServiceCtrlDispatcher 함수에 넘기는 구조체에 설정된 disseminateServiceProc 함수 내부를 확인해 보면 위와 같은 부분이 있습니다. 내부에서 랜덤하게 IP Address를 생성하여 SMB Exploit을 시도하기 때문에 위와 같이 함수를 네이밍 해두었습니다.
[그림 7. SMB Exploit Function]
내부에선 랜덤하게 IP Address를 생성하여 SMB 포트인 445포트로 접속을 시도한 후, 접속에 성공하면 해당 IP의 마지막 1바이트를 1~254까지 바꿔가며 접속 및 Exploit을 시도합니다. SMB 익스플로잇의 경우 EternalBlue 라고 명명된 CVE-2017-0144를 사용하는데 이는 따로 분석하지 않겠습니다. 이 방식으로 수많은 취약한 호스트를 자동으로 공격하고 전파되는 방식을 사용했기 때문에 첫 등장 이후 큰 이슈가 되었습니다.
1-1-3. 인자가 존재하지 않을 경우
[그림 8. 서비스 생성 및 실행]
인자가 존재하지 않을 경우 “mssecsvc2.0” 서비스를 생성하고 실행합니다. 어디서 많이 본 서비스인데요, 위에 인자가 존재할 경우에 실행된 루틴에서 핸들을 가져와 SERVICE_FAILURE_ACTIONS를 정의한 그 서비스입니다. CreateService 함수의 인자인 Binary Path에는 “argv[0] –m security” 형식이 되어 인자가 들어간 상태로 실행되도록 설정되어 있습니다. 이러면 자동으로 새로 생성된 서비스가 직접 스스로에게 SERVICE_FAILURE_ACTIONS를 정의하고 SMB Exploit을 하는 Thread를 만들어서 계속 실행될 것입니다.
[그림 9. 리소스 드랍 및 실행]
서비스 생성을 마친 후 “C:\Windows\tasksche.exe” 파일을 “C:\Windows\qeriuwjhrf” 파일로 옮긴 후, 리소스 영역에서 PE 파일을 가져와 “C:\Windows\tasksche.exe”에 드랍합니다. 이후 CreateProcess를 이용하여 실행합니다. 이 파일은 tasksche.exe 라고 부르겠습니다. 분석해본 결과 실제 파일을 암호화하고 랜섬노트를 드랍하는 랜섬웨어의 행위는 여기서 드랍된 tasksche.exe에서 실행되었습니다.
1-2. tasksche.exe 정적 분석
파일명 |
tasksche.exe |
파일 크기 |
3,514,368 Bytes (3.35 MB) |
파일 타입 |
PE32 executable for MS Windows (GUI) Intel 80386 32-bit |
||
MD5 |
7f7ccaa16fb15eb1c7399d422f8363e8 |
||
SHA1 |
bd44d0ab543bf814d93b719c24e90d8dd7111234 |
||
SHA256 |
2584e1521065e45ec3c17767c065429038fc6291c091097ea8b22c8a502c41dd |
||
SSDeep |
98304:QqPoBhz1aRxcSUDk36SAEdhvxWa9P593R8yAVp2Hj:QqPe1Cxcxk3ZAEUadzR8yc4Hj |
WannaCry.exe의 리소스 영역에서 그대로 드랍된 파일입니다. 파일 크기가 거의 변화가 없는 것으로 보아 WannaCry.exe의 거의 대부분은 이 파일이 차지하고 있었던 것으로 보입니다. 이 파일을 드랍한 후 WannaCry.exe의 나머지 부분은 서비스를 만들어서 특정 Host에 EternalBlue취약점을 이용하여 SMB Exploit으로 전파되는 행위를 수행했습니다. 이 파일에서는 실제로 랜섬웨어의 행위를 진행합니다.
[그림 10. 자가복제 작업]
tasksche.exe 파일은 실행되고 나면 argv[1]을 검사하여 “/i”와 일치하는지 확인합니다. Anti-Sandbox 기법인지는 모르겠으나 이 값이 없을 경우 아무것도 하지 않고 종료됩니다.
[그림 11. 랜덤 문자열 생성 루틴]
SetRandomString_by_PCName이라고 이름 붙인 함수 내부에서는 PC 이름에 따라 8~15글자의 소문자 알파벳 + 3글자의 대문자 알파벳으로 이루어진 문자열을 생성하여 파라미터로 전달받은 포인터에 저장합니다. 이 값은 특정 루틴 내에서 PC 이름을 이용해 seed를 생성하고, 이를 이용해 srand한 후 생성한 문자열이므로 PC 이름이 같을 경우 다른 환경에서도 똑 같은 값을 뽑아낼 것입니다. 이후 그림 10의 루틴을 계속 타면서 “C:\Windows\ProgramData\<RANDOM>”, “C:\Windows\Intel\<RANDOM>”, “C:\Windows\<RANDOM>”, “%TEMP%..\<RANDOM>” 경로에 순차적으로 시도해가면서 디렉토리를 생성하고 CurrentDirecotry를 설정합니다. 그 다음 CopyFile API를 이용해 자가복제하고 복제한 파일을 서비스 또는 프로세스를 이용하여 새 프로세스로 생성하고, 다시 원래 디렉토리로 돌아옵니다. 그리고 현재 실행되고 있는 디렉토리를 “HKEY_CURRENT_USER\Software\WannaCrypt0r”, “HKEY_LOCAL_MACHINE\Software\WannaCrypt0r”에 등록합니다.
[그림 12. 리소스 unzip]
unzipResource라고 이름붙인 함수 내에서는 리소스 파일을 하나 가져와서 unzip을 수행합니다. 인자로 넘어간 s_WNcry_2o17의 값은 “WNcry@2ol7”로, 압축파일의 비밀번호에 해당했습니다. 해당 리소스를 덤프하여 확인해 보면 확실히 zip 압축 파일이었고, 압축을 해제하면 여러 파일들이 드랍됩니다.
[그림 13. 리소스 내부 파일들]
[그림 14. msg 내부]
msg 폴더 내부에는 PC 언어 환경에 따라 다른 메시지를 보여줄 수 있도록 다양한 언어로 랜섬노트가 작성되어 있습니다.
[그림 15. b.wnry]
b.wnry 파일은 BMP 포맷 이미지 파일로, 파일 암호화가 완료된 뒤 이것으로 바탕 화면을 변경할 것으로 보입니다.
[그림 16. c.wnry]
c.wnry 파일은 Tor브라우저 관련 설정이 들어 있는 파일로, 도메인과 토르 브라우저를 다운받을 수 있는 URL이 적혀 있었습니다.
[그림 17. r.wnry]
r.wnry 파일은 랜섬노트 텍스트 파일이었습니다.
[그림 18. s.wnry]
s.wnry 파일은 zip 포맷 압축 파일로, 내부에는 토르 브라우저 관련 파일들이 들어 있었습니다.
[그림 19. 랜섬 행위 시작]
현재 디렉토리를 숨김 설정하고 모든 사용자에게 폴더 접근 권한 준 후 t.wnry 파일을 읽고 랜섬 행위를 시작합니다. t.wnry 파일은 리소스에도 존재하지 않았고 어디서 드랍되는지 찾을 수가 없어 분석이 불가능했습니다. 핵심 부분은 그림 19의 p_CustomFuncPointer에 접근해야 알 수 있는데, 이는 t.wnry 파일에서 가져온 버퍼이기 때문에 내용을 알 수 없었으며 분석하는 도중 깨달은 것이지만 정상적으로 실행되지도 않기 때문에 동적으로 분석하는 것도 불가능했습니다. 마지막으로 문자열 내부를 확인하여 랜섬행위를 진행하는 확장자명을 뽑아 보았는데, 이는 다음과 같습니다.
.doc, .docx, .docb, .docm, .dot, .dotm, .dotx, .xls, .xlsx, .xlsm, .xlsb, .xlw, .xlt, .xlm, .xlc, .xltx, .xltm, .ppt, .pptx, .pptm, .pot, .pps, .ppsm, .ppsx, .ppam, .potx, .potm, .pst, .ost, .msg, .eml, .edb, .vsd, .vsdx, .txt, .csv, .rtf, .123, .wks, .wk1, .pdf, .dwg, .onetoc2, .snt, .hwp, .602, .sxi, .sti, .sldx, .sldm, .sldm, .vdi, .vmdk, .vmx, .gpg, .aes, .ARC, .PAQ, .bz2, .tbk, .bak, .tar, .tgz, .gz, .7z, .rar, .zip, .backup, .iso, .vcd, .jpeg, .jpg, .bmp, .png, .gif, .raw, .cgm, .tif, .tiff, .nef, .psd, .ai, .svg, .djvu, .m4u, .m3u, .mid, .wma, .flv, .3g2, .mkv, .3gp, .mp4, .mov, .avi, .asf, .mpeg, .vob, .mpg, .wmv, .fla, .swf, .wav, .mp3, .sh, .class, .jar, .java, .rb, .asp, .php, .jsp, .brd, .sch, .dch, .dip, .pl, .vb, .vbs, .ps1, .bat, .cmd, .js, .asm, .h, .pas, .cpp, .c, .cs, .suo, .sln, .ldf, .mdf, .ibd, .myi, .myd, .frm, .odb, .dbf, .db, .mdb, .accdb, .sql, .sqlitedb, .sqlite3, .asc, .lay6, .lay, .mml, .sxm, .otg, .odg, .uop, .std, .sxd, .otp, .odp, .wb2, .slk, .dif, .stc, .sxc, .ots, .ods, .3dm, .max, .3ds, .uot, .stw, .sxw, .ott, .odt, .pem, .p12, .csr, .crt, .key, .pfx, .der
2. 동적 분석
[그림 20. WannaCry.exe 동적 분석 - 1]
API Monitor를 이용하여 동작을 확인해 보니 정적 분석에서 확인한 것처럼 “mssecsvc2.0”으로 서비스를 만들고, “C:\Windows\tasksche.exe”에 리소스 드랍 후 CreateProcess로 실행시키지만 드랍한 파일이 정상이 아닌지 제대로 시작되지 않는 것을 볼 수 있습니다. 이 문제로 실제 암호화 행위를 진행하는 부분은 분석이 불가능한 상태에 있습니다.
[그림 21. WannaCry.exe 동적 분석 - 2]
서비스로 등록되어 실행된 루틴을 보니 수많은 쓰레드들이 계속해서 생성되면서 무언가 작업을 진행하고 있었습니다.
[그림 22. 등록된 mssecsvc2.0 서비스]
mssecsvc2.0 이름으로 등록하는 루틴이 존재했던 것과 같이 서비스가 등록되어 실행되고 있었습니다.
[그림 23. WannaCry.exe 네트워크 분석]
네트워크로는 수많은 호스트의 445포트로 연결을 시도하고, SMB 익스플로잇을 시도하는 내용이 보입니다. 드랍했던 파일인 tasksche.exe도 동적으로 분석하고 싶었지만 위에 언급한 대로 정상적인 실행이 되지 않았기 때문에 분석이 불가능했습니다.
3. 결론 & 자동 탐지 방안
WannaCry.exe는 2017년 5월경 등장하여 SMB 취약점을 이용한 강력한 자가 전파 능력으로 전 세계에 큰 충격을 안겨줬던 랜섬웨어입니다. 처음에 연결을 시도한 도메인은 킬 스위치였던 모양입니다. 어떤 방식으로 접속에 성공할 경우 전파되지 않는지는 잘 모르겠지만, 기사는 이렇게 나와 있습니다. ( http://www.itworld.co.kr/news/104756 )
분석을 시작하기 전까진 몰랐지만 패킹이나 프로텍팅이 전혀 되어 있지 않은 깔끔한 바이너리였고, 따라서 정적으로 분석하는 데에 큰 무리는 없었습니다. 그냥 문자열 패턴만으로도 내부에 “*.wnry”와 여러 확장자명들, 킬 스위치로 사용된 도메인 등이 들어 있기 때문에 정적으로도 무리 없이 탐지가 가능할 것으로 보입니다. tasksche.exe 내부 리소스로 zip파일에 암호를 걸어서 넣어둔 것은 데이터를 자동 분석으로 뽑아내기는 어렵게 만들었지만 zip 파일 구조 특성상 파일, 디렉토리명 등은 전혀 암호화가 되지 않기 때문에 정적으로 탐지하는 데에 전혀 지장을 주지 않았습니다. 또한 동적 분석으로도 특정 이름의 서비스를 등록하거나, 파일을 드랍하거나, 특정 포트로의 수많은 접근을 시도하는 등 뚜렷한 행위가 나타났기 때문에 탐지에 큰 어려움이 없을 것으로 보입니다. 탐지 가능한 지표에는 대표적으로 “C:\Windows\tasksche.exe” 파일을 생성하고, “mssecsvc2.0” 서비스를 등록하거나, “*.wnry” 확장자의 파일을 읽고 쓰는 행위 등이 있겠습니다.
요약하면, 이 샘플은 취약점을 Exploit하여 네트워크를 통해 자동으로 전파되는 기능을 가진 랜섬웨어입니다. 정상 파일로 위장하기 위해 “mssecsvc2.0”이라는 이름의 서비스를 생성하고 실패시 자동으로 다시 시작하는 루틴을 만들고, 여러 프로세스와 파일을 넘나들며 실행되는 것을 보면 상당히 정교하게 만들어져 있습니다. 하지만 그럼에도 패킹이나 프로텍팅이 전혀 되어있지 않아 정적 분석에 어려움이 별로 없었다는 점이 특징이며, 리소스에서 드랍된 tasksche.exe는 실제 VirusTotal등에서 수많은 벤더가 악성으로 진단하고 있는 상황임에도 정상 동작하지 않았습니다. 정적 시그니쳐는 물론이고 패턴, 문자열 등으로 충분히 악성 판단이 가능하고, 동적으로도 서비스 등록 및 네트워크를 통한 Exploit 등 특징이 두드러지기 때문에 쉽게 악성 판단이 가능한 샘플인 것으로 보입니다.
4. 기타
IDA를 이용하여 정적 분석을 하다 보면 악성코드가 직접 만든 custom struct들을 자주 만나게 됩니다. 특히 이번에 분석했던 WannaCry의 경우는 그게 더 심했는데요, 1000바이트가 넘어가는 크기의 struct를 선언하고 사용하는 경우가 있어 이를 직접 만들긴 힘들어 보여 idapython을 사용하였습니다. idapython은 IDA와 연동하여 사용할 수 있는 일종의 Python 라이브러리인데, IDA를 켰을 때 아래에 있는 커맨드라인 입력 창에서 인터프리트 형식으로 사용이 가능합니다. 예를 들어, 크기가 상당히 큰 Struct이고 멤버 변수를 모두 4바이트 DWORD로 선언하고 싶은 경우 다음과 같이 사용이 가능합니다.
[그림 24. idapython 사용]
IDA 에서 Python 스크립트를 이용하는 것은 2~3년쯤 전 BoB를 하면서 배웠었지만 지금까지 실감하지 못하고 있었는데 상당히 강력한 도구인 만큼 잘 활용하면 분석에 큰 도움이 될 것으로 보입니다.
'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 |
배틀그라운드 핵으로 위장한 NanoCore RAT 악성코드 분석 (0) | 2018.03.29 |
__미니__
E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?