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
|
I know of at least 2 vulnerabilites in proftp, although looking at the
code there are probably hundreds more.
The first one is in sreplace() and is overflowable by making lots of
nested paths. The overflow is in the form of a while loop where a pointer
to a local buffer is continually written to and incremented. It is
particularly difficult to exploit because you have to overwrite many
arguments on the stack, including an array of pointers and the pointer
itself ! Unless you can preserve the stack by being very cunning this is
effectively unexploitable. (it segfaults before the function returns).
The second one is much nicer. it occurs in log_xfer when STOR command is
invoked.
--
sprintf(buf,"%s %d %s %lu %s %c _ %c %c %s ftp 0 *\n",
fmt_time(time(NULL)),xfertime,remhost,fsize,
fname,xfertype,direction,access,user);
--
where fname is the name of the file u are STORing and buf is the only
local buffer on the stack (1024 bytes long);
This is not so easy since you have to take account of the length of the
arguments preceding fname, i.e. fmt_time(time(NULL)), xfertime, remhost,
fsize
heres a snippet from my xferlog file:
--
Thu Dec 2 19:19:14 1999 0 localhost 0 /tmp/blah b _ i r dave ftp 0 *
--
^^^^^^^^^^^^^^^^^^^^^^^^
The formatted time is thankfully always the same size, 24 bytes,
the xfer time is dependant on how long you stay connected, preferably 0,
giving a 1 byte string. the hostname that the remote server sees, you
should be able to find out yourself for sure(try SMTP).
the fsize you should be able to control as well, in my case 0.
So adding all that up gives an inital offset into the buffer of
30 + strlen(hostname)
therefore the distance until the end of the buffer is 996-strlen(hostname)
bytes
consider the length of the buffer to be 996-strlen(hostname)
Calculating the offset is quite difficult off hand but basically all you
have to do is create 4 big directorys (194 chars long), then another
directory approx 200 - strlen(initdir) - strlen(hostname) chars long with
the nops and shellcode. then STOR a 19 byte string with the return
addresses at the end. Note that this last directory has to have a length
<= 194 but this shouldn't be a problem unless you are writing to '/' with a
4 char hostname....
Hopefully this won't 'exploit' the first bug explained above because the
string we are sending is too small to overflow that buffer
(1004-strlen(hostname)).
update: I just found out there is a far better (and easier!) way to exploit proftp which requires only anonymous and a file which you can read. it is still in log_xfer(). all you have to do is log in as anonymous with a really long password and do RETR somefile. the transfer (including your password) is logged, and voila. I have to get around to adding this.
|