Jump - SECCON 2024

» CTF

aarch64(ARM) 아키텍쳐의 문제입니다.

기본적으로 함수가 가져야 할 포멧을 파괴하여 decompile이 정상적으로 되지 않는 트릭을 사용합니.

ARM 계열의 난독화기에 write-up으로 남겨둡니다.

디컴파일을 방해하는 것에는 크게 2가지 방법이 사용되었습니다.

첫 번째는 Return Address 조작입니다.

ARM 계열에서는 call 명령어가 수행될 때 SFP와 Return Address를 stack에 X29, X30 레지스터에 저장합니다.

image.png

그 뒤 함수 프롤로그에서 이렇게 X29, X30의 값을 스택에 삽입하게 됩니다.

image.png

그리고 에필로그에서 스택의 값을 X29, X30에 다시 불러오고 RET이 수행되면서 PC와 FP가 원상복구됩니다.

이 점을 이용하여 Ret Address가 저장되는 X30에 임의로 다른 값을 설정하면,

image.png

함수가 RET할때 정상적으로 리턴되는 것이 아니라 임의로 설정한 X30 주소로 jmp하게 됩니다.

이런 기법들로 control flow가 난잡하게 구성되어 있어서, 함수가 return되고 나서 수행될 코드가 decompile결과에는 나타나지 않게 됩니다.

두 번째는 다른 함수 중간으로 jmp입니다.

다른 함수의 시작 지점으로 jmp하는 것은 call로써 잘 정의되어 있지만, 갑자기 다른 함수 중간으로 jmp하는 것은 굉장히 부자연스러운 흐름입니다. 이런 것들을 잘 활용하면 디컴파일러가 해석하지 않는 코드 block들을 만들 수 있습니다.

문제에서는 이렇게 6가지 case에 따라 분기하는 switch-case문이 존재합니다.

image.png

하지만 디컴파일 결과는 다음과 같습니다.

image.png

이유는 case에 해당하는 변수가 dword_41203C인데 0으로 초기화된 뒤 바로 switch-case문으로 들어가는 것을 확인할 수 있습니다. 그러니 decompiler는 case 0에 대한 block에만 해석을 시도하게 됩니다.

하지만 다른 함수에서 dword_41203C를 다른 값으로 설정한 뒤 바로 switch-case문으로 jmp하는 지점들이 존재합니다.

image.png

그러면 실제로 다른 케이스들도 실행이 되게 되는 것이죠.

이 두 점을 알고 나면 분석하는 것은 크게 어렵지는 않았습니다.

arm handray와 디버깅을 적절히 섞어서 분석 후 flag를 획득해 주었습니다.

flag: SECCON{5h4k3_1t_up_5h-5h-5h5hk3}