SlideShare a Scribd company logo
1 of 50
LINUX REVERSING BASIC #4 Injection
목차
• Injection
• ptrace를 이용한 Injection
• 실습 – ptrace 사용법
• 실습 – Code injection
• Injector
• 실습 – SO injection
• Shared library
• Injector
• dlopen
• open & mmap
• 환경변수를 이용한 Injection
• 실습 – SO injection
• 실습 – API Hooking
• 부록
• 참고 사이트
PTRACE를 이용한 INJECTION
• 실습 – ptrace 사용법
• 실습 – Code injection
• 실습 – SO injection
PTRACE를 이용한 INJECTION
• 리눅스는 윈도우에서 DLL injection에 이용했던 CreateRemoteThread와 같은 API가 없음
• 대신 ptrace 함수 이용
• ptrace
• process trace의 약자
• 프로세스의 상태를 조사하고 조작할 수 있게 하여, 한 프로세스가 다른 프로세스를 제어할 수 있도록 하
는 시스템 콜
• 디버거, strace와 ltrace 등의 프로그램이 주로 이용
• 파일 디스크립터, 메모리, 레지스터 등을 조작할 수 있고, 코드를 싱글스텝하고 시스템 호출과 그 결과를
가로채며 대상의 시그널 핸들러와 시그널을 조작할 수 있다.
• ->강력한 능력이 있으므로, 오직 소유자가 시그널을 보낼 수 있는 프로세스들만 attach할 수 있음(일반
적으로 자신의 프로세스들)
• (최신 리눅스에는 ptrace protection이 적용되어 있음)
PTRACE를 이용한 INJECTION
• ptrace
• 인자
• request
• ptrace를 이용해 하고자 하는 작업
• pid
• 대상 프로세스 id
• addr
• request에 따라 무시되거나 이용 됨
• data
• request에 따라 무시되거나 이용 됨
PTRACE를 이용한 INJECTION – 실습
• 대상 프로그램
• 종료하기 전까지는 꺼지지 않는 프로그램을 제작
• 이 프로그램에 injection을 할 것임
• 일단 32bit로 컴파일
PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법
•ptrace 함수(시스템
콜)를 이용해본다.
• ptrace는 인자로 넣은
요구에 따라 여러가지
일을 해 준다.
• ptrace로 할 수 있는 일
을 몇 가지 정리했음
명령 설명 비고
PTRACE_ATTACH 프로세스 추적을 위해 대상 프로세스에 대한 부모 프로세스가 됨
일반적으로 자식 프로세스만 attach 가능 (OS 설정 따라 다름)
non-child를 attach하려면 root 권한 필요
attach된 프로세스는 stop됨
PTRACE_TRACEME 자식 측에서 호출해야 함. 부모가 trace할 수 있도록 함.
SIGKILL 이외의 다른 signal을 받으면 부모프로세스에게 SIGTRAP을 걸어 전달
부모 프로세스가 준비되기 전
에 호출하면 안 됨
PTRACE_DETATCH PTRACE_ATTACH로 붙은 프로세스를 분리
PTRACE_POKEDATA
PTRACE_POKETEXT
대상 프로세스 메모리에 기록 (워드 단위) 워드 크기는 OS마다 다름
PTRACE_PEEKDATA
PTRACE_PEEKTEXT
대상 프로세스 메모리에서 읽어서 내용 반환 (워드 단위) 워드 크기는 OS마다 다름
PTRACE_GETREGS
PTRACE_GETFPREGS
대상 프로세스의 레지스터 값을 읽음.
위는 general 레지스터, 아래는 부동소수점 레지스터
PTRACE_SETREGS
PTRACE_SETFPREGS
대상 프로세스의 레지스터에 값을 씀.
위는 general 레지스터, 아래는 부동소수섬 레지스터
PTRACE_CONT 정지 상태에 있는 대상 프로세스를 계속 실행하도록 함
PTRACE_SINGLESTEP 대상 프로세스가 하나의 기계어를 실행한 뒤 멈춤
PTRACE_KILL 대상 프로세스에 SIGKILL을 보내 종료하도록 함
PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법
• ptrace
• 프로세스 attach 하기
• 실행중인 프로그램에 대해 trace할 수 있
도록 attach 한다.
• register 값 얻기
• 프로세스의 register 값을 가져온다
• data 인자에 레지스터 값을 저장할 버퍼
주소를 넣어주어야 한다.
• 프로세스 detach 하기
• attach했던 프로세스를 detach 한다.
PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법
• ptrace 실습
• 컴파일은 32비트로 한다.
• 레지스터 값을 가져오는 ptrace의 data 인자로
버퍼 주소를 넣는다
• 데이터는 sys/user.h 에 정의된 구조체인
user_regs_struct 포맷이다.
PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법
• ptrace
• 대상 프로세스 register에 쓰기
• data에 적어준 주소에 있는 구조체(앞에서 언급)에 있는 값으로 레지스터 값 설정
• 실습
• 컴파일은 32비트로 한다.
• 구조체에 값을 설정하고, ptrace의 PTRACE_SETREGS
• data 인자로 버퍼 구조체 주소를 넣는다
PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법
• ptrace
• 대상 프로세스 메모리 읽기
• 인자에 넣은 addr를 시작으로 워드 크기만
큼 읽는다.
• 32비트의 워드는 보통 4바이트, 64비트의
워드는 8바이트
• 대상 프로세스 메모리에 쓰기
• 인자에 넣은 addr부터 data에 넣은 값을 쓴다.
• 워드 단위로 쓴다.
PTRACE를 이용한 INJECTION – 실습 – CODE INJECTION
• code injection
• 직접 코드를 끼워 넣음
• 기계어를 메모리에 쓰고, EIP를 조작하여 실행
• (기존 프로그램을 이어서 하기를 원한다면 레지스터 값을 백업해두고, dlopen 호출하기 전에 레지스터 값
을 백업해두고, bp를 걸어 둔 뒤 다시 복원하면 됨)
• 여기까진 안 하겠음
• 예에서는 그냥 코드 영역에 덮어 썼음
• EIP를 조작할 필요 없었음
• 새로 실행권한이 있는 메모리를 할당하고 이용하거나, 스택에 저장 후 mprotect 함수를 이용하여 실행 권
한을 줘도 됨
PTRACE를 이용한 INJECTION – 실습 – CODE INJECTION – INJECTOR
• code injection
• 왼쪽은 끼워 넣을 코드
• 예전에 작성했던 셸 코드를
이용했음
• 오른쪽은 인젝션하는 코드
• eip 바로 뒤에 코드를 넣었음
• ptrace는 워드 단위로 복사한다
는 점에 주의
PTRACE를 이용한 INJECTION – 실습 – CODE INJECTION – INJECTOR
• 인젝션된 모습
• 다음엔 기존 프로그램의 코드를 망치지 않고, 다른 영역에 코드를 인젝션하여 실행하고, 다시 기존 코드로 돌아오도록
해보자
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION
• so injection
• 기본적으로 Code injection과 비슷함
• dlopen 함수를 호출하는 코드를 injection하여 so injection
• dlopen은 Windows의 LoadLibrary에 해당하는 함수
• 인젝션 한 라이브러리에 __attribute__((constructor)) 를 붙인 함수가 있다면 dlopen이 반환하기 전에 실행 됨
• DllMain과 비슷한 역할
• __attribute__((constructor)) 는 gcc 지시자이다
• 참고로, __attribute__((destructor)) 를 붙이면 main이 끝난 뒤 호출된다.
• (기존 프로그램을 이어서 하기를 원한다면 레지스터 값을 백업해두고, dlopen 호출하기 전에 레지스터 값을 백업해
두고, bp를 걸어 둔 뒤 다시 복원하면 됨)
• 여기까진 안 하겠음
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – SHARED LIBRARY
• injection할 라이브러리 제작
• -fPIC : position-independent code로 컴파일 됨
• 올라오는 주소가 랜덤해도 상관없는 코드
• -shared : 공유 라이브러리이므로, 공유 되도록 함
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – SHARED LIBRARY
• injection할 라이브러리 테스트
• 동적 라이브러리를 로드하는 코드
• LoadLibrary를 호출한 것과 같음
• -ldl
• libdl.so를 링킹
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR
• Injector
• dlopen 함수는 libdl.so 라이브러리에 있는 함수이다
• 인젝션된 코드에서 dlopen을 호출하기 위해서는 대상 프로세스가 libdl.so를 로드해야 한다.
• LoadLibrary를 호출하기 위해 kernel32.dll이 올라와 있어야 한다는 것과 비슷한 맥락
• 따라서, dlopen을 이용한 방법에는 제약이 있다.
• dlopen 대신에 open 시스템 콜과 mmap 시스템 콜을 이용할 수 있음
• -> 직접 .so 파일을 열고, 메모리를 할당하여 올린다.
• 첫 번째 injector 실습은 dlopen을 이용
• ->대상 프로세스에 dlopen을 이용하는 코드를 넣을 것
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – DLOPEN
• 대상 프로그램 수정
• dlopen을 plt, got에 잡아 주기 위해 호출했다.
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – DLOPEN
• Injector
• dlopen 함수
• 라이브러리가 잘 작동하는지 체크하기 위해 이용했던 코드에
서 dlopen 인자가 어떻게 넘어가는지 확인
• RTLD_NOW는 1로 정의되어 있음
• 이를 참고하여 인라인 어셈블리로 코드를 작성한다.
• PLT를 이용하여 dlopen을 호출하도록 할 것이므로, PLT를 알아
낸다.
• 0x8048410
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – DLOPEN
• Injector
• 앞에서 얻은 정보를 이용하여
dlopen을 호출하는 코드를 어셈
블리로 씀
• 이 코드를 injection하여 대상 프
로세스가 dlopen 함수를 호출하
도록 함
• exit을 넣어서 종료되도록 했음
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – DLOPEN
• 인젝션된 모습
• 다음엔 기존 프로그램의 코드를 망치지 않고, 다른 영역에
코드를 인젝션하여 실행하고, 다시 기존 코드로 돌아오도
록 해보자
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• 특정 라이브러리가 필요한 dlopen은 제약이 있음
• open과 mmap 시스템콜을 이용하여 대신할 수 있다.
• 직접 라이브러리 파일을 열고, 그 내용을 메모리에 올려준다.
• 계획
• open으로 라이브러리 파일을 연다.
• mmap으로 메모리에 올린다.
• EIP를 옮겨 코드를 실행한다.
• 라이브러리가 올라온 주소에 맞게 relocation이 필요
• dlopen은 동적 라이브러리를 올리는 함수로, relocation 작업까지 포함하여 해준다.
• 이번에는 직접 파일을 열어 올리므로 relocation 작업을 직접 해주어야 한다.
• ->재배열이 싫다면 PIC로 컴파일하면 된다. 위치 독립적 코드로, relocation이 필요하지 않음.
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• mmap
• fd로 지정된 파일에서 offset을 시작으로 length바이트 만큼을 addr주소로 대응시키도록 한다.
• addr를 시작주소로, 파일 내용을 메모리에 올림
• addr는 단지 그 주소를 사용했으면 좋겠다 정도로, 무조건 해당 주소를 이용할 수 있는 것은 아님
• 보통 0을 지정한다. OS가 알아서 올려 줌
• prot은 원하는 메모리 보호 모드이다. bit OR로 설정.
• 반환 값
• 실제로 메모리에 올라온 시작 주소를 반환
• 아래 있는 munmap은 반대로 메모리를 해제하는 일을 한다.
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• open&mmap 실습
• 함수 사용법을 익히고, 인젝터에 필요
한 어셈블리어를 얻기 위해 간단한 예
제 프로그램을 작성해 본다.
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• 대상 프로그램
• 다시 dlopen코드를 뺌
• 인젝션 할 라이브러리
• 기존 코드 그대로 사용
• 단, PIC로 컴파일 해야 함(앞에서 PIC로 컴파일 했다)
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• 인젝션 할 라이브러리
• relocation이 필요하다.
• ->이 예에서는 relocation이 없어도 가능하도록 인라인 어셈블리로 코딩했음
• 문자열을 write하는 코드의 라이브러리
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• Injector
• 앞서 만든 open&mmap 실습 코드에서 시스템 콜 인자를 조사
• open
• flag로 이용할 O_RDWR는 2로 정의되어 있음
• 사실 open은 int open (const char *FILENAME, int FLAGS[, mode_t MODE]) 형태
• 뒤의 mode_t는 O_CREAT 옵션을 이용 할 시 필요
• O_CREAT가 아닐 경우 인자를 2개만 쓸 수 있음(오버로딩)
• edx에는 mode에 해당하는 값(2개만 쓸 경우 무시됨. 쓰레기 값을 넣으면 됨)
• ecx에는 flags에 해당하는 값 (2)
• ebx에는 파일 이름 문자열 주소
• eax에는 시스템 콜 번호인 5
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• Injector
• 앞서 만든 open&mmap 실습 코드에서 시스템 콜 인자를 조사
• mmap
• prot로 이용할 PROT_READ | PROT_WRITE | PROT_EXEC 는 0x7로 정의되어 있음
• 인젝터의 코드에서는 length를 100이 아니라 so파일 크기로 넣을 것임
• 7888 (=0x1ED0)
• flags의 MAP_PRIVATE은 0x2로 정의되어 있음
• fd는 open 시스템콜의 반환 값을 이용
• ebx에는 addr에 해당하는 값 (0)
• ecx에는 length에 해당하는 값
• edx에는 prot에 해당하는 값 (7)
• esi에는 flags에 해당하는 값 (2)
• edi에는 fd
• ebp에는 offset에 처리한 값 (파일 시작부터 올릴 것이므로, 0으로 설정하면 됨)
• eax에는 시스템 콜 번호인 0xc0
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• Injector
• 앞의 조사를 참고하여 인젝션할 코드 작성
• open과 mmap을 호출하는 코드
• 맨 끝에 bp를 넣음
• open과 mmap을 호출한 뒤 다시 tracer에 제어를 넘김
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
• Injector
• 인젝션하는 코드
• open과 mmap을 호출한 뒤 다시 제어를 받고, 인젝션한 라이브러리 루틴을 실행할 수
있도록 EIP를 조작해 줌
• 원본 프로그램을 이어서 실행할 수 있도록 했음
• 인젝션한 코드는 다시 쓰이지 않는 start 루틴에 덮어썼다.
• start 루틴 시작 주소를 쓰면 작동을 잘 안 하여 nop을 넣고 주소를 미뤘음
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
•Injector
• 뒤에는 다시 이어하는 루틴을 넣었음
• 원본 레지스터를 복구
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP
•성공
• 이번 예제에서는 인젝션한 라이브러리에 재배치할 요소
가 없도록 했다
• open/mmap을 이용한 경우 재배치가 필요할 수 있다
PTRACE를 이용한 INJECTION – VDSO를 이용
• VDSO란?
• Virtual Dynamically linked Shared Object
• user space에 shared object 형태로 mapping 됨
• 신중하게 선택된 커널 영역 루틴들의 집합을 사용자 영역 애플리케이션으로 내보내는 리눅스 커널 매커니즘
• 시스템 콜을 호출할 수 있는 코드를 담고 있다.
• 크게 2가지 일을 함
• 적절한 system call method를 선택하는 역할
• calling overhead를 줄여주는 역할
PTRACE를 이용한 INJECTION – VDSO를 이용
• 적절한 system call method를 선택하는 역할
• legacy system call인 int 0x80의 경우 full interrupt-handling paths를 타기 때문에 overhead가 큼
• 이를 해결하기 위해 sysenter가 생김
• system call method가 2개가 되어 어떤 system call method를 선택할 지 결정하는 루틴 필요
• ->VDSO의 __kernel_vsyscall 함수에서 처리
• __kernel_vsycall
• sysenter는 VDSO에서만 사용하는 것이 원칙
• library 등에서 시스템 콜을 호출하기 위해 _dl_sysinfo 전역변수나 gs 레지스터를 이용해 __kernel_vsycall을
호출하고, 여기서 sysenter 하게 됨
• _dl_sysinfo 전역변수에는 __kernel_vsycall 의 주소가 있음
• gs 레지스터는 TCB(Thread Control Block)을 가리키고, TCB의 0x10 위치에 __kernel_vsycall의 주소가 있음
• calling overhead를 줄여주는 역할
• user mode, kernel mode를 왔다 갔다 할 때마다 context switching -> 오버헤드가 큼
• VDSO는 user space에 mapping되기 때문에, user mode에서 실행해도 상관 없는 몇몇 system call의 실제 구현
부를 VDSO에 넣으면 이 시스템 콜을 context switching 없이 처리 가능
• ->가능한 함수는 VDSO에서 처리, context switching이 필요한 함수는 VDSO의 __kernel_vsyscall 호출
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – VDSO를 이용
• VDSO를 이용하면 별도의 code injection 없이도 시스템 콜을 호출할 수 있음
• 레지스터에 적절한 인자를 넣어두고 VDSO를 이용하면 됨
• ptrace를 이용하면 이 코드가 어디에 존재하는 지 찾아낼 수 있다
• PTRACE_SYSCALL 이용
• 기본적으로 PTRACE_CONT와 같지만, 시스템 콜이 불릴 때나 시스템 콜이 끝났을 때 tracer에게 제어가 돌아옴
• 호출하려는 순간 멈춤 : 시스템 콜 인자를 확인하기 위한 용도로 쓰임
• 끝나는 순간 멈춤 : return 값을 확인하기 위한 용도로 쓰임
• 이 예에서는 write 시스템 콜을 호출해 봄
• 시스템 콜만 필요한 동작이라면 굳이 injection할 필요 없이, VDSO를 이용하기만 해도 충분
• open / mmap 을 이용하면 so injection 가능
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – VDSO를 이용
• 문자열 저장을 위해 대상 프로그램의 메모리 중 읽을 수 있는 공간을 찾음
• ptrace를 이용하여 라이브러리 이름 문자열을 저장한다
• 리틀 엔디안에 주의
• write 할 문자열을 저장할 것
PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – VDSO를 이용
• Injector
• bss 영역에 ptrace를 이용하여 문자열
저장
• VDSO를 이용하여 write 시스템 콜을
호출하여 출력
• 주의!
• 시스템 콜 번호를 설정할 때,
orig_eax에 설정해야 함
환경변수를 이용한 INJECTION • 실습 – SO injection
• 실습 – API Hooking
환경변수를 이용한 INJECTION
• LD_PRELOAD
• LD_가 붙은, ld.so에 속하는 환경변수
• Windows의 AppInit_DLLs 레지스트리와 비슷한 역할을 함
• LD_PRELOAD에 설정된 shard object는 libc를 비롯한 다른 모든 shard object보다 먼저 로딩됨
• libc(기존 C라이브러리 함수)에 있는 함수의 이름과 동일한 함수가 있다면?
• LD_PRELOAD에 적힌 라이브러리 함수를 호출해 줌
• ->자동으로 함수 후킹이 되는 효과!
환경변수를 이용한 INJECTION – 실습 – SO INJECTION
• 앞에서 만든 라이브러리 이용
• 환경변수 LD_PRELOAD에 경로를 저장
• 지속적으로 injection하기 위해서는 파일에 적어주어야 함
• .profile 등의 파일에 저장
환경변수를 이용한 INJECTION – 실습 – SO INJECTION
• 대상 프로그램 실행
• 프로그램 비트 수가 맞아야 함
• 라이브러리가 로딩되며 라이브러리의 constructor 함수가 실행 됨
환경변수를 이용한 INJECTION – 실습 – API HOOKING
• 인젝션을 이용한 API hooking
• 라이브러리 함수와 같은 이름을 이용하는 함수를 제작
• LD_PRELOAD에 써 준 라이브러리는 다른 동적 라이브러리보다 먼저 올라옴
• -> 같은 함수 이름으로 호출 시 인젝션한 라이브러리의 함수가 불림
• 원본 함수를 호출하고 싶을 시
• 동적 라이브러리를 이용하는 함수를 사용하여 직접 주소를 구해 호출
환경변수를 이용한 INJECTION – 실습 – API HOOKING
• 대상 프로그램
• write함수를 호출하는 프로그램
환경변수를 이용한 INJECTION – 실습 – API HOOKING
• 인젝션할 라이브러리
• write를 hooking하여 출력할 내용을 바꿈
• 버퍼를 조작한 뒤 원본 함수 호출
• 원본 write함수와 인자와 리턴 타입이
같도록 한다.
환경변수를 이용한 INJECTION – 실습 – API HOOKING
• 인젝션 결과
• 원본 write함수 대신 인젝션한 라이브러리의 wirte 호출
부록 • 참고 사이트
참고 사이트
• Linux 공유 라이브러리
• http://it-diary.tistory.com/3
• ptrace 사용법
• https://mikecvet.wordpress.com/2010/08/14/ptrace-tutorial/
• http://man7.org/linux/man-pages/man2/ptrace.2.html
• Linux injection(code injection/so injection) – ptrace
• http://umbum.tistory.com/123
• http://it-diary.tistory.com/9
• ptrace 권한
• http://egloos.zum.com/seoz/v/4070663
• 동적 라이브러리 이용 함수
• https://wiki.kldp.org/HOWTO/html/Program-Library-HOWTO/dl-libraries.html
참고 사이트
• __attribute__((constructor))
• https://kldp.org/node/68257
• open&mmap을 이용한 injection (ptrace)
• https://www.codeproject.com/Articles/33340/Code-Injection-into-Running-Linux-Application
• ptrace를 이용한 오픈소스 Injector
• https://github.com/gaffe23/linux-inject
• LD_PRELOAD를 이용한 injection과 hooking
• http://umbum.tistory.com/128
• http://it-diary.tistory.com/8
http://hyunmini.tistory.com/55
• http://i5on9i.blogspot.kr/2013/05/hooking-wrapper-function.html
참고 사이트
• VDSO
• http://umbum.tistory.com/61
• so 인젝션 여러 종류 총 정리
• https://backtrace.io/blog/elf-shared-library-injection-forensics/
• Linux systemcall table
• https://syscalls.kernelgrok.com/

