Wordpress 버전은 5.4.6 사용
위 페이지에서 0.3 버전 다운로드 후 Plugin Upload를 통해 플러그인 적용

그럼 Plugin 탭에서 Visitors가 적용된 것을 확인할 수 있다.

해당 플러그인은 접속한 웹 사이트 방문자 데이터 수집 역할을 하며 IP 주소, User-Agent, 시간과 같은 정보를 수집한다. XSS가 작동하는 이유를 확인하기 위해 소스 코드를 확인하려 한다. includes/database.php 파일에서 보면 함수 VST_save_record
함수에서 HTTP 헤더를 통해 워드프레스 DB에 기록을 저장한다.
function VST_save_record() {
global $wpdb;
$table_name = $wpdb->prefix . 'VST_registros';
VST_create_table_records();
return $wpdb->insert(
$table_name,
array(
'patch' => $_SERVER["REQUEST_URI"],
'datetime' => current_time( 'mysql' ),
'useragent' => $_SERVER['HTTP_USER_AGENT'],
'ip' => $_SERVER['HTTP_X_FORWARDED_FOR']
)
);
}
해당 데이터는 admin/start.php
파일에서 includes/database.php
파일에서 VST_get_Records
함수를 사용해 플러그인 페이지에 데이터를 추출해 보여준다.
#includes/database.php VST_get_records 함수
function VST_get_records($date_start, $date_finish) {
global $wpdb;
$table_name = $wpdb->prefix . 'VST_registros';
return $wpdb->get_results('
SELECT *
FROM '.$table_name.'
WHERE datetime between "'.$date_start->format("Y-m-d").' 00:00:00" and "'.$date_finish->format("Y-m-d").' 23:59:59"
ORDER BY id DESC;
');
}
#데이터 추출
----------------------------------------------
#admin/start.php 플러그인 페이지에 데이터 열거
<table class="wp-list-table widefat plugins">
<thead>
<tr>
<th scope="col" id="description" class="manage-column column-description"><b>#</b></th>
<th scope="col" id="description" class="manage-column column-description"><b><?php echo __("Date and Time", "Visitors"); ?></b></th>
<th scope="col" id="name" class="manage-column column-name column-primary"><b><?php echo __("URL", "Visitors"); ?></b></th>
<th scope="col" id="description" class="manage-column column-description"><b><?php echo __("IP", "Visitors"); ?></b></th>
<th scope="col" id="description" class="manage-column column-description"><b><?php echo __("Browser", "Visitors"); ?></b></th>
</tr>
</thead>
<tbody id="the-list">
<?php
$i=count(VST_get_records($date_start, $date_finish));
foreach(VST_get_records($date_start, $date_finish) as $record) {
echo '
<tr class="active" >
<td scope="row" >'.$i.'</td>
<td scope="row" >'.date_format(date_create($record->datetime), get_option("links_updated_date_format")).'</td>
<td scope="row" >'.$record->patch.'</td>
<td scope="row" ><a href="https://www.geolocation.com/es?ip='.$record->ip.'#ipresult">'.$record->ip.'</a></td>
<td>'.$record->useragent.'</td>
</tr>';
$i--;
}
?>
</tbody>
</table>
#추출한 데이터를 페이지에 나열
위 코드를 보면, /admin/start.php
에서 데이터베이스에 저장된 데이터를 추출해 해당 페이지에서 보여주는 코드임을 알 수 있다. 위 코드에서 보면 User-Agent 값이 데이터베이스에서 추출할 때 데이터에 데이터 정제 없이 들어가는 것을 볼 수 있다.
User-Agent는 사용자가 제어할 수 있어서 해당 취약점을 남용할 수 있는지 alert()를 통해 팝업 메시지를 생성하는 스크립트 태그를 삽입해서 XSS 취약점이 활성화되어 있는지 확인할 수 있다.

해당 Request에 User-Agent에 대한 값을 변조해도 데이터가 들어가는지 확인해보기 위해 User-Agent값을 XSS-Test로 바꿔서 보내보면

이렇게 XSS-Test로 데이터가 바뀐 것을 확인할 수 있다.
이제 XSS 페이로드를 넣어서 실제 페이지에서 XSS를 적용할 수 있는지 확인해볼 수 있다.

<script>alert(1)</script>

script문이 작동되는 것을 확인할 수 있다. 이에 넘어온 데이터를 확인해보면


필터링 없이 script문이 저장되는 것을 확인할 수 있다.
이에 User Agent에 <script>alert(1)</script>
말고, <script>alert(”XSS_Payload”)</script>
를 넣어서 보내보았다. 스크립트가 작동되지 않는데 이는 데이터가 저장될 때 필터링 규칙에 의해 \
가 추가되기 때문이다.

그래서 ', "
둘 다 테스트를 해보았는데 필터링 규칙이 적용됐다. 하지만 `
즉, 백틱은 필터링이 되지않아 스크립트 문이 작동되는 것을 확인할 수 있다.

데이터베이스에 들어간 내용을 확인하게 되면 다음과 같다.

이는 Stored XSS로 CVSS 점수는 8.3점으로 높은 점수를 받게 됐다. 관리자 권한 없이 XSS를 일으켜 관리자 계정을 추가할 수 있는 시나리오를 야기할 수 있기 때문이다.
테스트 버전
- Wordpress Version : 5.4.6
- XAMPP Version: 7.4.10
'공부 정리' 카테고리의 다른 글
CVE-2023-23488 (0) | 2025.01.30 |
---|---|
PenTest Cheat Sheet[OSCP] (0) | 2025.01.11 |