[openssl-users] Two broken SSL_ERROR_WANT_READ/WRITE handling examples - how exploit cpu-hogging and zombification, and, how badly broken do you consider them to be?

Tinker tinkr at openmailbox.org
Wed Feb 25 18:31:08 UTC 2015


Dear list,

I have been given two example programs that I have been requested to 
provide exploits for.

I would kindly ask you to suggest me the simplest way to cause as much 
cpu-hogging in the first one, and zombification in the second, as 
possible.

For causing this, you may use

  * As server for it to connect to, any simple unix tool or C script of 
your choice, and

  * You may alter any Linux kernel settings you want, to alterate the 
fwrite() and fread() behavior that OpenSSL gets.

My suggestions for how exploit below, but without exploit scripts.

Also, if you think these are *not explotaible*, please tell!!


Also just for reference, how badly broken do you consider programs that 
do select() in the wrong direction like this to be - do you consider 
them disqualified from any production use?


Thanks!!



(1)

The first program invokes SSL_write only. Its error is that it responds 
to SSL_ERROR_READ by making a select() for writability, which is of 
course basically always there, meaning that when that is the case it 
will.

How would you cause this program to hog as much CPU as possible?

void make_me_hog_cpu_main() {
     [Connects to an SSL server of your choice, sets the SSL in 
nonblocking mode, and does all way up to SSL_connect.]

     char buf[1];
     // Needed?: SSL_write(ssl,buf,1);
     do {
         int r = SSL_write(ssl,buf,0);
         int e = SSL_get_error(ssl,r);
         if ((e == SSL_ERROR_WANT_READ) || (e == SSL_ERROR_WANT_WRITE)) {
             select( with the SSL socket in writefds );
         }
     } while (not EOF yet);
}


I think the way I would do it, would be to make it connect to a dummy 
TCP server that reads all data and throws it away, but never responds 
with any data.


(2)

The second program invokes SSL_read only. Its error is that it responds 
to SSL_ERROR_WRITE by making a select() for readability.

It should be easy to make the select() call never return.

How would you cause this program to zombify?

void make_me_zombify_main() {
     [Connects to an SSL server of your choice, sets the SSL in 
nonblocking mode, and does all way up to SSL_connect.]

     do {
         int r = SSL_read(ssl,buf,1);
         int e = SSL_get_error(ssl,r);
         if ((e == SSL_ERROR_WANT_READ) || (e == SSL_ERROR_WANT_WRITE)) {
             select( with the SSL socket in readfds );
         }
     } while (not EOF yet);
}

I see this one as a bit trickier - what I see is that OpenSSL starts 
with writing 320 bytes on the socket (see strace output below), when 
starting negotiation.

If I somehow would decrease Linux' NIC's MTU, decrease OS write buffers, 
and similar things, to less than 320 bytes so say to 1 byte, then the 
SSL_read SSL negotiation's first fwrite() would not write all 320 bytes 
and thus it would return SSL_ERROR_WRITE and the server would never 
answer anything, at least not before disconnecting, so the select() 
would cause the connection to zombify until it closes.


Thanks!











strace openssl s_connect -host wikipedia.org -port 443 shows:

socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
setsockopt(3, SOL_SOCKET, SO_KEEPALIVE, [0], 4) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(443), 
sin_addr=inet_addr("208.80.154.224")}, 16) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) 
= 0x7f9c3e8be000
write(1, "CONNECTED(00000003)\n", 20CONNECTED(00000003)
)   = 20
select(4, [3], [3], NULL, NULL)         = 1 (out [3])
time(NULL)                              = 1424859317
time(NULL)                              = 1424859317
write(3, 
"\26\3\1\1;\1\0\0017\3\3T\355\240\265\341\232v\352N\6\357Q\1\0}\2248\362\332\240\201"..., 
320) = 320
read(3, "\26\3\3\0B\2\0", 7)            = 7
time(NULL)                              = 1424859317
time(NULL)                              = 1424859317
read(3, 
"\0>\3\3T\355\240\265+\246\24\\(\337\214\336\241\356)\33\357\342\217\253\254X\257\267\335\35\233\36"..., 
64) = 64
read(3, "\26\3\3\fT", 5)                = 5
read(3, 
"\v\0\fP\0\fM\0\7\3320\202\7\3260\202\6\276\240\3\2\1\2\2\22\21!\227.2\245\345"..., 
3156) = 1384
read(3, "g\202\rwikipedia.org0\t\6\3U\35\23\4\0020\0000\35\6\3U"..., 
1772) = 1772


More information about the openssl-users mailing list