More Related Content

Similar to Linux reversing study_basic_4

요람(CreateProcess)에서 무덤(ResumeThread)까지
요람(CreateProcess)에서 무덤(ResumeThread)까지요람(CreateProcess)에서 무덤(ResumeThread)까지
요람(CreateProcess)에서 무덤(ResumeThread)까지Hyoje Jo
 
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기Jinkyoung Kim
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본ssuser0c2478
 
뇌자T etc.windows multi threading programming
뇌자T   etc.windows multi threading programming뇌자T   etc.windows multi threading programming
뇌자T etc.windows multi threading programmingcancan21st
 
Linux reversing study_basic_3
Linux reversing study_basic_3Linux reversing study_basic_3
Linux reversing study_basic_3Jinkyoung Kim
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱jungjinwouk
 
Assembly 스터디 1
Assembly 스터디 1Assembly 스터디 1
Assembly 스터디 1Jinkyoung Kim
 
Windows reversing study_basic_1
Windows reversing study_basic_1Windows reversing study_basic_1
Windows reversing study_basic_1Jinkyoung Kim
 
Windows reversing study_basic_6
Windows reversing study_basic_6Windows reversing study_basic_6
Windows reversing study_basic_6Jinkyoung Kim
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템QooJuice
 
Pwnable study basic_2
Pwnable study basic_2Pwnable study basic_2
Pwnable study basic_2Jinkyoung Kim
 
