[KDT_AISEC] 8주차 - 악성코드 리버싱(MINI60)

Gloomy·2024년 1월 30일
0

KDT_AISEC

목록 보기
20/25

분석 대상 파일 확인


60바이트 크기의 MINI60이 분석할 악성코드 파일이다.

분석

지난 글에서 사용한 debug툴로 MINI60파일을 열어보자.

우선 분석을 시작하기 전에 SI레지스터를 0x100로 이동시켜야 한다. MINI60이라는 악성코드 자체의 확장자가 원래 .com파일이고, .com파일의 기본 SI0x100이기 때문이다.

코드를 한줄 한줄 실행시켜가면서 분석해보자.

코드를 실행시키다보니 INT 21, 인터럽트를 실행시키는 코드가 등장했다. 이전 글에서 언급했듯이 INTAH레지스터의 값으로 종류를 구분하기 때문에 INT 21,4E에 대해 찾아보자.

뭔가 조건에 맞는 첫 번째 파일을 찾는 인터럽트처럼 보인다. DX레지스터에 저장된 값을 와일드카드를 포함한 아스키 파일 규격의 포인터로 사용하는 것 같다. 즉, 해당 레지스터에 저장된 값이 일종의 파일 이름 정규표현식 역할을 하는 것이다. 어떤 파일을 찾는지 확인해보자.

*.*즉, 모든 파일 형식을 찾는 것을 알 수 있다.

파일을 찾는 데 실패하면 캐리 플래그가 SET되며 AX레지스터에 에러코드를 반환하고, 파일을 찾는 데 성공하면 DTA라는 구조로 해당 파일의 정보를 반환하는 것 같다.

DTA의 구조를 살펴보자.

기본적으로 DTA의 오프셋은 0x80이고, 해당 오프셋으로부터 Ox1E번째 오프셋에 찾고자 하는 파일의 이름이 존재하는 것 같다. 그렇다면 0x9E오프셋에 해당 파일 이름이 존재하는 것이기 때문에 해당 주소의 값을 살펴보자.

MIN60폴더 내부의 MINI60악성코드를 제외한 1234라는 이름의 파일을 찾아낸 것을 볼 수 있다. Ox9A에는 해당 파일의 사이즈도 저장되어 있는 것 같으니 확인해보자.

실제로 1234파일은 5바이트짜리 파일이기 때문에 정상적으로 잘 저장이 된 것을 확인할 수 있다.

지금까지 악성코드의 실행 방식은 해당 폴더 내부에서 *.*형식에 알맞은 첫 번째 파일을 찾는 것이다.

또다시 인터럽트가 등장했다. 이번엔 INT 21,3D를 찾아보자.

이번엔 핸들을 이용해서 해당 파일을 오픈하는 인터럽트인 것 같다. 현재 AL0x02이므로 읽기 및 쓰기 모드로 연 것을 알 수 있고, DX에는 0x9E즉, 아까 확인했던 읽어온 파일의 이름이 들어가는 것을 볼 수 있다. 파일을 여는 데 성공한다면 AX에 해당 파일의 핸들을 리턴해주고 캐리 플래그가 set되지 않는다.

캐리 플래그가 발생하지 않을 것으로 보아 파일을 여는 데 성공했고, AX에 저장된 0x5는 해당 파일의 핸들임을 알 수 있다.


이번엔 INT 21,3F이다.

핸들을 이용해 파일이나 장치를 읽는 인터럽트같다.
BX에 저장된 값을 파일 핸들로, CX에 저장된 값을 읽어올 바이트 수로, DX에 저장된 값을 읽어올 버퍼의 포인터로 사용한다. 현재 CX에는 OxFD가 저장되어 있는데, 이는 크게 의미있는 수치가 아니라 이 악성코드 제작자가 악성코드의 길이를 정확히 60바이트로 맞추려다보니 작성한 코드라고한다. DX에는 0x13C, 즉 메모리의 시작점부터 해당 악성코드가 차지하는 부분 바로 다음의 주소이다.

만약 파일을 읽는 데 성공한다면 읽어온 바이트 수를 AX에 리턴해주고 캐리를 발생시키지 않는다.

