IDAPRO on 2018-09-28 10:31:
Hello kellek,
the behavior of the ptrace function is not well defined. This function only can take two possible values (0 or -1) depending on the number of calls that you have done to it.
This makes impossible to resolve the challenge by line command.
kuroguro on 2018-09-28 18:32:
I wonder if the ptrace is there so a parent process can attach to it and manipulate it's memory? Not 100% sure what counts as a valid solution in this case.
kuroguro on 2018-09-28 20:35:
Does this count? :D
gdb --batch-silent -ex='catch syscall ptrace' -ex=r -ex=c -ex='set ($eax) = 1337' -ex=c --args ./noprelo __gmon_start__
kellek on 2018-09-30 08:06:
IDAPRO: try harder :)
@kuroguro: No solutions in the comments please.
Your solve feels like patching during runtime, you should not modify the binary (even if it's in memory).
kuroguro on 2018-11-01 13:12:
Can we get a hint? I can't figure it out :/
kuroguro on 2018-11-01 16:10:
Would making the binary load a custom libc wrapper count as a solution or can ptrace really return the value? Or is there some other workaround I haven't noticed?
darksk4 on 2019-01-03 00:35:
Hello :) Did you already saw my solution? This is my first time so I really don't know how to sent it.
theroot99 on 2019-05-23 19:27:
Hi! Cool Crackme! Does patch the binary where the compare on the return value of ptrace is done count as a solution? Or is there an other way to make ptrace return that value?
BitFriends on 2020-03-02 18:25:
The solution from sys_v is not working. It should be removed also because of missing information.
BitFriends on 2020-03-02 18:36:
If you read the solution, the content of the .so file shold be:
#include
#include
enum __ptrace_request
{
/* Indicate that the process making this request should be traced.
All signals received by this process can be intercepted by its
parent, and its parent can use the other `ptrace' requests. */
PTRACE_TRACEME = 0,
#define PT_TRACE_ME PTRACE_TRACEME
/* Return the word in the process's text space at address ADDR. */
PTRACE_PEEKTEXT = 1,
#define PT_READ_I PTRACE_PEEKTEXT
/* Return the word in the process's data space at address ADDR. */
PTRACE_PEEKDATA = 2,
#define PT_READ_D PTRACE_PEEKDATA
/* Return the word in the process's user area at offset ADDR. */
PTRACE_PEEKUSER = 3,
#define PT_READ_U PTRACE_PEEKUSER
/* Write the word DATA into the process's text space at address ADDR. */
PTRACE_POKETEXT = 4,
#define PT_WRITE_I PTRACE_POKETEXT
/* Write the word DATA into the process's data space at address ADDR. */
PTRACE_POKEDATA = 5,
#define PT_WRITE_D PTRACE_POKEDATA
/* Write the word DATA into the process's user area at offset ADDR. */
PTRACE_POKEUSER = 6,
#define PT_WRITE_U PTRACE_POKEUSER
/* Continue the process. */
PTRACE_CONT = 7,
#define PT_CONTINUE PTRACE_CONT
/* Kill the process. */
PTRACE_KILL = 8,
#define PT_KILL PTRACE_KILL
/* Single step the process.
This is not supported on all machines. */
PTRACE_SINGLESTEP = 9,
#define PT_STEP PTRACE_SINGLESTEP
/* Get all general purpose registers used by a processes.
This is not supported on all machines. */
PTRACE_GETREGS = 12,
#define PT_GETREGS PTRACE_GETREGS
/* Set all general purpose registers used by a processes.
This is not supported on all machines. */
PTRACE_SETREGS = 13,
#define PT_SETREGS PTRACE_SETREGS
/* Get all floating point registers used by a processes.
This is not supported on all machines. */
PTRACE_GETFPREGS = 14,
#define PT_GETFPREGS PTRACE_GETFPREGS
/* Set all floating point registers used by a processes.
This is not supported on all machines. */
PTRACE_SETFPREGS = 15,
#define PT_SETFPREGS PTRACE_SETFPREGS
/* Attach to a process that is already running. */
PTRACE_ATTACH = 16,
#define PT_ATTACH PTRACE_ATTACH
/* Detach from a process attached to with PTRACE_ATTACH. */
PTRACE_DETACH = 17,
#define PT_DETACH PTRACE_DETACH
/* Get all extended floating point registers used by a processes.
This is not supported on all machines. */
PTRACE_GETFPXREGS = 18,
#define PT_GETFPXREGS PTRACE_GETFPXREGS
/* Set all extended floating point registers used by a processes.
This is not supported on all machines. */
PTRACE_SETFPXREGS = 19,
#define PT_SETFPXREGS PTRACE_SETFPXREGS
/* Continue and stop at the next (return from) syscall. */
PTRACE_SYSCALL = 24,
#define PT_SYSCALL PTRACE_SYSCALL
/* Set ptrace filter options. */
PTRACE_SETOPTIONS = 0x4200,
#define PT_SETOPTIONS PTRACE_SETOPTIONS
/* Get last ptrace message. */
PTRACE_GETEVENTMSG = 0x4201,
#define PT_GETEVENTMSG PTRACE_GETEVENTMSG
/* Get siginfo for process. */
PTRACE_GETSIGINFO = 0x4202,
#define PT_GETSIGINFO PTRACE_GETSIGINFO
/* Set new siginfo for process. */
PTRACE_SETSIGINFO = 0x4203
#define PT_SETSIGINFO PTRACE_SETSIGINFO
};
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data) {
return 1337;
}
Thank you for the crackme!
You must be logged in to submit a writeup
Solution by SYS_V on 2019-08-07 07:15: I used DLL injection to substitute libc ptrace with my own version of ptrace. The binary was not modified in any way.