01.SROP(Sigreturn-oriented programming) - x86
signal은 프로세스에게 이벤트가 발생했음을 알린다.
signal은 다른 프로세스에게 시그널을 전송 할 수 있다.
signal은 일반적으로 커널이 송신하며, 다음과 같은 이벤트 종류가 있다.
하드웨어 예외가 발생한 경우
사용자가 시그널을 발생시키는 터미널 특수 문자 중 하나를 입력한 경우
Interrupt character(Control + c)
sigreturn() : Kernel Mode stack에 hardware context를 복사하고, User Mode stack의 원래의 content를 저장한다.
Source code
다음과 같이 프로그램을 실행 후 "Ctrl + C"를 눌러서 Interrupt 신호를 발생시킨다.
다음과 같이 0번째 Frame에서 Stack에 저장된 각 각의 레지스터 값을 확인 할 수 있다.
다음과 같이 1번째 Frame의 내용을 보면 __kernel_sigreturn() 함수에서 에서 sys_sigreturn() 시스템 함수 호출한다.
다음과 같이 signal에 대한 처리가 끝난 후에 Frame 0의 Stack에 저장된 값이 레지스터에 저장된 것을 확인 할 수 있다.
즉, ROP와 같이 값을 레지스터에 저장할 수 있는 Gadget이 없어도 sigreturn() 함수를 이용해 각 레지스터에 원하는 값을 저장할 수 있다.
stack에 저장된 레지스터 값들은 restore_sigcontext()함수의 인자값 &frame->sc에 의해 전달된다.
즉, SROP 를 이용할 때 Stack에 다음과 같은 형태로 값을 저장해야 한다.
다음과 같이 Overflow를 확인할 수 있다.
Return address - buf 변수의 시작 주소 = 66
Exploit 순서
sigreturn()함수를 이용해 레지스터에 필요한 값을 저장
sigreturn()
int 0x80
확인해야 할 정보 목록
"/bin/sh"명령가 저장된 영역
Gadgets
int 0x80
다음과 같이 __kernel_sigreturn() 함수를 Exploit에 사용할 수 있다.
0xf7fd7ff1 주소를 사용할 경우 "mov eax,0x77" 명령어가 실행되기 때문에 0xf7fd7ff1 호출 뒤에 sigcontext 구조체가 저장되어야 합니다.
32bit이기 때문에 sigreturn() 함수를 vdso 영역에서 확인 할 수 있다.
SROP의 Exploit code를 작성할 때 중요한 부분이 있다.
sigcontext 구조체 형태로 stack에 값을 저장할 때 최소한 CS, SS레지스터에 대한 값을 설정해야한다.
Linux kernel에는 4개의 세그먼트만 존재한다.
이외의 값을 저장하게 되면 에러가 발생하게된다.
purpose | Segment(32bit) | Segment(64bit-32bit) |
Kernel Code | 0x60 | 0x8 |
Kernel Data/Stack | 0x68 | 0x18 |
User Code | 0x73 | 0x23 |
User Data/Stack | 0x7b | 0x2b |
REF : https://www.lazenca.net/display/TEC/01.SROP%28Sigreturn-oriented+programming%29+-+x86
01.SROP(Sigreturn-oriented programming) - x86 - TechNote - Lazenca.0x0
Excuse the ads! We need some help to keep our site up. List SROP(Sigreturn-oriented programming) SROP는 sigreturn 시스템 콜을 이용하여 레지스터에 원하는 값을 저장할 수 있습니다.해당 기법을 이용하여 원하는 시스템
www.lazenca.net
02.SROP(Sigreturn-oriented programming) - x64 (0) | 2020.07.05 |
---|
댓글 영역