Bläddra i källkod

Add wifi and calls

Rich Infante 7 år sedan
förälder
incheckning
104389ec00
2 ändrade filer med 133 tillägg och 11 borttagningar
  1. 77 0
      tools/index.js
  2. 56 11
      tools/util/iphone_backup.js

+ 77 - 0
tools/index.js

@@ -333,6 +333,83 @@ if(program.list) {
             .catch((e) => {
                 console.log('[!] Encountered an Error:', e)
             })
+    } else if(program.report == 'calls') {
+        if(!program.backup) {
+            console.log('use -b or --backup <id> to specify backup.')
+            process.exit(1)
+        }
+
+
+        // Grab the backup
+        var backup = iPhoneBackup.fromID(program.backup, base)
+        backup.getCallsList()
+            .then((items) => {
+
+                if(program.dump) {
+                    console.log(JSON.stringify(items, null, 4))
+                    return
+                }
+
+                var items = items.map(el => [
+                    el.Z_PK + '',
+                    el.XFORMATTEDDATESTRING,
+                    el.ZANSWERED + '',
+                    el.ZORIGINATED + '',
+                    el.ZCALLTYPE + '',
+                    el.ZDURATION + '',
+                    el.ZLOCATION + '',
+                    el.ZISO_COUNTRY_CODE + '',
+                    el.ZSERVICE_PROVIDER + '',
+                    (el.ZADDRESS || '').toString()
+                ])
+
+                items = [['ID', 'Date', 'Answered', 'Originated', 'Type', 'Duration', 'Location', 'Country', 'Service', 'Address'], ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-'], ...items]
+                items = normalizeCols(items).map(el => el.join(' | ').replace(/\n/g, '')).join('\n')
+                
+                if(!program.color) { items = stripAnsi(items) }
+
+                console.log(items)
+            })
+            .catch((e) => {
+                console.log('[!] Encountered an Error:', e)
+            })
+    }  else if(program.report == 'wifi') {
+        if(!program.backup) {
+            console.log('use -b or --backup <id> to specify backup.')
+            process.exit(1)
+        }
+
+
+        // Grab the backup
+        var backup = iPhoneBackup.fromID(program.backup, base)
+        backup.getWifiList()
+            .then((items) => {
+
+                if(program.dump) {
+                    console.log(JSON.stringify(items, null, 4))
+                    return
+                }
+
+                var items = items['List of known networks'].map(el => [
+                    el.lastJoined + '' || '',
+                    el.lastAutoJoined + '' || '',
+                    el.SSID_STR + '',
+                    el.BSSID + '',
+                    el.SecurityMode || '',
+                    el.HIDDEN_NETWORK + '',
+                    el.enabled + '',
+                ]).sort((a, b) => new Date(a[0]).getTime() - new Date(b[0]).getTime())
+
+                items = [['Last Joined', 'Last AutoJoined', 'SSID', 'BSSID','Security', 'Hidden', 'Enabled'], ['-', '-', '-', '-', '-', '-'], ...items]
+                items = normalizeCols(items).map(el => el.join(' | ').replace(/\n/g, '')).join('\n')
+                
+                if(!program.color) { items = stripAnsi(items) }
+
+                console.log(items)
+            })
+            .catch((e) => {
+                console.log('[!] Encountered an Error:', e)
+            })
     } else {
         console.log('')
         console.log('  [!] Unknown Option type:', program.report)

+ 56 - 11
tools/util/iphone_backup.js

@@ -13,9 +13,11 @@ const databases = {
   Notes: 'ca3bc056d4da0bbf88b5fb3be254f3b7147e639c',
   Notes2: '4f98687d8ab0d6d1a371110e6b7300f6e465bef2',
   Calls: '2b2b0084a1bc3a5ac8c27afdf14afb42c61a19ca',
+  Calls2: '5a4935c78a5255723f707230a451d79c540d2741',
   Locations: '4096c9ec676f2847dc283405900e284a7c815836',
   WebHistory: 'e74113c185fd8297e140cfcf9c99436c5cc06b57',
-  Photos: '12b144c0bd44f2b3dffd9186d3f9c05b917cee25'
+  Photos: '12b144c0bd44f2b3dffd9186d3f9c05b917cee25',
+  WiFi: 'ade0340f576ee14793c607073bd7e8e409af07a8'
 }
 
 var cache = {}
@@ -58,7 +60,20 @@ class iPhoneBackup {
     return new iPhoneBackup(id, status, info, manifest)
   }
 
-  getDatabase(fileID, isAbsoulte) {
+  getFileName (fileID, isAbsoulte) {
+    isAbsoulte = isAbsoulte || false
+
+    // Get the backup folder
+    const base = path.join(process.env.HOME, '/Library/Application Support/MobileSync/Backup/', this.id)
+    // Return v2 filename
+    if (this.status.Version < 3 || isAbsoulte) {
+      return path.join(base, fileID)
+    } else {
+      // v3 has folders
+      return path.join(base, fileID.substr(0, 2), fileID)
+    }
+  }
+  getDatabase (fileID, isAbsoulte) {
     isAbsoulte = isAbsoulte || false
 
     // Get the backup folder
@@ -237,8 +252,8 @@ class iPhoneBackup {
     })
   }
 
-  getNotes() {
-    if(parseInt(this.manifest.Lockdown.BuildVersion) <= 13) {
+  getNotes () {
+    if (parseInt(this.manifest.Lockdown.BuildVersion) <= 13) {
       // Legacy iOS 9 support
       // May work for earlier but I haven't tested it
       return this.getNewNotesLegacyiOS9()
@@ -247,32 +262,62 @@ class iPhoneBackup {
     }
   }
 
-  getWebHistory() {
+  getWebHistory () {
     return new Promise((resolve, reject) => {
       var messagedb = this.getDatabase(databases.WebHistory)
       messagedb.all(`SELECT *, datetime(visit_time + 978307200, 'unixepoch') AS XFORMATTEDDATESTRING from history_visits LEFT JOIN history_items ON history_items.ROWID = history_visits.history_item`, async function (err, rows) {
-        if(err) reject(err)
+        if (err) reject(err)
 
         resolve(rows)
       })
-    
     })
   }
 
-  getPhotoLocationHistory() {
+  getPhotoLocationHistory () {
     return new Promise((resolve, reject) => {
       var messagedb = this.getDatabase(databases.Photos)
       messagedb.all(`SELECT ZDATECREATED, ZLATITUDE, ZLONGITUDE, ZFILENAME, datetime(ZDATECREATED + 978307200, 'unixepoch') AS XFORMATTEDDATESTRING FROM ZGENERICASSET ORDER BY ZDATECREATED ASC`, async function (err, rows) {
-        if(err) reject(err)
+        if (err) reject(err)
+
+        resolve(rows)
+      })
+    })
+  }
+
+  getGeofencesList () {
+    return new Promise((resolve, reject) => {
+      var messagedb = this.getDatabase(databases.Locations)
+      messagedb.all(`SELECT datetime(Timestamp + 978307200, 'unixepoch') AS XFORMATTEDDATESTRING, Latitude, Longitude, Distance FROM Fences ORDER BY Timestamp ASC`, async function (err, rows) {
+        if (err) reject(err)
 
         resolve(rows)
       })
-    
     })
   }
-}
 
+  getCallsList () {
+    return new Promise((resolve, reject) => {
+      var messagedb = this.getDatabase(databases.Calls2)
+      messagedb.all(`SELECT *, datetime(ZDATE + 978307200, 'unixepoch') AS XFORMATTEDDATESTRING from ZCALLRECORD ORDER BY ZDATE ASC`, async function (err, rows) {
+        if (err) reject(err)
 
+        resolve(rows)
+      })
+    })
+  }
+
+  getWifiList () {
+    return new Promise((resolve, reject) => {
+      var filename = this.getFileName(databases.WiFi)
+
+      try {
+        resolve(bplist.parseBuffer(fs.readFileSync(filename))[0])
+      } catch (e) {
+        reject(e)
+      }
+    })
+  }
+}
 
 module.exports.availableBackups = function () {
   const base = path.join(process.env.HOME, '/Library/Application Support/MobileSync/Backup/')