공부 내용

2017. 10. 23. 01:520x04 pwnable

728x90

위치 독립 코드 (Position Independent Code) 또는 PIE(Position Independent Executable)

: 메모리 어딘가에 위치한 기계어 명령

: "절대주소"와 관계없이 적절히 실행되는 코드 


RIP (32BIT에서는 EIP)

즉, 다음에 실행 될 주소를 담고 있는 레지스터 

IP : Instruction Pointer 


프로그램을 컴파일 할 때는 static compile과 dynamic compile이 있다.

기본적으로 default는 dynamic compile 이고, gcc에서 static compile을 하기 위해서는 -static 옵션을 부여해야 한다.


dynamic compile은 동적라이브러리 링크에서 적용되는 컴파일 기법이다.

동적라이브러리는 정적라이브러리와 다른점이 있다.

그 다른점은 프로그램 내부에 고정되어 있는 것이 아니라, 어떠한 프로그램에서 필요할 때 마다 호출하여 사용할 수 있는 기능을 지니고 있다.


이때, 알아야 하는 개념은 두가지이다.

하나는 plt 또 하나는 got이다.

plt는 procedure linkage table

got는 global offset table의 약어이다.


plt는 외부 라이브러리를 사용할 수 있게 해주는 테이블이다.

plt를 통해 외부 라이브러리에 있는 프로시저를 호출할 수 있다.


dynamic compile은 호출 횟수에 따라 동작하는 것이 조금 다르다.


첫 번째 호출 :

함수를 호출 == PLT를 호출 하게 되면, GOT로 점프하게 되는데 GOT에는 사용자가 원하는 함수의 실제 주소가 쓰여있다. 하지만, GOT는 함수의 주소를 가지고 있지 않고 dynamic_link함수(이 부분은 정확한 명칭이 무엇인지 기억이 잘 나지 않는다)

dll_runtime_resolve를 통해 주소를 알아내게 된다. 

첫 번째 호출은 plt+6으로 점프하여 got를 매핑하는 과정이라고도 한다.


두 번째 호출을 하게 되면, 이미 dll_runtime_resolve를 통해 주소를 알아냈기 때문에

바로 점프할 수 있게 된다.


plt, got를 사용하는 이유는 빠른 프로그램 실행을 위해서라고 한다.

만약에, 프로그램이 실행될 때 사용되지 않는 것 포함하여, 모든 프로시저 심볼을 해석 -> 그 모든 주소를 GOT에 넣고 이러한 과정을 계속하게 되면, 프로그램은 실행시간이 길어지게 될 것이다.


프로그램의 시간을 최대한 단축시키기 위해서 PLT, GOT를 이용하여 필요한 프로시져의 심볼을 해석하여 접근하는 방법을 택하게 된 것이다.


그리고 이런 해석 방법은 "Lazy Binding"이라고 칭한다고 한다.


got overwrite 기법을 이용해서 특정 권한을 얻는 (pwn) 유형의 문제가 있다고 한다.

2번째 호출 시 dll_runtime_resolve를 거치지 않고, 이미 특정 함수의 주소를 알고 있는 상태이다. 그렇다면, 그 주소만 살짝쿵 바꾸어서 다른 함수를 호출할 수 있게 되는 것이다. 


제대로 이해하고 있는걸까... 


url : https://www.tortall.net/projects/yasm/manual/html/objfmt-elf64.html

10.1. elf64 Special Symbols and WRT (elf64에는 특별한 심볼이 있고, WRT가 있다)

---> EL464에서 사용되는 특별한 상징들에 대해 설명해보고자 한다.


The primary difference between elf32 and elf64 (other than 64-bit support in general) is the differences in shared library handling and position-independent code. 

ELF32와 ELF64의 주요한 차이는 무엇일까? 

일반적으로 64비트에서 ELF64는 지원된다. 둘의 차이점은 공유라이브러리의(동적라이브러리) 핸들링과 위치 독립코드(PIC)입니다.


As BITS 64 enables the use of RIP-relative addressing, most variable accesses can be relative to RIP, 

allowing easy relocation of the shared library to a different memory address.

64비트는 RIP(Rapid Instruction Pointer) 상대 주소에 사용이 가능하다.

대부분의 가변적인 접근은 rip와 관련될 수 있다.

다른 메모리 주소에 공유 라이브러리 주소를 재배치하는 것이 쉬워진다.


While RIP-relative addressing is available, it does not handle all possible variable access modes, 

so special symbols are still required, as in elf32. 

RIP 상대주소 지정을 사용할 수는 있지만, 가능한 모든 가변 액세스 모드를 처리하지는 못한다. (그렇단다..)


And as with elf32, the elf64 output format / makes use of WRT for utilizing the PIC-specific relocation types.

as with : ~와 마찬가지로 

utilizing : 활용

for : ~하기 위해 

WRT = With Respect To : ~와 관련하여 

그리고 elf32와 마찬가지로 elf64 출력형식은  PIC 특정 재배치 타입에 관련되어 사용된다.

// 그리고 

(WRT) :뭐 이런 약어가 다있노,,,,,,,,,, 복습 With Respect To : ~와 관련하여 


elf64 defines four special symbols which you can use as the right-hand side of the WRT operator to obtain PIC relocation types. They are ..gotpcrel, ..got, ..plt and ..sym. 

elf64는 4개의 특별한 심볼로 정의된다. 당신은 gotpcrel, ..got, ..plt 그리고 ..sym애 관련하여 pic 재배치를 획득할 수 있다. 


Their functions are summarized here:

다음의 기능들은 하기에 요약해두었다.


..gotpcrel

While RIP-relative addressing allows you to encode an instruction pointer relative data reference to foo with [rel foo], 


it’s sometimes necessary to encode a 

RIP-relative reference to a linker-generated symbol pointer for symbol foo; 

this is done using wrt ..gotpcrel, 

e.g. [rel foo wrt ..gotpcrel]. 




Unlike in elf32, this relocation, combined with RIP-relative addressing, 

elf32와 다르게 이 재배치는 RIP 상대 주소와 결합된다. 당연히 elf32는 eip와 결합되니까 그렇겠지 뭐.

makes it possible to load an address from the ((global offset table)) using a single instruction. Note that since RIP-relative references are limited to a signed 32-bit displacement, 

the GOT size accessible through this method is limited to 2 GB.

..gotpcrel은 


..got

As in elf32, referring to an external or global symbol using wrt ..got causes the linker to build an entry in the GOT containing the address of the symbol, and the reference gives the distance from the beginning of the GOT to the entry; so you can add on the address of the GOT, load from the resulting address, and end up with the address of the symbol.


..plt

As in elf32, referring to a procedure name using wrt ..plt causes the linker to build a procedure linkage table entry for the symbol, and the reference gives the address of the PLT entry. You can only use this in contexts which would generate a PC-relative relocation normally (i.e. as the destination for CALL or JMP), since ELF contains no relocation type to refer to PLT entries absolutely.

..sym


As in elf32, referring to a symbol name using wrt ..sym causes Yasm to write an ordinary relocation, but instead of making the relocation relative to the start of the section and then adding on the offset to the symbol, it will write a relocation record aimed directly at the symbol in question. The distinction is a necessary one due to a peculiarity of the dynamic linker.


'0x04 pwnable' 카테고리의 다른 글

rtl 공부  (0) 2017.11.27
Main HEAP and Thread HEAP  (0) 2017.10.30
Lord of Bof 2번 문제  (0) 2017.07.07
overflow_example  (0) 2017.07.06
Lord Of BOF 1번 문제  (0) 2017.05.12