Django로 배우는 쉽고 빠른 웹개발 study 자료
Django로 배우는 쉽고 빠른 웹개발 study 자료Django로 배우는 쉽고 빠른 웹개발 study 자료
Django로 배우는 쉽고 빠른 웹개발 study 자료Han Sung Kim
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 pptInjae Lee
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화sung ki choi
 
More Effective Python 3st (Multitask)
More Effective Python 3st (Multitask)More Effective Python 3st (Multitask)
More Effective Python 3st (Multitask)경섭 심
 
V8 engine internal
V8 engine internalV8 engine internal
V8 engine internalJinhyuck Kim
 
6. code level reversing
6. code level reversing6. code level reversing
6. code level reversingYoungjun Chang
 
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)Dong Chan Shin
 
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드GangSeok Lee
 

Similar to Linux reversing study_basic_4 (20)

요람(CreateProcess)에서 무덤(ResumeThread)까지
요람(CreateProcess)에서 무덤(ResumeThread)까지요람(CreateProcess)에서 무덤(ResumeThread)까지
요람(CreateProcess)에서 무덤(ResumeThread)까지
 
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
 
뇌자T etc.windows multi threading programming
뇌자T   etc.windows multi threading programming뇌자T   etc.windows multi threading programming
뇌자T etc.windows multi threading programming
 
