The custom HTTP header works as a defense in and of itself. Actually, one rudimentary form of CSRF protection is to simply set a custom header to a constant non secret value and then check for it server side. This protection is sometimes applied unknowingly by simply requireing certain content-type headers.
OWASP describes this technique:
Adding CSRF tokens, a double submit cookie and value, encrypted token, or other defense that involves changing the UI can frequently be complex or otherwise problematic. An alternate defense that is particularly well suited for AJAX/XHR endpoints is the use of a custom request header. This defense relies on the same-origin policy (SOP) restriction that only JavaScript can be used to add a custom header, and only within its origin. By default, browsers do not allow JavaScript to make cross origin requests.
A particularly attractive custom header and value to use is "X-Requested-With: XMLHttpRequest" because most JavaScript libraries already add this header to requests they generate by default.
The limitation to this is, as you say yourself, Flash vulnerabilities:
[B]ypasses of this defense using Flash were documented as early as 2008 and again as recently as 2015 by Mathias Karlsson to exploit a CSRF flaw in Vimeo. Riyaz Walikar from Appsecco Labs was able to exploit this even in early 2019 using older versions of Firefox and also in some recent versions of Chrome (with a bit of user involvement). Since we cannot the control the versions of browser end user uses nor depend on it for their security, this technique is not recommended as a primary defense in measure.
The last sentence is key here. If the victim uses a vulnerable combination of browser and Flash plugin, you can exploit this. If not, you are probably out of luck (unless a permissive CORS policy lets you set the header).