캐리가 여전히 NC인 것으로 보아 파일을 읽는 데 성공했고 읽어온 바이트 수는 5바이트인 것으로 보인다. 이 때, AXBX모두 0x5라는 값이 들어있지만, AX에 들어있는 값은 읽어온 바이트 수, BX에 들어있는 값은 파일의 핸들이다.

현재까지 이 악성코드는 감염시킬 파일을 찾고, 해당 파일의 정보를 메모리 상에서 자신이 차지하는 부분 바로 다음에 위치시키는 작용을 한다. 읽어온 부분의 데이터를 확인해보자.

1234파일의 내용인VIRUS를 잘 읽어온 것을 볼 수 있다.


다음에 실행하는 코드가 좀 특이한데, 읽어온 파일의 첫 부분이 0x2A로 시작하는지 검사한다. 이 악성코드 자체의 작용 메커니즘이 자가 복제 매커니즘이기 때문에 읽어온 파일이 이미 감염되었는지 확인하는 절차인 것이다. 중복 감염을 방지하는 로직이다.


이 부분에서 재밌는 부분이 나오는데, 우선 CX레지스터의 값을 XOR연산을 이용해 초기화시킨 후, MUL명령을 실핸하는데 MUL명령은 AX레지스터와 MUL의 첫 번째 오퍼랜드를 곱한 후 AXDX에 나눠서 저장하는 명령이다. 악성코드 작성자는 2바이트의 XOR과 2바이트의 MUL로 세 개의 레지스터를 모두 0으로 초기화시킨 것이다.


또 다시 인터럽트이다. INT 21,42를 확인해보자.

파일 포인터를 이동시키는 인터럽트이다. 파일을 읽어올 때 파일 포인터가 파일의 맨 끝으로 이동했기 때문에 해당 파일의 포인터를 맨 앞에 위치시켜 주는것이다.


INT 21,40을 살펴보자.

DX에 저장된 값의 주소부터 CX에 저장된 값의 바이트 수 만큼 BX파일 핸들에 쓰는 인터럽트이다.

지금까지 이 악성코드의 작동 원리는 우선 *.*의 형식의 파일을 찾고, 해당 파일을 열어서 메모리 상 자신의 다음에 위치시킨 후, 중복 감염 여부를 조사하고 감염된 파일이 아니라면 파일 포인터를 파일의 맨 앞으로 이동시킨 후 DX에 저장된 값의 주소부터 CX에 저장된 값의 바이트 수 만큼 파일에 쓰는 원리이다.



이전의 파일을 성공적으로 감염시켰으니 조건에 맞는 다음 파일을 찾는 인터럽트를 실행한다.

다음에 찾은 파일을 확인해보니 0x9E에 자기 자신이 들어있는 모습을 볼 수 있다. 그렇다면 자기자신은 중복 감염 여부를 검사하는 로직에서 뭔가 다르게 작용할 것이다. 확인해보자.


Zero플래그가 SET되어 0x138로 점프한 것을 볼 수 있다.

이후 또 다시 다음 파일을 찾지만, 해당 폴더에 더 이상 파일이 없기 때문에 캐리 플래그가 발생하고 AX레지스터에 에러코드가 리턴된 것을 볼 수 있다. 해당 에러코드를 살펴보자.

DOS에러코드에서 12는 NO more files, 즉 찾을 파일이 더 이상 없다는 것을 의미한다.

분석 결과

해당 악성코드는 같은 폴더 내의 *.*형식의 파일을 찾아 열어서 메모리 상에서 자신이 위치하는 다음 부분에 불러온 후 해당 파일의 첫부분을 검사해 중복 감염을 방지하고 감염된 파일이 아니라면 파일 포인터를 처음으로 이동시킨 후 자기 자신+해당 파일의 내용을 파일에 새로 써내서 복제하는 악성코드이다.

결과 확인


1234파일의 크기가 60 + 5, 65바이트로 증가했고 내부를 살펴보면

자기자신을 복제한 후 뒤에 해당 파일의 내용을 붙이는 식으로 감염시켰음을 알 수 있다. 해당 파일의 치료는 원래 파일의 내용 앞부분을 지우면 정상적으로 치료가 된다.

이렇게 수정하면 치료가 완료된 것이다.

profile
𝙋𝙤𝙨𝙨𝙤 𝙁𝙖𝙧𝙚!

0개의 댓글