대부분 64비트의 운영체제 PC를 사용하는 데

32비트를 사용하는 머신을 공략해야 하는 일이 생긴다.

이런 경우 공격 코드를 '크로스' 컴파일 하는데 있어

어려움을 겪을 수 있는데 그와 관련한 간단한 팁과

기초 이론을 공유해 본다.

 

 

 

 

우선 패키지 설치다.

gcc는 칼리에 기본 내장되어 있지만

크로스 컴파일 작업을 위해 필요한 패키지인

gcc-multilib를 추가로 설치해야 한다.

 

$ sudo apt-get install gcc-multilib

 

(필요하다면 아래도 설치)

$ sudo apt-get install g++-multilib

$ sudo apt-get install gcc-9-base libgcc-9-dev libc6-dev

 

 

 

 

설치를 마쳤으면 컴파일을 해주면 되는데

'어떤 방식'의 파일로 컴파일을 할지를 정해야 한다.

그리고 이 '어떤 방식'이란

statically-linked ("static") executable 과

dynamically-linked ("shared") executable

두 가지 유형의 실행 파일을 의미하며

이 두 가지의 차이점에 대한 이해가 필요하다.

 

 

 

statically-linked("statc") => 정적 링크된 정적 실행 파일

dynamically-linked("shared") => 동적으로 링크된 공유 실행 파일

 

 

 

공유 실행 파일에는 실제 결과 파일로 컴파일하는 코드만 포함된다.

printf(), socket() 등과 같은 모든 C 라이브러리 호출은

바로 이 '공유 라이브러리'에서 구현된다.

공유 라이브러리는 /usr/lib32 및 기타 위치에 저장되고

파일 이름은 항상 .so로 끝난다.

실행 파일이 실행되면 라이브러리 함수가 호출될 때마다

RUN TIME의 공유 라이브러리에서 로드 되는데

이 말은 곧 링커가 컴파일 시 실행 파일이 의존할

특정 라이브러리 이름을 정해야 함을 의미한다.

 

 

 

반면 정적 실행 파일에는 실행 파일을 실행하는데

필요한 모든 코드 및 라이브러리가 포함된다.

라이브러리는 링크 타임에 의해 선택된다.

정적 라이브러리는 공유 라이브러리와 동일한 위치에

저장되지만 파일 이름은 .a로 끝나며 코드에 포함된

양이 많기 때문에 공유된 실행 파일보다 사이즈가 크다.

 

 

 

다음은 서버에서 사용한 exploit의 예인데

같은 코드를 정적 바이너리와 공유 바이너리로

컴파일 했고 크기 차이는 다음과 같다.

-rwxr-xr-x 1 taku taku  16004 May 25 16:18 shared-binary
-rwxr-xr-x 1 taku taku 697812 May 25 16:18 static-binary

 

 

 

본인이 컴파일한 코드가 어떤 유형인지 알고 싶다면

file 명령어로 언제든 확인이 가능하다.

$ file *binary
shared-binary: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=25d71ad2477d1459ac45865dd0484c06511fd8fb, for GNU/Linux 3.2.0, not stripped
static-binary: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, BuildID[sha1]=74a316b99aff4e2dbbcf60771dcf7885f6cc2975, for GNU/Linux 3.2.0, not stripped

 

 

 

만약 공유 바이너리로 컴파일을 했고

해당 파일이 어떤 라이브러리에

의존하고 있는지 확인하고 싶다면

ldd 명령어로 확인이 가능하다.

$ file *binary
shared-binary: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=25d71ad2477d1459ac45865dd0484c06511fd8fb, for GNU/Linux 3.2.0, not stripped
static-binary: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, BuildID[sha1]=74a316b99aff4e2dbbcf60771dcf7885f6cc2975, for GNU/Linux 3.2.0, not stripped

 

 

 

실제 활용 예)

 

 

중요한 것은 경우에 따라

동작하는 파일이 다르기 때문에

둘 다 시도해 봐야 하는 경우가

종종 있다.

 

 

 

추가로

오늘 푼 문제에서 코드를 실행했더니

다음과 같은 에러가 나왔는데

$ ./PE
./PE: error while loading shared libraries: requires glibc 2.5 or later dynamic linker

 

 

공격 코드를 컴파일 할 때

다음과 같은 인자 값을 넣어 컴파일

해주면 해결된다.

 

 

-Wl,--hash-style=both

$ gcc -m32 -Wl,--hash-style=both -o PE 9542.c

 

 

 

다른 방법으로는

동일한 버전의 OS를 미리 구해둔 뒤

(vulnhub 등에서) 필요할 때마다

그곳에서 컴파일해 가져오는 방법이 있고

 

 

 

혹 윈도우 exe 파일로 크로스 컴파일 시

mingw32 툴을 활용하는 방법이 있다.

$ sudo atp install mingw-w64 

사용법 
$i686-w64-mingw32-gcc taku.c -lws2_32 -o taku.exe

 

 

 

 

 

 

 

728x90

+ Recent posts