Cobalt Strike를 활용할 때, 윈도우 버전과 코발트 스트라이크 버전에 따라 미미카츠가 실행되지 않는 경우가 종종 있다.
내가 겪었던 에러는 다음과 같다.
mimikatz error kuhl_m_sekurlsa_acquirelsa ; key import
(구글링을 해보면, 이런 사례가 굉장히 많이 있는 것으로 보인다.)
다른 모듈은 정상 작동을 하지만 해당 미미카츠만 되지않았다.
당시 내가 사용한 Cobalt Strike는 4.x 버전이었다.
하지만 3.x버전을 사용하면, 정상적으로 미미카츠 모듈이 수행되었다.
코발트 스트라이크에서 미미카츠만 문제였다! 하면, 구버전을 이용해보면 되고
4.x에서 문제점을 해결하고자 한다면, 다른 방법을 시도해 볼 수 있다.
다른 방법은 코발트 스트라이크 4.x 버전에서 미미카츠 모듈만 3.x 버전(정상 동작 확인 이후)을 사용하는 것이다.
사용하는 방법에도 여러 방법이 존재한다.
먼저 3.x와 4.x는 모듈을 로드하고 실행시키는 방법에 약간의 차이가 존재하는 것으로 보이는데,
이를 설명하기에 앞서 코발트 스트라이크가 모듈을 실행시키는 원리에 대해서 먼저 얘기하는 것이 좋아보인다.
코발트 스트라이크는 JAVA기반으로 만들어진 프로그램으로
각각의 모듈을 디렉토리 안에 DLL형태로 만들어놓고 이를 불러와 수행하는 형태이다. (윈도우)
그래서 cobaltstrike.jar 파일 내부를 확인해보면, resource 디렉토리에 필요한 모듈에 해당하는 DLL이 존재하는 것을 확인할 수 있다.
그럼 3.x 버전의 jar 파일에 있는 미미카츠 DLL을 가져와서 4.x 버전에서 활용하면 된다.
보통 4.x 버전에는 resource 디렉토리가 따로 존재하지 않는 경우가 많기 때문에
MimikatzKit 디렉토리 안에 resource 디렉토리를 만들고, 그 안에 3.x버전의 DLL을 위치시켜놓는 수작업이 필요하다.
또한, 4.x버전은 코발트스트라이크 내부 slave 경로에 필요한 모듈들을 DLL형태로 인코딩시켜놓고 이를 활용하는 형태이기에
MimikatzKit 디렉토리에 존재하는 cna 파일을 로드해야 우리가 가져다놓은 DLL을 활용한다.
(cna 스크립트의 내용은 그냥 미미카츠 할 때, resource 경로에 있는 DLL 사용할게요! 라는 내용이다.)
이렇게하면 실행이 되는가? NO!
코발트 스트라이크는 모듈을 사용할 때 pipe라인을 활용한다.
이를 통해 victim과 통신하여 원하는 기능을 수행하게한다.
pipe라인을 만들고 모듈을 실행하는 내용은 DLL에 존재하고, 코발트스트라이크 자체는 이에 맞는 기능을 수행한다.
다만, 각 DLL은 고유의 pipe name이 존재하고 코발트 스트라이크는 이 pipe name을 인식한다.
name이 맞지않으면? 또 에러가 난다.
3.x 버전 DLL을 그대로 활용하기위해서는 다음의 2가지 방법을 활용할 수 있다.
첫 번째는 profile 파일을 수정하는 방법이 있다.
3.x 버전에서 DLL을 확인해보면 pipe name이 하드코딩으로 박혀있는 것을 확인할 수 있다.
우리는 profile을 통해 cobaltstrike의 pipe 명을 3.x 버전의 미미카츠 DLL이 사용하는 pipename으로 세팅하면 된다.
set pipename = 'XXXXX'
이런 형태로 해놓으면, 4.x 버전에서도 3.x 버전의 미미카츠 모듈을 활용하여 정상적인 기능을 수행할 수 있다.
하지만 이 방법에도 문제가 존재하는데, 스크린 샷이나 미미카츠와 같은 단발성의 모듈같은 경우는 아무런 문제가 없지만
keylogger같은 기능은 해당 파이프라인으로 지속적으로 통신을 해야해서, keylogger기능을 수행하고 있다면
pipename 중복으로 인해 다른 기능이 수행되지 않는다.
위를 보완할 수 있는 두 번째 방법은 jar파일을 수정하는 방법이 있다.
jar 파일 내부 (beacon\jobs\mimikatzjob.class)에서 해당 모듈의 default pipename을 3.x 버전의 DLL pipe name으로 수정하는 방법이 있다.
해당 클래스만 수정하여 리패키징하면, 다른 모듈은 다 내부의 있는 slave에서 DLL 가져와서 통신하고(원래 정상 동작 방법)
미미카츠만 우리가 지정한 DLL에서 우리가 지정한 pipename을 활용하여 통신한다.
keylogger를 활용해도 pipename이 달라서 충돌이 안하고 말끔하게 해결이 되는것을 볼 수 있다.
아니면, 또 다른 방법으로는 DLL의 pipename을 jar파일에 있는 pipename으로 커스터마이징하는 방법도 가능할 것 같다.
(그 과정이 jar파일 커스터마이징보다 훨씬 까다롭겠지만..)
다행히 무결성검증은 없었다.