Linux reversing study_basic_3
Linux reversing study_basic_3Linux reversing study_basic_3
Linux reversing study_basic_3
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱
 
Assembly 스터디 1
Assembly 스터디 1Assembly 스터디 1
Assembly 스터디 1
 
Windows reversing study_basic_1
Windows reversing study_basic_1Windows reversing study_basic_1
Windows reversing study_basic_1
 
Windows reversing study_basic_6
Windows reversing study_basic_6Windows reversing study_basic_6
Windows reversing study_basic_6
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템
 
Pwnable study basic_2
Pwnable study basic_2Pwnable study basic_2
Pwnable study basic_2
 
Django로 배우는 쉽고 빠른 웹개발 study 자료
Django로 배우는 쉽고 빠른 웹개발 study 자료Django로 배우는 쉽고 빠른 웹개발 study 자료
Django로 배우는 쉽고 빠른 웹개발 study 자료
 
Chapter7~9 ppt
Chapter7~9 pptChapter7~9 ppt
Chapter7~9 ppt
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
 
More Effective Python 3st (Multitask)
More Effective Python 3st (Multitask)More Effective Python 3st (Multitask)
More Effective Python 3st (Multitask)
 
JetsonTX2 Python
 JetsonTX2 Python  JetsonTX2 Python
JetsonTX2 Python
 
