summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvoisin2013-01-15 21:31:40 +0100
committerjvoisin2013-01-15 21:31:40 +0100
commit808069c906a036f3b8c5de51e302245154131584 (patch)
treec8e046626973ee28a793c24faba312ace286c8c1
First commit with an ugly makefile !
-rw-r--r--Makefile26
-rw-r--r--crash/10123.c32
-rw-r--r--crash/header_screwer.c65
-rw-r--r--detect/gdb.c99
-rw-r--r--detect/gdb.h13
-rw-r--r--detect/main.c72
-rw-r--r--detect/various.c46
-rw-r--r--detect/various.h7
8 files changed, 360 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7933f7e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
1OUTPUT_DIR=./bin/
2
3CC=gcc
4CFLAGS=-m32
5
6
7all: directory prog
8
9directory:
10 @mkdir -p $(OUTPUT_DIR)
11
12prog: detection crash
13
14crash: header_screwer 10123
15
1610123:
17 $(CC) $(CFLAGS) ./crash/10123.c -o $(OUTPUT_DIR)$@
18
19header_screwer:
20 $(CC) $(CFLAGS) ./crash/header_screwer.c -o $(OUTPUT_DIR)$@
21
22detection:
23 $(CC) $(CFLAGS) ./detect/*.c -o $(OUTPUT_DIR)$@
24
25clean:
26 rm -Rf $(OUTPUT_DIR)
diff --git a/crash/10123.c b/crash/10123.c
new file mode 100644
index 0000000..48a9304
--- /dev/null
+++ b/crash/10123.c
@@ -0,0 +1,32 @@
1/*
2 *Excerpt of the bug's description:
3 GDB fails to interrupt the program being debugged if the program is blocking SIGINT.
4
5 When using the sigwait function to retrieve signals, the program is expected to block them. SIGINT is a commonly handled signal. Any
6 program using sigwait to retrieve signals and handling SIGINT this way will not be interruptible by GDB.
7 */
8
9#include <stddef.h>
10#include <stdio.h>
11#include <unistd.h>
12#include <signal.h>
13
14int main(){
15 sigset_t sigs;
16 sigfillset(&sigs);
17 sigprocmask(SIG_SETMASK, &sigs, NULL);
18
19 if(fork()){
20 sleep(1); // to be sure that
21 kill(getppid(), SIGINT);
22 _exit(0);
23 }
24 while(1){
25 pause();
26 printf("[*] No GBD detected\n");
27 /*
28 * Put your code here
29 */
30 }
31 return 0;
32}
diff --git a/crash/header_screwer.c b/crash/header_screwer.c
new file mode 100644
index 0000000..735aecd
--- /dev/null
+++ b/crash/header_screwer.c
@@ -0,0 +1,65 @@
1/*
2 * Elf header screwer, based on an idea of svenka's crackme, named Thellurik (http://crackmes.de/users/svenka/thellurik/)
3 * Unfortunately for me, ioactive was quicker than me : http://blog.ioactive.com/2012/12/striking-back-gdb-and-ida-debuggers.html
4 * Kudos to them !
5 *
6 */
7
8
9#include <stdio.h>
10#include <sys/mman.h>
11#include <unistd.h>
12#include <stdlib.h>
13#include <elf.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <sys/procfs.h>
17#include <fcntl.h>
18
19
20int main(int argc, char** argv){
21 int f;
22 static Elf32_Ehdr* header;
23
24 printf(".: Elf corrupt :.\n");
25
26 if(argc < 2){
27 printf("Usage: %s file", argv[0]);
28 return 1;
29 }
30
31 if((f = open(argv[1], O_RDWR)) < 0){
32 perror("open");
33 return 1;
34 }
35
36 //MAP_SHARED is required to actually update the file
37 if((header = (Elf32_Ehdr *) mmap(NULL, sizeof(header), PROT_READ | PROT_WRITE, MAP_SHARED, f, 0)) == MAP_FAILED){
38 perror("mmap");
39 close(f);
40 return 1;
41 }
42
43 printf("[*] Current header values:\n");
44 printf("\te_shoff:%d\n\te_shnum:%d\n\te_shstrndx:%d\n",
45 header->e_shoff, header->e_shnum, header->e_shstrndx);
46
47 header->e_shoff = 0xffff;
48 header->e_shnum = 0xffff;
49 header->e_shstrndx = 0xffff;
50
51 printf("[*] Patched header values:\n");
52 printf("\te_shoff:%d\n\te_shnum:%d\n\te_shstrndx:%d\n",
53 header->e_shoff, header->e_shnum, header->e_shstrndx);
54
55 if(msync(NULL, 0, MS_SYNC) == -1){
56 perror("msync");
57 close(f);
58 return 1;
59 }
60
61 close(f);
62 munmap(header, 0);
63 printf("You should no more be able to run \"%s\" inside GDB\n", argv[1]);
64 return 0;
65}
diff --git a/detect/gdb.c b/detect/gdb.c
new file mode 100644
index 0000000..53a0311
--- /dev/null
+++ b/detect/gdb.c
@@ -0,0 +1,99 @@
1/*
2 * Various tricks to detect GDB or any related GNU tools
3 *
4 */
5
6
7#include <signal.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/ptrace.h>
12
13
14#define check_strings(str_buff) (strstr(str_buff, "gdb") || strstr(str_buff, "ltrace") || strstr(str_buff, "strace"))
15
16/*
17 * This is an old well known bug (#7912)
18 *
19 * GDB leaks 2 file descriptors when it opens a program to be debugged.
20 * Both file descriptors are pointing to the file being debugged.
21 */
22int dbg_file_descriptor(){
23 FILE* fd = fopen("/", "r");
24 int nb_fd = fileno(fd);
25 fclose(fd);
26
27 return (nb_fd > 3);
28}
29
30/*
31 * Detect GDB by the mean of /proc/$PID/cmdline, which should no be "gdb"
32 */
33int dbg_cmdline(){
34 char buff [24], tmp [16];
35 FILE* f;
36
37 snprintf(buff, 24, "/proc/%d/cmdline", getppid());
38 f = fopen(buff, "r");
39 fgets(tmp, 16, f);
40 fclose(f);
41
42 return check_strings(tmp);
43}
44
45/*
46 * Classic self ptrace trick: a program can only be ptraced by ONE other.
47 */
48int dbg_ptrace(){
49 if(ptrace(PTRACE_TRACEME, 0, 0, 0) == -1)
50 return 1;
51 //TODO : detach ptrace
52 return 0;
53}
54
55/*
56 * GDB handle SIGTRAP, if we raise one under GDB, it will not reach our handler.
57 * FIXME
58 */
59unsigned int no_dbg = 1;
60static void handler(int signum){no_dbg = 0;}
61int dbg_sigtrap(){
62 no_dbg = 1;
63 signal(SIGTRAP, handler);
64 raise(SIGTRAP);
65 signal(SIGTRAP, SIG_IGN);
66 return no_dbg;
67}
68
69/*
70 * Scan memory for breakpoints
71 * TODO
72 */
73int dbg_check_bp(){
74 unsigned char* start;
75 size_t size;
76 size_t i;
77
78 for(i = 0; i < size; i++){
79 if(start[i] == 0xCC || start[i] == 0xCD)
80 return 1;
81 }
82 return 0;
83}
84
85/*
86 * Check the parent's name
87 */
88int dbg_getppid_name(){
89 char buff1[24], buff2[16];
90 FILE* f;
91
92 snprintf(buff1, 24, "/proc/%d/status", getppid());
93 f = fopen(buff1, "r");
94 fgets(buff2, 16, f);
95 fclose(f);
96
97 return check_strings(buff2);
98}
99
diff --git a/detect/gdb.h b/detect/gdb.h
new file mode 100644
index 0000000..c899cf2
--- /dev/null
+++ b/detect/gdb.h
@@ -0,0 +1,13 @@
1#ifndef _GDB_
2#define _GDB_
3
4#define check_strings(str_buff) (strstr(str_buff, "gdb") || strstr(str_buff, "ltrace") || strstr(str_buff, "strace"))
5
6int dbg_file_descriptor();
7int dbg_cmdline();
8int dbg_ptrace();
9int dbg_sigtrap();
10int dbg_check_bp();
11int dbg_getppid_name();
12
13#endif
diff --git a/detect/main.c b/detect/main.c
new file mode 100644
index 0000000..09e7515
--- /dev/null
+++ b/detect/main.c
@@ -0,0 +1,72 @@
1#include <signal.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <sys/ptrace.h>
6
7#include "gdb.h"
8#include "various.h"
9
10
11int main(int argc, char** argv){
12 unsigned int res = 0;
13
14 printf(".: GDB detector :.\n\n");
15
16 if(res += dbg_file_descriptor())
17 printf("[x] file descriptor\n");
18 else
19 printf("[ ] file descriptor\n");
20
21 if(res += dbg_cmdline())
22 printf("[x] /proc/PID/cmdline\n");
23 else
24 printf("[ ] /proc/PID/cmdline\n");
25
26 if(res += dbg_sigtrap())
27 printf("[x] SIGTRAP\n");
28 else
29 printf("[ ] SIGTRAP\n");
30
31 if(res += dbg_getppid_name())
32 printf("[x] getppid name\n");
33 else
34 printf("[ ] getppid name\n");
35
36 if(res += dbg_ptrace())
37 printf("[x] ptrace\n");
38 else
39 printf("[ ] ptrace\n");
40
41 if(res)
42 printf("\n[*] GDB detected\n");
43 else
44 printf("\n[ ] No GDB detected\n");
45
46
47 res = 0;
48 printf("\n\n");
49 printf(".: Various tricks detector :.\n\n");
50
51 if(res += various_ldpreload())
52 printf("[x] LD_PRELOAD\n");
53 else
54 printf("[ ] LD_PRELOAD\n");
55
56 if(res += various_ldpreload_custom_getenv())
57 printf("[x] hidden LD_PRELOAD\n");
58 else
59 printf("[ ] hidden LD_PRELOAD\n");
60
61 if(res += various_rdtsc())
62 printf("[x] Something is slowing the process...\n");
63 else
64 printf("[ ] Everything is running well\n");
65
66 if(res)
67 printf("\n[*] Something is wrong\n");
68 else
69 printf("\n[ ] Everything seems fine\n");
70
71 return 0;
72}
diff --git a/detect/various.c b/detect/various.c
new file mode 100644
index 0000000..3689a8a
--- /dev/null
+++ b/detect/various.c
@@ -0,0 +1,46 @@
1/*
2 * Detection of various tricks
3 *
4 */
5
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11
12
13/*
14 * Dead simple try to detect the LD_PRELOAD trick by looking
15 * into environnement variables of the program.
16 */
17int various_ldpreload(){
18 return (getenv("LD_PRELOAD") != NULL);
19}
20
21/*
22 * Try to detect the LD_PRELOAD trick when used with a custom
23 * gentenv() function. Feel free to expand it using the same principe.
24 */
25int various_ldpreload_custom_getenv(){
26 if(!various_ldpreload()){
27 putenv("LD_PRELOAD=hello");
28 return (strcmp(getenv("LD_PRELOAD"), "hello"));
29 }
30 return 1;
31}
32
33/*
34 * Timiming attack, useful for detecting breakpoints
35 */
36int various_rdtsc(){
37 clock_t t = clock();
38
39 int i; //Time-consuming crap
40 for(i=2; i<7137001; i++)
41 if (7137001 % i == 0)
42 break;
43
44 return (clock() - t > 0xffff); //adjust this
45}
46
diff --git a/detect/various.h b/detect/various.h
new file mode 100644
index 0000000..321c9c8
--- /dev/null
+++ b/detect/various.h
@@ -0,0 +1,7 @@
1#ifndef _VARIOUS_
2#define _VARIOUS_
3int various_ldpreload();
4int various_ldpreload_custom_getenv();
5int various_rdtsc();
6#endif
7