PS4 Network MITM


I decided that I wanted to run my PS4 through a proxy so I can see if the version assertion could possibly be ‘fixed’ by some network manipulation. I found a bunch of things out but was unsuccessful!

Setting it all up

Using a package manager of your choice, install mitmproxy and spin it up. ifconfig or ip addr to get your LAN IP, and then set up hostname:8080 as the proxy server on your PS4. Testing your internet connection should yield the following mitmproxy output:

   GET http://fus01.ps4.update.playstation.net/update/ps4/list/us/ps4-updatelist.xml
       ← 200 application/xml 1.25k 190ms
   GET http://fus01.ps4.update.playstation.net/update/ps4/list/us/ps4-updatelist.xml
       ← 200 application/xml 1.25k 219ms

Signing in to PSN

Strangely, this doesn’t yield any kind of calls to the Playstation update server. The procedure that I am using is navigating to Profile -> Sign In to PlayStation Network. The mitmproxy log does not yield any new data. It would seem that this file is pulled once at boot. Shutting down the console and turning it back on confirms my suspicions…

   GET http://ps4-system.sec.np.dl.playstation.net/ps4-system/bgdc/np/v00/bgdc-config.xml.env
       ← 304 application/xml [no content] 213ms
   GET http://ps4-system.sec.np.dl.playstation.net/ps4-system/bgft/np/v02/bgft.env
       ← 304 text/plain [no content] 173ms
   GET http://fus01.ps4.update.playstation.net/update/ps4/list/us/ps4-updatelist.xml
       ← 200 application/xml 1.25k 207ms
   GET http://ps4-system.sec.np.dl.playstation.net/ps4-system/timezone/np/v00/timezone.dat.env
       ← 404 text/html 16b 97ms

A few minutes later as I let the console idle, we notice this:

   GET http://ps4-system.sec.np.dl.playstation.net/ps4-system/netev/np/v00/netev-config.env
       ← 304 text/plain [no content] 199ms
   GET http://ps4-system.sec.np.dl.playstation.net/ps4-system/wctl/np/v00/wctl-config.env
       ← 304 text/plain [no content] 656ms
   GET http://ps4-system.sec.np.dl.playstation.net/ps4-system/hid_config/np/v00/hid_config.env
       ← 304 text/plain [no content] 635ms
   GET http://ps4-system.sec.np.dl.playstation.net/ps4-system/hidusbpower/np/v00/hidusbpower.env
       ← 304 text/plain [no content] 678ms

Hmm. What can we do about this now? Looks like there are more files that need tampering!

Looking at our spoils

.env files

These appear to be some kind of binary files, Sony’s servers send us a blatantly vague MIME type, which can really be used for anything, even files of other types. Nothing is immediately obvious here, so let’s not waste too much time on this today. Make no mistake, these are important.

Updatelist

Finally, an xml file. Let’s have a look!

<update_data_list>
	<region id="us">
		<force_update>
			<system level0_system_version="04.060.000" level1_system_version="04.060.000">
				<product_requirement id="CUSA03274" level1_system_version="04.070.000" level2_system_version="04.070.000"/>
				<product_requirement id="CUSA05633" level1_system_version="04.070.000" level2_system_version="04.070.000"/>
				<product_requirement id="CUSA06200" level1_system_version="04.070.000" level2_system_version="04.070.000"/>
				<product_requirement id="CUSA05880" level1_system_version="04.070.000" level2_system_version="04.070.000"/>
			</system>
		</force_update>
		<system_pup label="4.07" sdk_version="04.070.001" version="04.070.000">
			<update_data update_type="full">
				<image size="312236032">http://dus01.ps4.update.playstation.net/update/ps4/image/2016_1201/sys_908b5f52e82c36536707844df67961d8/PS4UPDATE.PUP?dest=us
				</image>
			</update_data>
		</system_pup>
		<recovery_pup type="default">
			<system_pup label="4.07" sdk_version="04.070.001" version="04.070.000"/>
			<image size="891231744">http://dus01.ps4.update.playstation.net/update/ps4/image/2016_1201/rec_edffaf60c694b226f9123e634ed6aa00/PS4UPDATE.PUP?dest=us
			</image>
		</recovery_pup>
	</region>
</update_data_list>

Alright, that’s not too bad then. Looks like we should tamper with that force_update key.

It seems that the author of PSProxy has already done this for us, so let’s start there, with this file. Some report that it works, some do not – let’s find out.

