CreateMutex
까보면 다나와~

Bootkit 심층분석

작년에 분석한건데 공유(&관리) 차원에서 포스팅해 보아요.




1) 드라이버의 설치

최초 웹을 통해 실행되는 Agent 파일에 의해 드라이버가 설치된다.

  

이후 Agent는 생성한 파일을 서비스에 등록하여 실행시키고 DeviceIoControl 함수를 통해 직접 통신을 한다.

  

이때 드라이버는 Parameter로 보내지는 Control Code를 기준으로 각각의 명령을 처리한다.

  

Control Code에 대한 분석은 밑에서 다시 자세히 보도록 하자.

 

2) Driver Entry 분석

먼저 Control Code 명령을 받기 위한 IRP_MJ_DEVICE_CONTROL Object를 생성한다.

  

이후 IoCreateFile 함수에 대한 SSDT 후킹을 한다. (SSDT Hook같은 경우 이미 많이 보아온 기법이라 자세하게 보지는 않았다.)

  

후킹이 완료되면 atapi DriverObject를 찾아서 DeviceTypeFILE_DEVICE_DISK” DeviceObject를 찾고 Attach Device"\\Device\\Harddisk0\\DR0"인 경우 그 값을 전역변수로 저장한다.

 

, “\Driver\atapi”를 통해 Attached Device“\\Device\\Harddisk0\\DR0”이고 DeviceTypeFILE_DEVICE_DISK”인 조건의 atapi DeviceObject를 찾는 것이다. 이는 Disk ReadWrite시 필요한 조건임을 추측 할 수 있다.

 

3) Read/Write Disk Control Code 분석

위에서 언급했듯 Control Code로 넘어온 값들은 다음과 같이 일정한 조건을 통해 다양한 명령을 수행하게 된다.

  

Parameter 222008, 222000인 경우 파일명을 버퍼에 저장하여 로컬에서 접근을 막도록 한다. SSDT와 관련된 내용으로 자세한 분석은 생략한다.

 

222014의 경우 실제 하드디스크의 특정 SectorWrite를 수행한다.


 

넘어오는 Parameter Agent에서 보낸 Data I/O manager를 통해 SystemBuffer에 포함된다. IRP 데이터의 입출력 처리 방식은 따로 언급하지 않겠다. 다만, SystemBuffer를 사용하는 방식은 IRP_BUFFERED_IO(0X10)이고 IRP + 8 byte offset에 위치한 Flags값으로 확인 가능하다.

 

위의 그림에서 볼 수 있듯이 SystemBuffer(밑의 80D50DF8) + 8 byte offset 위치에 있는 값이 악성코드가 디스크에 쓰는 값이고(밑의 빨간 네모 박스), Sector 번호 및 Sector Counter값이 같이 인자로 넘어온다.

 


그렇다면 해당 인자를 통해 어떠한 방식으로 물리 디스크에 데이터를 삽입할까?

 

악성코드가 물리 디스크에 데이터를 Read/Write하는 방식은 다음과 같다.

(1) 임의 메모리에 ScsiRequestBlock(이하 SRB) 구조체를 생성 및 셋팅

(2) ATAPI DeviceObject Index를 통해 해당 Device의 비동기적 IRP 생성

(3) 생성한 IRP 셋팅 – StackMajorFunction, SRB 포인터 등을 설정

(4) ATAPI Device에 붙은 Atapi.sys (Driver)IRP_MJ_INTERNAL_DEVICE_CONTROL를 호출하여 디스크 접근

 

다음은 소스코드이다.

 


위의 코드 중 특별히 확인해야 할 부분은 IRP Stack에 들어가는 MajorFunction 3(IRP_MJ_READ)인경우 Command Descriptor Block(CDB) 구조체의 OpCode Read이고 아닐 경우 Write라는 것이다.

CDB에는 실제 물리 디스크에 어느 위치를 사용할 지 정의할 수 있고 따라서 SRB구조체의 CDB는 디스크 위치를 찾아가는 중요 포인트가 된다.

 

다음은 MBR Sector를 수정하는 SRB이다.

 

노란색으로 나타낸 부분이 CDB 부분이며 주황색으로 표시된 부분이 CDB[5]으로 Logical Block Address(LBA)을 나타낸다. LBA Sector를 나타내는 번호이고 위의 그림상으로 00 이므로 0번째 Sector가 된다. 0번째 Sector Disk MBR이 위치하는 곳이다. CDB[7] Sector Counter로 몇 개의 Sector를 사용할지 나타낸다. 위의 그림상에서는 01이므로 한 개의 Sector를 사용한다는 뜻이다. (보통의 경우 1 Sector 512byte로 만약 쓰고자 하는 데이터가 그 이상이 될 때는 사용할 Sector를 더 많이 지정해 줘야한다.)

 

CDB는 사용하는 목적에 따라서 여러가지 구조로 정의 할 수 있는데 악성코드에 의해 만들어지는 것은 10 Size 2A(write)로 정의되었다.

  

CDB(10) Write의 구조

 

SRB가 셋팅되면 IRP를 생성하고, Stack SRB의 구조체를 Parameter로 설정한다.

 

Stack의 첫번째 0FIRP_MJ_INTERNAL_DEVICE_CONTROL(Major Function)을 나타내며 80D7A858 SRB의 포인터가 된다. IRP_MJ_INTERNAL_DEVICE_CONTROL SCSI Request를 요청할 때 SRB 포인터를 Parameter로 설정한다.

 

이후 IofCallDriver 함수를 통해 atapi driver에게 IRP를 넘기게 되고 Stack에 담겨진 SRB 데이터를 읽어 물리 디스크에 직접 접근하게 된다.

 

 

 

디스크에 Write를 완료하면 Agent 222020 ControlCode를 호출하게 되는데 이는 atapi driverIRP_MJ_INTERNAL_DEVICE_CONTROL함수를 후킹하게 된다.

  

더 이상 해당 SCSI I/O Request를 수행 할 수 없게 되는 것이다.

  


디스크에 삽입된 데이터를 분석하면 Anti AV, OnlinegameHack Tool, DownLoader 등이 있으며, 부팅시 변조된 MBR 코드에 의해 자동으로 실행되어 진다.

  Comments,     Trackbacks