I just stumbled upon a funny trick to detect gdb in this crackme
(btw, strace lincrack2
and it's done.): using file descriptors.
Normally, a programm has 3 file descriptors :
- 0: stdin
- 1: stdout
- 2: stderr
But, if you are running you binary under gdb, you'll notice that it opens 3 more file descriptors, and never closes them.
Example
#include <stdio.h>
#include <unistd.h>
int main(){
FILE* fd = fopen("/tmp", "r");
if(fileno(fd) > 3){
printf("Gdb detected :(\n");
_exit(1);
}
printf("No gdb detected :)\n");
return 0;
}
Result:
$ gcc detect_gdb.c && a.out
No gdb detected :)
$ gdb a.out
Reading symbols from /home/jvoisin/a.out...(no debugging symbols
found)...done.
(gdb) r
Starting program: /home/jvoisin/a.out
Gdb detected :(
[Inferior 1 (process 19872) exited with code 01]
(gdb)
Bypass
Fortunately, this can easily be bypassed :
- Break before the check, on __libc_start_main for example.
- Closes the file descriptors
- Resume
Result:
$ gdb a.out
Reading symbols from /home/jvoisin/a.out...(no debugging symbols
found)...done.
(gdb) b __libc_start_main
Breakpoint 1 at 0x400500
(gdb) r
Starting program: /home/jvoisin/a.out
Breakpoint 1, __libc_start_main (main=0x400668 , argc=1, ubp_av=0x7fffffffdfd8, init=0x400690 , fini=0x400720 ,
rtld_fini=0x7ffff7de9740 , stack_end=0x7fffffffdfc8)
(gdb) print close(3)
$1 = 0
(gdb) print close(4)
$2 = 0
(gdb) print close(5)
$3 = 0
(gdb) c
Continuing.
No gdb :)
[Inferior 1 (process 19804) exited normally]
(gdb)
You can also execute your check_gdb() function before the main, using attributes for even more fun ;)
edit This bug is now fixed in GDB 7.11