Skip to main content

Hi folks!

Eventually, after some brainstorming conversations with Kostas we decided to create this blog in order to post our work.

As you may guess my name is Anastasios. My interests are comprised of computer security, linux, operating systems and many more low level programming concepts :P.

Finally and before my first post, I would like to thank Kostas for taking care of junkbytes.com because i wasn't involved in the creation process. May the source be with you Kostas :) .

So regarding my first post, last days i encountered a very interesting way to execute ptrace. What is ptrace system call ?

ptrace is a system call found in several Unix and Unix-like operating systems. By using ptrace (the name is an abbreviation of "process trace") one process can control another, enabling the controller to inspect and manipulate the internal state of its target. ptrace is used by debuggers and other code-analysis tools, mostly as aids to software development. (wikipedia.org)

As you can see it is used mainly on debuggers during development process. But debuggers are also used during advanced dynamic malware analysis. It is true that malwares in order to avoid being traced by debuggers, use ptrace system call.

The ptrace's prototype is the following:

long ptrace(enum __ptrace_request request, pid_t pid,
                   void *addr, void *data);

By properly executing ptrace malwares can detect the "tracer" process (e.g. debuggers, ltrace, strace).


In terms of my static analysis using IDA PRO, i discovered this way to call ptrace:


The first three lines is the prologue of the certain assembly subroutine, nothing interesting. The ptrace system call takes place in the last four lines. At first, eax and ebx registers are wiped out and then the value 1A(hex)=26(dec) are passed to al (which is the lower 8 bits of eax register). After that an interrupt is made in order to transfer execution from user to kernel mode .

But what's the purpose of moving the value 1A(hex) to al?

Digging the linux system call table, i realized that in order to execute ptrace the value 26(dec) should be present on eax! Bing! This explains why "mov al, 1Ah" was executed.

Regarding calling conventions, i also noticed that this piece of assembly code is not the appropriate way that gcc compiler translates C code to assembly. The gcc usually uses stack in order to pass arguments and call functions. So this piece of code is a inline assembly addition often used in C.

Assembly code can be added in C code using a function. In this case named insert_assembly().

__attribute__((always_inline)) void inline insert_assembly()
{
   __asm__ __volatile__(".byte 0xb3, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb0, 0x1a, 0xcd, 0x80" );
}

This hex code will execute the ptrace system call with the following arguments:

ptrace(PTRACE_TRACEME, 0, 0, 0)

If ptrace's return value is -1 then the process will be traced by a "tracer". In that way, the malware can detect its tracer and follow a different code path.

So tweaking with this concept i wrote the following assembly code (file ass_ptrace.s):


 .text

     .global _start

 _start:

     movb $0, %ebx
     movb $0, %ecx
     movb $0, %edx
     movb $0x1A, %al
     int $0x80
     cmp $0xFFFFFFFF, %eax
     jz exit

     xor %eax, %eax
     movb $1, %al
     xor %ebx, %ebx
     int $0x80

 exit:
     movl $len, %edx
     movl $msg, %ecx
     xor %ebx, %ebx
     movb $1, %bl
     xor %eax, %eax
     movb $4, %al
     int $0x80

     xor %eax, %eax
     movb $1, %al
     xor %ebx, %ebx
     int $0x80


 .data

 msg:
     .ascii "Tracer detected!\n"
     len = . - msg


Briefly, this assembly code executes ptrace(PTRACE_TRACEME, 0, 0, 0) and according to the result it exits or it prints a message and then exits. It prints the message every time it detects a tracer.

Assembled and linked the assembly file,

as --32 ass_ptrace.s -o ass_ptrace.o
ld -m elf_i386 ass_ptrace.o -o ass_ptrace

and then executed it.


As you can see when ass_ptrace is executed without a tracer it does nothing and exits. But when i try to trace it using strace system command, it detects strace, prints "Debugger detected!\n" and exits with the same exit code (0).

The result of "objdump -d ass_ptrace" follows:


The interesting thing despite of the detection of ptrace system call using strace is that ptrace doesn't exist on symbols' table even if i never stripped ass_ptrace (strip removes unnecessary symbols from an ELF, in this case "strip ass_ptrace").


Combining this technique (calling ptrace in this way using assembly and importing it to C code) with some kind of obfuscation can make things nasty. Obfuscation techniques will be discussed in another post.

It is not my intent to train new bad guys, but to make people (particularly security guys) aware of techniques used by them.

Feel free to post your comment. Have a nice day!

Comments

Popular posts from this blog

Blockbuster Inc. & other catch-up

This year has gone by super fast and it's about time for an update. Since June I've been working with Super Sly Fox as the lead developer on our upcoming game Blockbuster Inc , where you build and manage your movie studio through the decades.

Stick Veterans 2.0: a long-overdue update

It's been so long since the last game update that I feel nervous writing this. After a long time of development and rewriting, a new update is finally available. Stick Veterans 2.0 is now published on Poki, a popular online games website.

Aircraft maintenance simulator & VR game projects

Since the start of this academic year I've been enrolled in a Computer Science postgraduate program. I have found a couple of my semester projects to be noteworthy, so I thought I should post about them.