Security/AI

머신러닝을 활용한 악성코드 분석 - 빌드 프로세스

criling 2021. 11. 19. 00:16

간단한 실습을 통해 컴파일된 빌드 프로세스를 단계별로 진행하는 C코드를 살펴보겠습니다.

 

실습 환경

Linux kali 5.7.0-kali1-686-pae #1 SMP Debian 5.7.6-1kali2 (2020-07-01) i686 GNU/Linux

gcc (Debian 9.3.0-15) 9.3.0

 

 

실습

[그림 1] cat add.c

 

1. 전처리

이 단계는 전처리 단계입니다.

C에서 #문자로 시작하는 줄은 선행 처리기 지시문으로 전처리기에 의해 해석됩니다.

전처리기는 단순히 코드를 반복하고 이러한 지시문을 매크로로 처리합니다.

포함된 라이브러리의 내용을 삽입하고 코드 주석을 제거해 컴파일할 코드를 준비합니다.

 

[그림 2] cc -E add.c(전처리) (일부 캡처)

[그림 2]를 통해 #include <stdio.h>가 표준 C 라이브러리 stido.h의 일부 내용으로 대체된 것을 알 수 있습니다.

 

2. 컴파일

컴파일러는 전처리된 코드를 어셈블리 코드로 변합니다.

이렇게 생성된 어셈블리 코드는 CPU가 이해하고 실행해야 하는 명령을 포함하고 있으므로 대상 프로세서 아키텍처에만 적용된다.

[그림 3] cc -S add.c(컴파일) -&amp;amp;amp;gt; cat add.s

빨간 박스로 표시된 addl과 call을 보아 변수에 1을 더하고 print 함수를 호출하는 것을 알 수 있습니다.

다른 라인들은 다른 기능들이 액세스 할 수 있는 CPU레지스터와 메모리 위치에서 이동 값을 구성합니다.

 

 

3. 어셈블리 코드를 오브젝트 코드(기계어 코드)로 변환

[그림 4] cc -c add.c(기계어로 변환)-&amp;amp;amp;gt; hexdump add.o(일부 캡처)
[그림 5] od -c add.o (일부 캡처)

기계어로 변환된 오브젝트 파일을 hexdump 및 od를 이용하여 확인할 수 있습니다.

[그림 5]의 빨간 박스로 표시된 부분을 통해 ELF 파일인 것을 알 수 있고 ELF 파일은 파일의 유형을 포함해 파일의 일부 특성을 나타내는 헤더로 시작합니다.

 

[그림 6] readelf -h add.o

readelf와 같은 유틸리티를 사용하면 이 헤더에 포함된 모든 정보를 파싱할 수 있습니다.

 

[그림 7] chmod u+x add.o -&amp;amp;amp;gt; ./add.o

해당 오브제트 파일에 실행 권한을 부여 후 실행하면 [그림 7]과 같이 실행이 되지 않는 것을 확인할 수 있습니다. (Exec 형식 오류)

이는 어셈블러에 의해 생성된 오브젝트 코드는 실행에 필요한 중요한 프로그램 일부가 누락되어 있기 때문입니다.

또한 프로그램의 섹션이 제대로 정렬되지 않아 라이브러리 및 프로그램 기능을 성공적으로 호출할 수 없습니다.

이를 해결하는 단계가 빌드 프로세스의 마지막 단계인 링킹입니다.

이 예시에서 링커는 printf 라이브러리 함수의 오브젝트 코드를 이진 파일에 삽입합니다.

 

[그림 8] 최종 실행 바이너리 생성

stdio.h 외부 라이브러리는 정적으로 이진 파일에 링크됐고, 이것은 나머지 패키지와 함께 단일 패키지로 컴파일됐다는 의미입니다. 일부 언어 및 구현에서는 외부 라이브러리를 동적으로 포함할 수 있습니다.

즉, 코드에서 참조되는 라이브러리 구성 요소가 컴파일된 이진 파일에 포함되지 않은 것입니다.

실행 시 로더가 호출돼 동적으로 링크된 라이브러리에 대한 참조를 검색한 후 시스템에 라이브러리를 배치해 이러한 참조를 확인합니다.

 

 

참고

"머신 러닝을 활용한 컴퓨터 보안, 클라렌스 치오, 데이비드 프리먼, 에이콘"

"Machine Learning and Security by Clarence Chio and David Freeman(O'Reilly). Copyright 2018 Clarence Chio and Davide Freeman, 978-1491-97990-7"