<?xml version="1.0" ?>
<update_data_list>
	<region id="uk">
		<force_update>
			<system level0_system_version="03.508.000" level1_system_version="03.508.000"/>
		</force_update>
		<system_pup label="3.50" sdk_version="03.508.001" version="03.508.000">
			<update_data update_type="full">
				<image size="299649024">http://dus01.ps4.update.playstation.net/update/ps4/image/2016_0405/sys_0aa1a7e346aaba18483a106f1a887a6f/PS4UPDATE.PUP?dest=uk</image>
			</update_data>
		</system_pup>
		<recovery_pup type="default">
			<system_pup label="3.50" sdk_version="03.508.001" version="03.508.000"/>
			<image size="878051840">http://duk01.ps4.update.playstation.net/update/ps4/image/2016_0405/rec_1c41826537584a850e0b1cdad1dede36/PS4UPDATE.PUP?dest=uk</image>
		</recovery_pup>
	</region>
</update_data_list>

Replacing update XML

Config

Now, we can use mitmproxy, but it doesn’t gracefully support full file replacement without writing a script. Let’s just use dnsmasq, as setup is much easier. To set up, just add address=/fus01.ps4.update.playstation.net/[your LAN IP] to your dnsmasq config.

Serving the file

Rack has a nice DSL for making rewrite rules. No need to make some shitty app or write httpd rewrite rules. To configure Rack, I consulted the documentation and used Rack::Rewrite. My configuration file is below; it also has a rewrite rule for the “User Guide” settings menu item. To make that work, just make another dnsmasq rule as above.

require 'rack/rewrite'

use Rack::Rewrite do 
  # User guide
  r301 '/document/en/ps4/index.html', '/'
  r301 '/update/ps4/list/us/ps4-updatelist.xml', '/updatelist'
end

use Rack::Static, urls: {
  # I am probably doing this wrong, but it will throw 404 if you provide a `/`-less link and vice versa and will not send data. Bug?
  '/updatelist/' => 'updatelist/ps4-updatelist.xml',
  '/updatelist' => 'updatelist/ps4-updatelist.xml',
  '/' => 'index.html'
}, root: 'web'
  
# Shitty catchall
error = proc do |env|
  [ 404, { 'Content-Type'  => 'text/html' }, ['404 - page not found'] ]
end

run error

And now, to serve:

gem install rack rack-rewrite
rackup -o 0.0.0.0 -p 80

Attempt at bypass

Recall that earlier, we noticed that the PS4 only checks for the update metadata at boot or at first network connection. To begin, make sure dnsmasq and mitmproxy are both running. DNS will handle the file intercept/redirect step, and we can still sniff what happens in the meantime (e.g. maybe we defeated one assertion and need to defeat another). We turn our console off, and back on again, and notice our response…

I am on firmware 4.05; it seems that there is some other assertion happening. Time to modify the xml some more.

More Updatelist Fun

Since the PSProxy-doctored xml doesn’t work, let’s try to doctor the latest one ourselves. The one below has all of the level1_system_version and level2_system_version fields set to 4.050.000. It yields a CE-34701-5, “Update the system software to use network features.”. Also changing other fields to 4.05 yields the same error.

<update_data_list>
	<region id="us">
		<force_update>
			<system level0_system_version="04.050.000" level1_system_version="04.050.000">
				<product_requirement id="CUSA03274" level1_system_version="04.050.000" level2_system_version="04.050.000"/>
				<product_requirement id="CUSA05633" level1_system_version="04.050.000" level2_system_version="04.050.000"/>
				<product_requirement id="CUSA06200" level1_system_version="04.050.000" level2_system_version="04.050.000"/>
				<product_requirement id="CUSA05880" level1_system_version="04.050.000" level2_system_version="04.050.000"/>
			</system>
		</force_update>
		<system_pup label="4.05" sdk_version="04.050.001" version="04.050.000">
			<update_data update_type="full">
				<image size="312236032">http://dus01.ps4.update.playstation.net/update/ps4/image/2016_1201/sys_908b5f52e82c36536707844df67961d8/PS4UPDATE.PUP?dest=us
				</image>
			</update_data>
		</system_pup>
		<recovery_pup type="default">
			<system_pup label="4.05" sdk_version="04.050.001" version="04.050.000"/>
			<image size="891231744">http://dus01.ps4.update.playstation.net/update/ps4/image/2016_1201/rec_edffaf60c694b226f9123e634ed6aa00/PS4UPDATE.PUP?dest=us
			</image>
		</recovery_pup>
	</region>
</update_data_list>

Removing the firmware file links from the XML invokes the same SU-30703 error as before. While disappointing, this yields some useful information. We can categorize this error as some kind of XML validation error, and then the former error that told us we should update our software as the actual assertion failure. Where do we go from here?