Stealthy MDM Blocker
An attempt to remove the MDM restrictions from an iPad while the MDM server still sees a compliant device.
What I tried
An iPad under MDM (mobile device management) gets configuration profiles from a server. Those profiles can limit which apps run, filter websites and disable features such as AirDrop or app installation.
I wanted to change the restrictions on the iPad while the server still recorded its commands as successful. In early 2024, I studied the traffic from a Jamf School setup and built two approaches in Python. One edits the profile before the iPad receives it. The other keeps the iPad out of the conversation and answers the server in its place.
The interesting part was the difference between the rules on the device and the state recorded by the server.
How the command cycle works
The server does not send a profile directly through a push notification. It uses Apple Push Notification service (APNs) to prompt the iPad to contact its MDM endpoint over HTTPS. The device starts with an Idle message, or sends the result of its previous command. The server's response contains the next command.
In the traffic I captured, the server first asked for a ProfileList, then sent InstallProfile commands. Each command had a CommandUUID. After installing a profile, the iPad sent Acknowledged with the same UUID. The server could then send another command, or an empty response if there was nothing left to do.
This gives both approaches a place to intervene: the profile travelling to the device, or the acknowledgement travelling back. The diagram shows one installation; the captured exchange includes the profile-list request and multiple installations. Apple's command-cycle documentation describes the underlying exchange.
Method 1: edit the profile on the way
The first approach is a mitmproxy add-on. The iPad's traffic goes through the proxy, and the iPad must trust its custom CA certificate. That lets the proxy read the HTTPS responses and change them before forwarding them to the device.
The add-on identifies InstallProfile responses and extracts their Payload. In the profiles I captured, that field contains base64-encoded XML. Base64 is an encoding, not encryption: HTTPS protects the transport, and decoding the payload exposes the profile's settings.
The patcher can make several changes:
- Extend the app allowlist with additional bundle IDs, or remove the allowlist payload.
- Change individual restriction flags, or experimentally remove the restrictions payload.
- Disable automatic web filtering and replace the denied-URL list.
It then encodes the edited XML back into the command and forwards it. The iPad installs the modified profile and sends its normal acknowledgement. The command UUID stays the same, so the server receives a successful result for the command it issued, even though the installed settings differ.
The profile's management identity is left in place. The goal was to change the restrictions while keeping enrollment. The patcher only edits installation commands; other command types pass through.
The main constraint was certificate trust. Without a trusted proxy CA, the proxy cannot read and rewrite this HTTPS traffic. The implementation also assumes the XML profile format I observed. Its fixture tests compare the edits against expected output for two captured profile versions.
Method 2: answer as the iPad
The second approach changes who receives the commands. It combines a DNS service with a separate HTTP client that speaks the observed MDM protocol.
The DNS service forwards ordinary queries to an upstream resolver. For the MDM host, it returns NXDOMAIN: the name does not exist. The iPad cannot find the server, so its attempt to fetch commands fails and it waits to retry. Blocking DNS alone does not remove a profile already installed on the device.
While the iPad is waiting, the replacement client contacts the real MDM endpoint using the device identity from the captured traffic. It starts the command cycle, reads each command UUID and sends a reply for that command. For InstallProfile, it says Acknowledged without installing anything.
The client also has recorded replies for ProfileList and SecurityInfo, and a declarative-management status message reporting passcode compliance. It continues the conversation until the server has no more commands to send. Those replies are specific to the endpoint and device I studied.
When ordinary DNS is restored, the real iPad can reach the MDM server again. The intended result is an empty response on its next retry: the replacement client has already acknowledged the pending commands. The server has advanced its queue, but the iPad never received those profiles.
DNS is only responsible for keeping the real device away during that exchange. The replacement HTTP client is what advances the queue. This depends on the endpoint accepting that client's requests as belonging to the enrolled device.
What this experiment shows
Both methods target the relationship between a command and its reported result. In the proxy method, the iPad acknowledges an installation whose contents were changed. In the DNS method, a substitute client acknowledges an installation that never happened on the iPad.
An acknowledgement tells the server that a command completed. In the exchange I studied, it did not prove that the original restrictions were active on the device. That is the gap I was investigating.
The project remains an archived experiment against that setup. An empty queue only describes the commands pending at that moment: the server can issue new commands later. The DNS method also leaves existing profiles in place. These constraints matter when interpreting what “the server sees a compliant device” means here.