[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
Sat Feb 28 17:07:22 UTC 2015


Program (1) below goes into 100% CPU consumption by running a dummy TCP 
server e.g. "nc -l 10000 > /dev/null" and making the program connect to 
that.

That's enough of an exploit to show that a program with this behavior is 
absolutely broken.

Thanks.



On 2015-02-26 00:01, Tinker wrote:
> 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
> _______________________________________________
> openssl-users mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users



More information about the openssl-users mailing list