Tips and tools for Linux and Windows
Dans toutes les étapes du dévelopement d’un sploit ou encore de la résolution d’un challenge (dans l’applicatif comme toujours :)) on se rend compte que notre meilleur ami après Google est notre débuggueur adoré (avant tous les autres tools de reversing :)).
Je vais ici décrire mon environnement de travail (qui est sommaire pour l’instant vu que je commence à peine à jouer avec les real world exploits …).
C’est une liste de tools qui est loin d’être exhaustive, mais je vais vous présenter ce que j’utilise.
Sous Linux
Pas de miracle ou de mystère, le débugueur roi est ici GDB!
C’est pas une panacé à utiliser mais avec l’habitude on s’y fait et c’est mine de rien une bien puissante bête :).
J’ai toujours trouvé un peu lourd à devoir retaper les habituels ‘i r’, etc après chaque break mais coup de chance, on peut tuner GDB! Un bon script existe : Plugin GDB :). Oui de zolies couleurs ^^.
Et pis bon, le débuguer fait pas tout, parfois on a besoin de choper des addresses de fonctions rapidos : nm.
On oublie pas de mater les bibliothèque loadées avec : ldd.
objdump est assez pratique pour dumper des listings asm entiers (et faire une recherche d’instructions intéressantes ;)).
nasm est indispensable pour l’assembly … sans compter ndisasm.
Ou si on veut analyser les shellcodes utilisés dans les sploits, voilà 3 scripts shells de ma conception qui pourraient vous être utiles. Le premier sert à cleaner les outputs de ndisasm :
1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh
sed -r -e '
1 i bits 32\
\
section .text\
global _start\
\
_start:
s/([0-9A-F]+\s+){2}/ /g
'
Le second à passer en unicode les payload unicode en ASCII :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/sh
if [ "$#" -lt 1 ]
then
echo "Usage : $0 (ascii2unicode|unicode2ascii)"
fi
case "$1" in
ascii2unicode)
sed -r 's/(\w)/\1\x00/g'
;;
unicode2ascii)
sed -r 's/(\w)\x00/\1/g'
;;
esac
Le dernier sert juste à me sortir n’importe quel fichier en hex escaped.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/python
import sys
import struct
if len(sys.argv) < 2:
filename = '-'
else:
filename = sys.argv[1]
if filename == '-':
data = sys.stdin.read()
else:
fp = open(filename, 'r')
data = fp.read()
fp.close()
# let's form the shellcode in C form
escaped = ''.join ("\\x%02x" % ord(c) for c in data)
shellcode = 'char shellcode[] = "' + escaped + '"'
print "shellcode size : %i" % len(data)
print shellcode
Ainsi en utilisant la ligne de commande on est mine de rien assez versatile :
1
2
3
4
5
6
7
8
9
10
11
12
m_101@m_101-laptop $ printf "CC" | ./ascii2unicode.sh ascii2unicode | ndisasm -b 32 - | ./clean_nasm.sed
bits 32
section .text
global _start
_start:
inc ebx
add [ebx+0x0],al
m_101@m_101-laptop $ printf "JUNK" | ./shellcode2arrayopt.py -
shellcode size : 4
char shellcode[] = "\x4a\x55\x4e\x4b"
On peut instrumenter GDB avec Python : PythonGDB. Au pire il suffit de créer un fichier de commande GDB et de le lancer comme ça :
1
$ gdb -ex 'source cmds.gdb'
C’est la méthode que j’utilise pour dumper par exemple :
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
#!/usr/bin/python
# Author : m_101
# email : m101.sec at gmail.com
# Target : Linux
# Depends : gdb, python
# Name : iDumpMem
# Purpose : Dumping memory portion out of some process
# Version : 0.1
# License : GPL
# Greetz to people for which hacking is a way to live
# Thanks to 2600 Montreal folks for bringing this script idea
# The code is a bit crappy but it works at least :)
from os.path import *
from os import *
from sys import *
from commands import *
from string import *
# arguments check
if len(argv) < 3:
# example: iDumpMem python heap
print 'Usage: ' + argv[0] + 'proc_name memory_section [dump_file]'
exit(1)
proc_name = argv[1]
mem_section = argv[2]
if len(argv) == 4:
dump_file = argv[3]
else:
dump_file = 'dump_' + proc_name + '_' + mem_section
# process information
proc_ps_line = getoutput('ps aux | grep ' + proc_name + ' | grep -Ev
"(grep|' + argv[0] + ')"')
if proc_ps_line == '':
print 'Process ' + proc_name + " doesn't exist"
exit(1)
# process id
proc_id = split(proc_ps_line)[1]
if proc_id == '':
print "Didn't found proc_id ... exiting"
exit(1)
# getting the memory section of interest
proc_maps_mem = getoutput('cat /proc/' + proc_id + '/maps | grep ' +
mem_section)
if proc_maps_mem == '':
print 'No ' + mem_section + ' found ... exiting'
exit(1)
# memory addresses
mem_range = split(proc_maps_mem)[0]
mem_start = '0x' + split(mem_range, '-')[0]
mem_end = '0x' + split(mem_range, '-')[1]
# printing the informations gained
print 'Process name : ' + proc_name
print 'Process id : ' + proc_id
print 'Process ' + mem_section + ' : ' + mem_range
print '[+] Dumping process ' + mem_section + ' memory ... '
cmds_file_existed = exists(getcwd() + '/cmds.gdb')
# we create gdb commands file if the file doesn't exist yet
# we delete it afterward
if cmds_file_existed == False:
gdb_cmds_file = file('cmds.gdb', 'w')
gdb_cmds_file.write('attach ' + proc_id + '\n')
gdb_cmds_file.write('dump mem ' + dump_file + ' ' + mem_start + '
' + mem_end + '\n')
gdb_cmds_file.write('detach\n')
gdb_cmds_file.write('quit\n')
gdb_cmds_file.close()
# we execute gdb cmds for dumping targeted memory
gdb_dump_mem = getoutput("gdb -ex 'source cmds.gdb'")
# we delete the created gdb cmds file
if cmds_file_existed == False:
unlink('cmds.gdb')
print '[+] ' + proc_name + ' ' + mem_section + ' was dumped'
print '[+] Bye bye ;)'
Sous Windows?
C’est pas les tools qui manquent!
Jouer avec les PEs
On pensent à identifier un éventuel packer avec PEiD ou RDG Packer Detector.
On peut ensuite faire du diffing avec DarunGrim. En terme de patching engine, le meilleur que j’ai trouvé est diablo2oo2’s Universal Patcher.
On peut aussi dumper ses process’ avec LordPE:
Pour reconstruire ses dump, ImpREC est toujours aussi utile.
Les debuggers :
En termes de plugins :
- Byakugan (windbg) : utile pour le sploit dév’
- pvefindaddr (ImmunityDBG) : utile pour le sploit dév’
- patchdiff2 : sert a choper les modifications des updates par exemple
D’autres tools peuvent être utiles :
Et pour finir l’un des tools qui est très utile :
Et vous, quels tools utilisez-vous?
m_101