V8 engine internal
V8 engine internalV8 engine internal
V8 engine internal
 
6. code level reversing
6. code level reversing6. code level reversing
6. code level reversing
 
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
 
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
 

More from Jinkyoung Kim

Axelar 22.04 bughunting case study
Axelar 22.04 bughunting case studyAxelar 22.04 bughunting case study
Axelar 22.04 bughunting case studyJinkyoung Kim
 
Angle Protocol bughunting case study
Angle Protocol bughunting case studyAngle Protocol bughunting case study
Angle Protocol bughunting case studyJinkyoung Kim
 
Nouns DAO bughunting case study
Nouns DAO bughunting case studyNouns DAO bughunting case study
Nouns DAO bughunting case studyJinkyoung Kim
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introductionJinkyoung Kim
 
Linux reversing study_basic_2
Linux reversing study_basic_2Linux reversing study_basic_2
Linux reversing study_basic_2Jinkyoung Kim
 
Linux reversing study_basic_1
Linux reversing study_basic_1Linux reversing study_basic_1
Linux reversing study_basic_1Jinkyoung Kim
 
Windows reversing study_basic_5
Windows reversing study_basic_5Windows reversing study_basic_5
Windows reversing study_basic_5Jinkyoung Kim
 
Windows reversing study_basic_4
Windows reversing study_basic_4Windows reversing study_basic_4
Windows reversing study_basic_4Jinkyoung Kim
 
Windows reversing study_basic_3
Windows reversing study_basic_3Windows reversing study_basic_3
Windows reversing study_basic_3Jinkyoung Kim
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2Jinkyoung Kim
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2Jinkyoung Kim
 

More from Jinkyoung Kim (19)

Axelar 22.04 bughunting case study
Axelar 22.04 bughunting case studyAxelar 22.04 bughunting case study
Axelar 22.04 bughunting case study
 
Angle Protocol bughunting case study
Angle Protocol bughunting case studyAngle Protocol bughunting case study
Angle Protocol bughunting case study
 
Nouns DAO bughunting case study
Nouns DAO bughunting case studyNouns DAO bughunting case study
Nouns DAO bughunting case study
 
Web hacking introduction
Web hacking introductionWeb hacking introduction
Web hacking introduction
 
Linux reversing study_basic_2
Linux reversing study_basic_2Linux reversing study_basic_2
Linux reversing study_basic_2
 
Linux reversing study_basic_1
Linux reversing study_basic_1Linux reversing study_basic_1
Linux reversing study_basic_1
 
Python
PythonPython
Python
 
System+os study 7
System+os study 7System+os study 7
System+os study 7
 
System+os study 6
System+os study 6System+os study 6
System+os study 6
 
System+os study 5
System+os study 5System+os study 5
System+os study 5
 
System+os study 4
System+os study 4System+os study 4
System+os study 4
 
System+os study 3
System+os study 3System+os study 3
System+os study 3
 
System+os study 2
System+os study 2System+os study 2
System+os study 2
 
System+os study 1
System+os study 1System+os study 1
System+os study 1
 
Windows reversing study_basic_5
Windows reversing study_basic_5Windows reversing study_basic_5
Windows reversing study_basic_5
 
Windows reversing study_basic_4
Windows reversing study_basic_4Windows reversing study_basic_4
Windows reversing study_basic_4
 
Windows reversing study_basic_3
Windows reversing study_basic_3Windows reversing study_basic_3
Windows reversing study_basic_3
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2
 
Assembly 스터디 2
Assembly 스터디 2Assembly 스터디 2
Assembly 스터디 2
 

