S
S
Stanislav Timoshko2020-11-28 22:42:00
linux
Stanislav Timoshko, 2020-11-28 22:42:00

Why does the program catch SIGSEGV on push instructions?

A simple x86_64 shellcode was written:

BITS 64
xor rax, rax
push rax
push 0x68732f6e
push 0x69622f2f
mov rbx, rsp
push rax
mov rdx, rsp
push rbx
mov rcx, rsp
mov al, 221
int 0x80

Through a buffer overflow, the shellcode got executed by the processor. Everything goes well until the 3rd instruction from the end (push rbx) is executed. Then the program catches SIGSEGV and never reaches the coveted interrupt - int 0x80. I thought maybe the stack was overflowing, I inserted several pop instructions at the beginning of the shellcode. As a result, SIGSEGV changed to SIGILL on the same instruction - push rbx. There are no ideas at all.
gdb:
=> 0x7fffffffea72:	mov    rdx,rsp
   0x7fffffffea75:	push   rbx
   0x7fffffffea76:	mov    rcx,rsp
   0x7fffffffea79:	mov    al,0xdd
   0x7fffffffea7b:	int    0x80
   0x7fffffffea7d:	(bad)  
   0x7fffffffea7e:	(bad)  
   0x7fffffffea7f:	inc    DWORD PTR [rax]
-----------------------------------------------------------------------------------------------------------------------------
0x00007fffffffea72 in ?? ()
gdb$ n
-----------------------------------------------------------------------------------------------------------------------[regs]
  RAX: 0x0000000000000000  RBX: 0x00007FFFFFFFEA88  RBP: 0xFFFFFFFFFFFFFFFF  RSP: 0x00007FFFFFFFEA80  o d I t s Z a P c 
  RDI: 0x00007FFFFFFFEA60  RSI: 0x0000555555556021  RDX: 0x00007FFFFFFFEA80  RCX: 0x60FFFFFFFFFFFFFF  RIP: 0x00007FFFFFFFEA75
  R8 : 0x0000000000000000  R9 : 0x00007FFFF7FE14C0  R10: 0xFFFFFFFFFFFFF8F5  R11: 0x00007FFFF7E54B60  R12: 0x0000555555555060
  R13: 0x0000000000000000  R14: 0x0000000000000000  R15: 0x0000000000000000
  CS: 0033  DS: 0000  ES: 0000  FS: 0000  GS: 0000  SS: 002B				
-----------------------------------------------------------------------------------------------------------------------[code]
=> 0x7fffffffea75:	push   rbx
   0x7fffffffea76:	mov    rcx,rsp
   0x7fffffffea79:	mov    al,0xdd
   0x7fffffffea7b:	int    0x80
   0x7fffffffea7d:	(bad)  
   0x7fffffffea7e:	(bad)  
   0x7fffffffea7f:	inc    DWORD PTR [rax]
   0x7fffffffea81:	add    BYTE PTR [rax],al
-----------------------------------------------------------------------------------------------------------------------------
0x00007fffffffea75 in ?? ()
gdb$ n

Program received signal SIGSEGV, Segmentation fault.
-----------------------------------------------------------------------------------------------------------------------[regs]
  RAX: 0x0000000000000000  RBX: 0x00007FFFFFFFEA88  RBP: 0xFFFFFFFFFFFFFFFF  RSP: 0x00007FFFFFFFEA78  o d I t s Z a P c 
  RDI: 0x00007FFFFFFFEA60  RSI: 0x0000555555556021  RDX: 0x00007FFFFFFFEA80  RCX: 0x60FFFFFFFFFFFFFF  RIP: 0x00007FFFFFFFEA76
  R8 : 0x0000000000000000  R9 : 0x00007FFFF7FE14C0  R10: 0xFFFFFFFFFFFFF8F5  R11: 0x00007FFFF7E54B60  R12: 0x0000555555555060
  R13: 0x0000000000000000  R14: 0x0000000000000000  R15: 0x0000000000000000
  CS: 0033  DS: 0000  ES: 0000  FS: 0000  GS: 0000  SS: 002B

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
SagePtr, 2020-11-29
@SagePtr

I can assume that the memory segment where the stack pointer points to is write-protected, and therefore it is not possible to push.

J
jcmvbkbc, 2020-12-09
@jcmvbkbc

The stack pointer ( RSP: 0x00007FFFFFFFEA78) points to roughly the same location as the program code ( 0x7fffffffea75: push rbx). The code is usually write-protected, so it may not be possible to write to the stack for this reason. In addition, if you can still write to the stack, push rbx will just overwrite itself and the next instruction. Without a debugger, this can work due to the pipeline, but it will not work under a debugger.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question