Linux reversing study_basic_4

  • 1. LINUX REVERSING BASIC #4 Injection
  • 2. 목차 • Injection • ptrace를 이용한 Injection • 실습 – ptrace 사용법 • 실습 – Code injection • Injector • 실습 – SO injection • Shared library • Injector • dlopen • open & mmap • 환경변수를 이용한 Injection • 실습 – SO injection • 실습 – API Hooking • 부록 • 참고 사이트
  • 3. PTRACE를 이용한 INJECTION • 실습 – ptrace 사용법 • 실습 – Code injection • 실습 – SO injection
  • 4. PTRACE를 이용한 INJECTION • 리눅스는 윈도우에서 DLL injection에 이용했던 CreateRemoteThread와 같은 API가 없음 • 대신 ptrace 함수 이용 • ptrace • process trace의 약자 • 프로세스의 상태를 조사하고 조작할 수 있게 하여, 한 프로세스가 다른 프로세스를 제어할 수 있도록 하 는 시스템 콜 • 디버거, strace와 ltrace 등의 프로그램이 주로 이용 • 파일 디스크립터, 메모리, 레지스터 등을 조작할 수 있고, 코드를 싱글스텝하고 시스템 호출과 그 결과를 가로채며 대상의 시그널 핸들러와 시그널을 조작할 수 있다. • ->강력한 능력이 있으므로, 오직 소유자가 시그널을 보낼 수 있는 프로세스들만 attach할 수 있음(일반 적으로 자신의 프로세스들) • (최신 리눅스에는 ptrace protection이 적용되어 있음)
  • 5. PTRACE를 이용한 INJECTION • ptrace • 인자 • request • ptrace를 이용해 하고자 하는 작업 • pid • 대상 프로세스 id • addr • request에 따라 무시되거나 이용 됨 • data • request에 따라 무시되거나 이용 됨
  • 6. PTRACE를 이용한 INJECTION – 실습 • 대상 프로그램 • 종료하기 전까지는 꺼지지 않는 프로그램을 제작 • 이 프로그램에 injection을 할 것임 • 일단 32bit로 컴파일
  • 7. PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법 •ptrace 함수(시스템 콜)를 이용해본다. • ptrace는 인자로 넣은 요구에 따라 여러가지 일을 해 준다. • ptrace로 할 수 있는 일 을 몇 가지 정리했음 명령 설명 비고 PTRACE_ATTACH 프로세스 추적을 위해 대상 프로세스에 대한 부모 프로세스가 됨 일반적으로 자식 프로세스만 attach 가능 (OS 설정 따라 다름) non-child를 attach하려면 root 권한 필요 attach된 프로세스는 stop됨 PTRACE_TRACEME 자식 측에서 호출해야 함. 부모가 trace할 수 있도록 함. SIGKILL 이외의 다른 signal을 받으면 부모프로세스에게 SIGTRAP을 걸어 전달 부모 프로세스가 준비되기 전 에 호출하면 안 됨 PTRACE_DETATCH PTRACE_ATTACH로 붙은 프로세스를 분리 PTRACE_POKEDATA PTRACE_POKETEXT 대상 프로세스 메모리에 기록 (워드 단위) 워드 크기는 OS마다 다름 PTRACE_PEEKDATA PTRACE_PEEKTEXT 대상 프로세스 메모리에서 읽어서 내용 반환 (워드 단위) 워드 크기는 OS마다 다름 PTRACE_GETREGS PTRACE_GETFPREGS 대상 프로세스의 레지스터 값을 읽음. 위는 general 레지스터, 아래는 부동소수점 레지스터 PTRACE_SETREGS PTRACE_SETFPREGS 대상 프로세스의 레지스터에 값을 씀. 위는 general 레지스터, 아래는 부동소수섬 레지스터 PTRACE_CONT 정지 상태에 있는 대상 프로세스를 계속 실행하도록 함 PTRACE_SINGLESTEP 대상 프로세스가 하나의 기계어를 실행한 뒤 멈춤 PTRACE_KILL 대상 프로세스에 SIGKILL을 보내 종료하도록 함
  • 8. PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법 • ptrace • 프로세스 attach 하기 • 실행중인 프로그램에 대해 trace할 수 있 도록 attach 한다. • register 값 얻기 • 프로세스의 register 값을 가져온다 • data 인자에 레지스터 값을 저장할 버퍼 주소를 넣어주어야 한다. • 프로세스 detach 하기 • attach했던 프로세스를 detach 한다.
  • 9. PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법 • ptrace 실습 • 컴파일은 32비트로 한다. • 레지스터 값을 가져오는 ptrace의 data 인자로 버퍼 주소를 넣는다 • 데이터는 sys/user.h 에 정의된 구조체인 user_regs_struct 포맷이다.
  • 10. PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법 • ptrace • 대상 프로세스 register에 쓰기 • data에 적어준 주소에 있는 구조체(앞에서 언급)에 있는 값으로 레지스터 값 설정 • 실습 • 컴파일은 32비트로 한다. • 구조체에 값을 설정하고, ptrace의 PTRACE_SETREGS • data 인자로 버퍼 구조체 주소를 넣는다
  • 11. PTRACE를 이용한 INJECTION – 실습 – PTRACE 사용법 • ptrace • 대상 프로세스 메모리 읽기 • 인자에 넣은 addr를 시작으로 워드 크기만 큼 읽는다. • 32비트의 워드는 보통 4바이트, 64비트의 워드는 8바이트 • 대상 프로세스 메모리에 쓰기 • 인자에 넣은 addr부터 data에 넣은 값을 쓴다. • 워드 단위로 쓴다.
  • 12. PTRACE를 이용한 INJECTION – 실습 – CODE INJECTION • code injection • 직접 코드를 끼워 넣음 • 기계어를 메모리에 쓰고, EIP를 조작하여 실행 • (기존 프로그램을 이어서 하기를 원한다면 레지스터 값을 백업해두고, dlopen 호출하기 전에 레지스터 값 을 백업해두고, bp를 걸어 둔 뒤 다시 복원하면 됨) • 여기까진 안 하겠음 • 예에서는 그냥 코드 영역에 덮어 썼음 • EIP를 조작할 필요 없었음 • 새로 실행권한이 있는 메모리를 할당하고 이용하거나, 스택에 저장 후 mprotect 함수를 이용하여 실행 권 한을 줘도 됨
  • 13. PTRACE를 이용한 INJECTION – 실습 – CODE INJECTION – INJECTOR • code injection • 왼쪽은 끼워 넣을 코드 • 예전에 작성했던 셸 코드를 이용했음 • 오른쪽은 인젝션하는 코드 • eip 바로 뒤에 코드를 넣었음 • ptrace는 워드 단위로 복사한다 는 점에 주의
  • 14. PTRACE를 이용한 INJECTION – 실습 – CODE INJECTION – INJECTOR • 인젝션된 모습 • 다음엔 기존 프로그램의 코드를 망치지 않고, 다른 영역에 코드를 인젝션하여 실행하고, 다시 기존 코드로 돌아오도록 해보자
  • 15. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION • so injection • 기본적으로 Code injection과 비슷함 • dlopen 함수를 호출하는 코드를 injection하여 so injection • dlopen은 Windows의 LoadLibrary에 해당하는 함수 • 인젝션 한 라이브러리에 __attribute__((constructor)) 를 붙인 함수가 있다면 dlopen이 반환하기 전에 실행 됨 • DllMain과 비슷한 역할 • __attribute__((constructor)) 는 gcc 지시자이다 • 참고로, __attribute__((destructor)) 를 붙이면 main이 끝난 뒤 호출된다. • (기존 프로그램을 이어서 하기를 원한다면 레지스터 값을 백업해두고, dlopen 호출하기 전에 레지스터 값을 백업해 두고, bp를 걸어 둔 뒤 다시 복원하면 됨) • 여기까진 안 하겠음
  • 16. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – SHARED LIBRARY • injection할 라이브러리 제작 • -fPIC : position-independent code로 컴파일 됨 • 올라오는 주소가 랜덤해도 상관없는 코드 • -shared : 공유 라이브러리이므로, 공유 되도록 함
  • 17. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – SHARED LIBRARY • injection할 라이브러리 테스트 • 동적 라이브러리를 로드하는 코드 • LoadLibrary를 호출한 것과 같음 • -ldl • libdl.so를 링킹
  • 18. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR • Injector • dlopen 함수는 libdl.so 라이브러리에 있는 함수이다 • 인젝션된 코드에서 dlopen을 호출하기 위해서는 대상 프로세스가 libdl.so를 로드해야 한다. • LoadLibrary를 호출하기 위해 kernel32.dll이 올라와 있어야 한다는 것과 비슷한 맥락 • 따라서, dlopen을 이용한 방법에는 제약이 있다. • dlopen 대신에 open 시스템 콜과 mmap 시스템 콜을 이용할 수 있음 • -> 직접 .so 파일을 열고, 메모리를 할당하여 올린다. • 첫 번째 injector 실습은 dlopen을 이용 • ->대상 프로세스에 dlopen을 이용하는 코드를 넣을 것
  • 19. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – DLOPEN • 대상 프로그램 수정 • dlopen을 plt, got에 잡아 주기 위해 호출했다.
  • 20. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – DLOPEN • Injector • dlopen 함수 • 라이브러리가 잘 작동하는지 체크하기 위해 이용했던 코드에 서 dlopen 인자가 어떻게 넘어가는지 확인 • RTLD_NOW는 1로 정의되어 있음 • 이를 참고하여 인라인 어셈블리로 코드를 작성한다. • PLT를 이용하여 dlopen을 호출하도록 할 것이므로, PLT를 알아 낸다. • 0x8048410
  • 21. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – DLOPEN • Injector • 앞에서 얻은 정보를 이용하여 dlopen을 호출하는 코드를 어셈 블리로 씀 • 이 코드를 injection하여 대상 프 로세스가 dlopen 함수를 호출하 도록 함 • exit을 넣어서 종료되도록 했음
  • 22. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – DLOPEN • 인젝션된 모습 • 다음엔 기존 프로그램의 코드를 망치지 않고, 다른 영역에 코드를 인젝션하여 실행하고, 다시 기존 코드로 돌아오도 록 해보자
  • 23. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • 특정 라이브러리가 필요한 dlopen은 제약이 있음 • open과 mmap 시스템콜을 이용하여 대신할 수 있다. • 직접 라이브러리 파일을 열고, 그 내용을 메모리에 올려준다. • 계획 • open으로 라이브러리 파일을 연다. • mmap으로 메모리에 올린다. • EIP를 옮겨 코드를 실행한다. • 라이브러리가 올라온 주소에 맞게 relocation이 필요 • dlopen은 동적 라이브러리를 올리는 함수로, relocation 작업까지 포함하여 해준다. • 이번에는 직접 파일을 열어 올리므로 relocation 작업을 직접 해주어야 한다. • ->재배열이 싫다면 PIC로 컴파일하면 된다. 위치 독립적 코드로, relocation이 필요하지 않음.
  • 24. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • mmap • fd로 지정된 파일에서 offset을 시작으로 length바이트 만큼을 addr주소로 대응시키도록 한다. • addr를 시작주소로, 파일 내용을 메모리에 올림 • addr는 단지 그 주소를 사용했으면 좋겠다 정도로, 무조건 해당 주소를 이용할 수 있는 것은 아님 • 보통 0을 지정한다. OS가 알아서 올려 줌 • prot은 원하는 메모리 보호 모드이다. bit OR로 설정. • 반환 값 • 실제로 메모리에 올라온 시작 주소를 반환 • 아래 있는 munmap은 반대로 메모리를 해제하는 일을 한다.
  • 25. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • open&mmap 실습 • 함수 사용법을 익히고, 인젝터에 필요 한 어셈블리어를 얻기 위해 간단한 예 제 프로그램을 작성해 본다.
  • 26. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • 대상 프로그램 • 다시 dlopen코드를 뺌 • 인젝션 할 라이브러리 • 기존 코드 그대로 사용 • 단, PIC로 컴파일 해야 함(앞에서 PIC로 컴파일 했다)
  • 27. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • 인젝션 할 라이브러리 • relocation이 필요하다. • ->이 예에서는 relocation이 없어도 가능하도록 인라인 어셈블리로 코딩했음 • 문자열을 write하는 코드의 라이브러리
  • 28. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • Injector • 앞서 만든 open&mmap 실습 코드에서 시스템 콜 인자를 조사 • open • flag로 이용할 O_RDWR는 2로 정의되어 있음 • 사실 open은 int open (const char *FILENAME, int FLAGS[, mode_t MODE]) 형태 • 뒤의 mode_t는 O_CREAT 옵션을 이용 할 시 필요 • O_CREAT가 아닐 경우 인자를 2개만 쓸 수 있음(오버로딩) • edx에는 mode에 해당하는 값(2개만 쓸 경우 무시됨. 쓰레기 값을 넣으면 됨) • ecx에는 flags에 해당하는 값 (2) • ebx에는 파일 이름 문자열 주소 • eax에는 시스템 콜 번호인 5
  • 29. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • Injector • 앞서 만든 open&mmap 실습 코드에서 시스템 콜 인자를 조사 • mmap • prot로 이용할 PROT_READ | PROT_WRITE | PROT_EXEC 는 0x7로 정의되어 있음 • 인젝터의 코드에서는 length를 100이 아니라 so파일 크기로 넣을 것임 • 7888 (=0x1ED0) • flags의 MAP_PRIVATE은 0x2로 정의되어 있음 • fd는 open 시스템콜의 반환 값을 이용 • ebx에는 addr에 해당하는 값 (0) • ecx에는 length에 해당하는 값 • edx에는 prot에 해당하는 값 (7) • esi에는 flags에 해당하는 값 (2) • edi에는 fd • ebp에는 offset에 처리한 값 (파일 시작부터 올릴 것이므로, 0으로 설정하면 됨) • eax에는 시스템 콜 번호인 0xc0
  • 30. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • Injector • 앞의 조사를 참고하여 인젝션할 코드 작성 • open과 mmap을 호출하는 코드 • 맨 끝에 bp를 넣음 • open과 mmap을 호출한 뒤 다시 tracer에 제어를 넘김
  • 31. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP • Injector • 인젝션하는 코드 • open과 mmap을 호출한 뒤 다시 제어를 받고, 인젝션한 라이브러리 루틴을 실행할 수 있도록 EIP를 조작해 줌 • 원본 프로그램을 이어서 실행할 수 있도록 했음 • 인젝션한 코드는 다시 쓰이지 않는 start 루틴에 덮어썼다. • start 루틴 시작 주소를 쓰면 작동을 잘 안 하여 nop을 넣고 주소를 미뤘음
  • 32. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP •Injector • 뒤에는 다시 이어하는 루틴을 넣었음 • 원본 레지스터를 복구
  • 33. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – INJECTOR – OPEN&MMAP •성공 • 이번 예제에서는 인젝션한 라이브러리에 재배치할 요소 가 없도록 했다 • open/mmap을 이용한 경우 재배치가 필요할 수 있다
  • 34. PTRACE를 이용한 INJECTION – VDSO를 이용 • VDSO란? • Virtual Dynamically linked Shared Object • user space에 shared object 형태로 mapping 됨 • 신중하게 선택된 커널 영역 루틴들의 집합을 사용자 영역 애플리케이션으로 내보내는 리눅스 커널 매커니즘 • 시스템 콜을 호출할 수 있는 코드를 담고 있다. • 크게 2가지 일을 함 • 적절한 system call method를 선택하는 역할 • calling overhead를 줄여주는 역할
  • 35. PTRACE를 이용한 INJECTION – VDSO를 이용 • 적절한 system call method를 선택하는 역할 • legacy system call인 int 0x80의 경우 full interrupt-handling paths를 타기 때문에 overhead가 큼 • 이를 해결하기 위해 sysenter가 생김 • system call method가 2개가 되어 어떤 system call method를 선택할 지 결정하는 루틴 필요 • ->VDSO의 __kernel_vsyscall 함수에서 처리 • __kernel_vsycall • sysenter는 VDSO에서만 사용하는 것이 원칙 • library 등에서 시스템 콜을 호출하기 위해 _dl_sysinfo 전역변수나 gs 레지스터를 이용해 __kernel_vsycall을 호출하고, 여기서 sysenter 하게 됨 • _dl_sysinfo 전역변수에는 __kernel_vsycall 의 주소가 있음 • gs 레지스터는 TCB(Thread Control Block)을 가리키고, TCB의 0x10 위치에 __kernel_vsycall의 주소가 있음 • calling overhead를 줄여주는 역할 • user mode, kernel mode를 왔다 갔다 할 때마다 context switching -> 오버헤드가 큼 • VDSO는 user space에 mapping되기 때문에, user mode에서 실행해도 상관 없는 몇몇 system call의 실제 구현 부를 VDSO에 넣으면 이 시스템 콜을 context switching 없이 처리 가능 • ->가능한 함수는 VDSO에서 처리, context switching이 필요한 함수는 VDSO의 __kernel_vsyscall 호출
  • 36. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – VDSO를 이용 • VDSO를 이용하면 별도의 code injection 없이도 시스템 콜을 호출할 수 있음 • 레지스터에 적절한 인자를 넣어두고 VDSO를 이용하면 됨 • ptrace를 이용하면 이 코드가 어디에 존재하는 지 찾아낼 수 있다 • PTRACE_SYSCALL 이용 • 기본적으로 PTRACE_CONT와 같지만, 시스템 콜이 불릴 때나 시스템 콜이 끝났을 때 tracer에게 제어가 돌아옴 • 호출하려는 순간 멈춤 : 시스템 콜 인자를 확인하기 위한 용도로 쓰임 • 끝나는 순간 멈춤 : return 값을 확인하기 위한 용도로 쓰임 • 이 예에서는 write 시스템 콜을 호출해 봄 • 시스템 콜만 필요한 동작이라면 굳이 injection할 필요 없이, VDSO를 이용하기만 해도 충분 • open / mmap 을 이용하면 so injection 가능
  • 37. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – VDSO를 이용 • 문자열 저장을 위해 대상 프로그램의 메모리 중 읽을 수 있는 공간을 찾음 • ptrace를 이용하여 라이브러리 이름 문자열을 저장한다 • 리틀 엔디안에 주의 • write 할 문자열을 저장할 것
  • 38. PTRACE를 이용한 INJECTION – 실습 – SO INJECTION – VDSO를 이용 • Injector • bss 영역에 ptrace를 이용하여 문자열 저장 • VDSO를 이용하여 write 시스템 콜을 호출하여 출력 • 주의! • 시스템 콜 번호를 설정할 때, orig_eax에 설정해야 함
  • 39. 환경변수를 이용한 INJECTION • 실습 – SO injection • 실습 – API Hooking
  • 40. 환경변수를 이용한 INJECTION • LD_PRELOAD • LD_가 붙은, ld.so에 속하는 환경변수 • Windows의 AppInit_DLLs 레지스트리와 비슷한 역할을 함 • LD_PRELOAD에 설정된 shard object는 libc를 비롯한 다른 모든 shard object보다 먼저 로딩됨 • libc(기존 C라이브러리 함수)에 있는 함수의 이름과 동일한 함수가 있다면? • LD_PRELOAD에 적힌 라이브러리 함수를 호출해 줌 • ->자동으로 함수 후킹이 되는 효과!
  • 41. 환경변수를 이용한 INJECTION – 실습 – SO INJECTION • 앞에서 만든 라이브러리 이용 • 환경변수 LD_PRELOAD에 경로를 저장 • 지속적으로 injection하기 위해서는 파일에 적어주어야 함 • .profile 등의 파일에 저장
  • 42. 환경변수를 이용한 INJECTION – 실습 – SO INJECTION • 대상 프로그램 실행 • 프로그램 비트 수가 맞아야 함 • 라이브러리가 로딩되며 라이브러리의 constructor 함수가 실행 됨
  • 43. 환경변수를 이용한 INJECTION – 실습 – API HOOKING • 인젝션을 이용한 API hooking • 라이브러리 함수와 같은 이름을 이용하는 함수를 제작 • LD_PRELOAD에 써 준 라이브러리는 다른 동적 라이브러리보다 먼저 올라옴 • -> 같은 함수 이름으로 호출 시 인젝션한 라이브러리의 함수가 불림 • 원본 함수를 호출하고 싶을 시 • 동적 라이브러리를 이용하는 함수를 사용하여 직접 주소를 구해 호출
  • 44. 환경변수를 이용한 INJECTION – 실습 – API HOOKING • 대상 프로그램 • write함수를 호출하는 프로그램
  • 45. 환경변수를 이용한 INJECTION – 실습 – API HOOKING • 인젝션할 라이브러리 • write를 hooking하여 출력할 내용을 바꿈 • 버퍼를 조작한 뒤 원본 함수 호출 • 원본 write함수와 인자와 리턴 타입이 같도록 한다.
  • 46. 환경변수를 이용한 INJECTION – 실습 – API HOOKING • 인젝션 결과 • 원본 write함수 대신 인젝션한 라이브러리의 wirte 호출
  • 47. 부록 • 참고 사이트
  • 48. 참고 사이트 • Linux 공유 라이브러리 • http://it-diary.tistory.com/3 • ptrace 사용법 • https://mikecvet.wordpress.com/2010/08/14/ptrace-tutorial/ • http://man7.org/linux/man-pages/man2/ptrace.2.html • Linux injection(code injection/so injection) – ptrace • http://umbum.tistory.com/123 • http://it-diary.tistory.com/9 • ptrace 권한 • http://egloos.zum.com/seoz/v/4070663 • 동적 라이브러리 이용 함수 • https://wiki.kldp.org/HOWTO/html/Program-Library-HOWTO/dl-libraries.html
  • 49. 참고 사이트 • __attribute__((constructor)) • https://kldp.org/node/68257 • open&mmap을 이용한 injection (ptrace) • https://www.codeproject.com/Articles/33340/Code-Injection-into-Running-Linux-Application • ptrace를 이용한 오픈소스 Injector • https://github.com/gaffe23/linux-inject • LD_PRELOAD를 이용한 injection과 hooking • http://umbum.tistory.com/128 • http://it-diary.tistory.com/8 http://hyunmini.tistory.com/55 • http://i5on9i.blogspot.kr/2013/05/hooking-wrapper-function.html
  • 50. 참고 사이트 • VDSO • http://umbum.tistory.com/61 • so 인젝션 여러 종류 총 정리 • https://backtrace.io/blog/elf-shared-library-injection-forensics/ • Linux systemcall table • https://syscalls.kernelgrok.com/