Skip to content

Commit 1190dd5

Browse files
author
Emery Ferrari
committed
iOS-Restrictions-Recovery v0.7
1 parent abe2bd4 commit 1190dd5

File tree

12 files changed

+256
-27
lines changed

12 files changed

+256
-27
lines changed

.classpath

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<classpath>
3-
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
4-
<classpathentry kind="src" path="src"/>
5-
<classpathentry kind="lib" path="X:/Libraries/Downloads/sshj-0.27.0.jar"/>
6-
<classpathentry kind="lib" path="X:/Libraries/Downloads/slf4j-api-1.7.2.jar"/>
7-
<classpathentry kind="lib" path="X:/Libraries/Downloads/slf4j-jdk14-1.7.2.jar"/>
8-
<classpathentry kind="lib" path="X:/Libraries/Downloads/eddsa-0.3.0.jar"/>
9-
<classpathentry kind="lib" path="X:/Libraries/Downloads/bcprov-jdk15on-1.64.jar"/>
10-
<classpathentry kind="output" path="bin"/>
3+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
4+
<attributes>
5+
<attribute name="module" value="true"/>
6+
<attribute name="maven.pomderived" value="true"/>
7+
</attributes>
8+
</classpathentry>
9+
<classpathentry kind="src" output="target/classes" path="src">
10+
<attributes>
11+
<attribute name="optional" value="true"/>
12+
<attribute name="maven.pomderived" value="true"/>
13+
</attributes>
14+
</classpathentry>
15+
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
16+
<attributes>
17+
<attribute name="maven.pomderived" value="true"/>
18+
</attributes>
19+
</classpathentry>
20+
<classpathentry kind="output" path="target/classes"/>
1121
</classpath>

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@
2222
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2323
hs_err_pid*
2424
/bin/
25+
/target/

.project

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,14 @@
1010
<arguments>
1111
</arguments>
1212
</buildCommand>
13+
<buildCommand>
14+
<name>org.eclipse.m2e.core.maven2Builder</name>
15+
<arguments>
16+
</arguments>
17+
</buildCommand>
1318
</buildSpec>
1419
<natures>
20+
<nature>org.eclipse.m2e.core.maven2Nature</nature>
1521
<nature>org.eclipse.jdt.core.javanature</nature>
1622
</natures>
1723
</projectDescription>

.settings/org.eclipse.jdt.core.prefs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
eclipse.preferences.version=1
2+
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
3+
org.eclipse.jdt.core.compiler.compliance=1.8
4+
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
5+
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
6+
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
7+
org.eclipse.jdt.core.compiler.release=disabled
8+
org.eclipse.jdt.core.compiler.source=1.8

.settings/org.eclipse.m2e.core.prefs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
activeProfiles=
2+
eclipse.preferences.version=1
3+
resolveWorkspaceProjects=true
4+
version=1

Keychain-Dumper_LICENSE

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2011, Neohapsis, Inc.
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,42 @@
1-
# iOS Restrictions Recovery
1+
# iOS-Restrictions-Recovery
22

3-
by Emery Ferrari<br/>
4-
A GUI/command-line tool that will recover the restrictions passcode from a device running iOS 7.0-11.4.1, either jailbroken or unjailbroken.
3+
by Alyx Ferrari<br/>
4+
A GUI/CLI tool that can find the Restrictions or Screen Time passcode of any iOS device running iOS 7.0 through iOS 13.x.
55

66
## Credit
77

88
slf4j Copyright (c) 2004-2017 QOS.ch<br/>
99
bc-java Copyright (c) 2000-2019 The Legion of the Bouncy Castle Inc.<br/>
1010
sshj Copyright (c) 2010-2012 sshj contributors<br/><br/>
11+
[keychain_dumper](https://github.com/ptoomey3/Keychain-Dumper/) was written by [ptoomey3](https://github.com/ptoomey3/).<br/>
1112
The idea for the iTunes backup feature was given to me by:<br/>
1213
[u/Starwarsfan2099](https://reddit.com/user/Starwarsfan2099) and<br/>
1314
[u/KuroAMK](https://reddit.com/user/KuroAMK)<br/>
1415
The code for the iTunes backup feature was loosely based on [this GitHub project](https://github.com/Starwarsfan2099/iOS-Restriction-Key-Cracker) by [u/Starwarsfan2099](https://reddit.com/user/Starwarsfan2099)
1516

1617
## Dependencies
1718

18-
To compile:<br/>
19-
slf4j (slf4j-api-1.7.2 and slf4j-jdk14-1.7.2 are used for compilation of the release jars)<br/>
20-
sshj (sshj-0.27.0 is used for compilation of the release jars)<br/>
21-
ed25519-java (eddsa-0.3.0 is used for compilation of the release jars)<br/>
22-
bc-java (bcprov-jdk15on-1.64 is used for compilation of the release jars)<br/><br/>
23-
Note: The iproxy feature currently does not work.<br/>
24-
To use the iproxy feature:<br/>
25-
-macOS: homebrew, libimobiledevice<br/>
26-
-Unix-based operating systems: libusbmuxd-tools<br/>
27-
-Windows: Must have iproxy in your PATH environment variable
19+
All dependencies are handled by Maven.<br/>
20+
sshj<br/>
21+
slf4j<br/>
22+
ed25519><br/>
23+
bcprov-jdk15on<br/>
24+
bcpkix-jdk15on<br/>
25+
jzlib
2826

2927
## Compilation/Execution
3028

31-
This tool can either be run from the .jar executable of the latest release in the Releases tab, or can be compiled using javac.
29+
To run this program, you can either download the JAR from the Releases tab or generate one yourself with Maven.<br/>
30+
Whether you use the Releases JAR or one generated yourself, if you want to use the iOS 12-13 features, keychain_dumper must be in the same directory as the JAR.<br/>
31+
OpenSSH is required to use the iOS 12-13 features and the iOS 7.0-11.4.1 SSH features. If you're using checkra1n, iproxy will work as an alternative. If you're using any other jailbreak, OpenSSH is available on the default repos.
3232

3333
## Contacting me
3434

3535
I will respond to any PM I receive on Reddit.<br/>
3636
[u/verystrangebeing](https://reddit.com/user/verystrangebeing/)
37+
38+
## Donate
39+
40+
All of my work is free and open-source. A donation would be greatly appreciated!<br/>
41+
[Buy me a coffee!](buymeacoff.ee/alyxferrari/)<br/>
42+
[PayPal](paypal.me/alyxferrari/)

keychain_dumper

224 KB
Binary file not shown.

pom.xml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<groupId>com.alyxferrari</groupId>
4+
<artifactId>iosrr</artifactId>
5+
<version>0.7</version>
6+
<name>iOS-Restrictions-Recovery</name>
7+
<packaging>jar</packaging>
8+
<dependencies>
9+
<dependency>
10+
<groupId>org.bouncycastle</groupId>
11+
<artifactId>bcprov-jdk15on</artifactId>
12+
<version>1.66</version>
13+
</dependency>
14+
<dependency>
15+
<groupId>net.i2p.crypto</groupId>
16+
<artifactId>eddsa</artifactId>
17+
<version>0.3.0</version>
18+
</dependency>
19+
<dependency>
20+
<groupId>org.slf4j</groupId>
21+
<artifactId>slf4j-api</artifactId>
22+
<version>1.7.30</version>
23+
</dependency>
24+
<dependency>
25+
<groupId>org.slf4j</groupId>
26+
<artifactId>slf4j-jdk14</artifactId>
27+
<version>1.7.30</version>
28+
</dependency>
29+
<dependency>
30+
<groupId>com.hierynomus</groupId>
31+
<artifactId>sshj</artifactId>
32+
<version>0.29.0</version>
33+
</dependency>
34+
</dependencies>
35+
<build>
36+
<sourceDirectory>src</sourceDirectory>
37+
<plugins>
38+
<plugin>
39+
<artifactId>maven-compiler-plugin</artifactId>
40+
<version>3.8.1</version>
41+
<configuration>
42+
<source>1.8</source>
43+
<target>1.8</target>
44+
</configuration>
45+
</plugin>
46+
</plugins>
47+
</build>
48+
</project>

src/com/emeryferrari/iosrr/Display.java

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
import javax.swing.*;
33
import java.awt.event.*;
44
import java.io.*;
5+
import net.schmizz.sshj.*;
6+
import net.schmizz.sshj.common.*;
7+
import net.schmizz.sshj.transport.verification.*;
8+
import net.schmizz.sshj.connection.channel.direct.*;
59
public class Display {
610
private Display() {}
711
private static final Display CLASS_OBJ = new Display();
@@ -13,16 +17,18 @@ private Display() {}
1317
private static JButton SSH_BUTTON = new JButton(RRConst.SSH_BUTTON);
1418
private static JButton IPROXY_BUTTON = new JButton(RRConst.IPROXY_BUTTON);
1519
private static JButton ITUNES_BACKUP = new JButton(RRConst.ITUNES_BACKUP);
20+
private static JButton KEYCHAIN_DUMPER = new JButton(RRConst.KEYCHAIN_DUMPER);
1621
private static InfoPlist[] plists = null;
1722
private static boolean initialized = false;
1823
public static void createDisplay() {
1924
if (!initialized) {
2025
Display.FRAME.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
21-
Display.FRAME.setSize(800, 600);
26+
Display.FRAME.setSize(550, 400);
2227
Display.FRAME.setLayout(new BoxLayout(FRAME.getContentPane(), BoxLayout.Y_AXIS));
2328
Display.KEY_SALT_BUTTON.addActionListener(Display.CLASS_OBJ.new KeySaltButtonListener());
2429
Display.FILE_BUTTON.addActionListener(Display.CLASS_OBJ.new FileButtonListener());
2530
Display.SSH_BUTTON.addActionListener(Display.CLASS_OBJ.new SSHButtonListener());
31+
Display.KEYCHAIN_DUMPER.addActionListener(Display.CLASS_OBJ.new KeychainDumperListener());
2632
Display.IPROXY_BUTTON.addActionListener(Display.CLASS_OBJ.new IproxyButtonListener());
2733
Display.IPROXY_BUTTON.setEnabled(false);
2834
Display.ITUNES_BACKUP.addActionListener(Display.CLASS_OBJ.new ItunesBackupListener());
@@ -33,9 +39,112 @@ public static void createDisplay() {
3339
Display.FRAME.getContentPane().add(Display.KEY_SALT_BUTTON);
3440
Display.FRAME.getContentPane().add(Display.FILE_BUTTON);
3541
Display.FRAME.getContentPane().add(Display.SSH_BUTTON);
42+
Display.FRAME.getContentPane().add(Display.KEYCHAIN_DUMPER);
3643
Display.FRAME.getContentPane().add(Display.ITUNES_BACKUP);
3744
Display.FRAME.setVisible(true);
3845
}
46+
public class KeychainDumperListener implements ActionListener {
47+
public void actionPerformed(ActionEvent ev) {
48+
new Thread() {
49+
@Override
50+
public void run() {
51+
try {
52+
int confirm = JOptionPane.showConfirmDialog(null, "This feature requires SQLite 3.x by Sam Bingner to be installed on your device. Do you consent to automatic installation of this package on your device?");
53+
if (confirm == 0) {
54+
String ip = JOptionPane.showInputDialog("Device IP address? OpenSSH must be installed on your device.");
55+
String portStr = JOptionPane.showInputDialog("Device SSH server port? (press enter to default to 22)");
56+
int port = 22;
57+
if (!portStr.equals("")) {
58+
port = Integer.parseInt(portStr);
59+
}
60+
String rootPass = JOptionPane.showInputDialog("What is your device's root password? (press enter to default to 'alpine')");
61+
if (rootPass.equals("")) {
62+
rootPass = "alpine";
63+
}
64+
Display.FRAME.getContentPane().removeAll();
65+
Display.FRAME.getContentPane().add(new JLabel("Connecting to " + ip + ":" + port + " over SSH..."));
66+
Display.refresh();
67+
System.out.println("Connecting to " + ip + ":" + port + " over SSH...");
68+
SSHClient ssh = new SSHClient();
69+
ssh.addHostKeyVerifier(new PromiscuousVerifier());
70+
ssh.connect(ip, port);
71+
Display.FRAME.getContentPane().add(new JLabel("Logging in as user 'root'..."));
72+
System.out.println("Logging in as user 'root'...");
73+
Display.refresh();
74+
ssh.authPassword("root", rootPass);
75+
Display.FRAME.getContentPane().add(new JLabel("Uploading keychain_dumper to device..."));
76+
Display.refresh();
77+
System.out.println("Uploading keychain_dumper to device...");
78+
ssh.newSCPFileTransfer().upload("keychain_dumper", "/User/Documents/keychain_dumper");
79+
Session session = ssh.startSession();
80+
Display.FRAME.getContentPane().add(new JLabel("Giving keychain_dumper '+x' permissions..."));
81+
System.out.println("Giving keychain_dumper '+x' permissions...");
82+
Display.refresh();
83+
session.exec("chmod +x /User/Documents/keychain_dumper");
84+
Display.FRAME.getContentPane().add(new JLabel("Installing SQLite 3.x by Sam Bingner to the device..."));
85+
System.out.println("Installing SQLite 3.x by Sam Bingner to the device...");
86+
Display.refresh();
87+
session = ssh.startSession();
88+
session.exec("apt install sqlite3");
89+
Display.FRAME.getContentPane().add(new JLabel("Disconnecting..."));
90+
System.out.println("Disconnecting...");
91+
Display.refresh();
92+
ssh.disconnect();
93+
ssh.close();
94+
SSHClient ssh2 = new SSHClient();
95+
ssh2.addHostKeyVerifier(new PromiscuousVerifier());
96+
Display.FRAME.getContentPane().add(new JLabel("Reconnecting to " + ip + ":" + port + "..."));
97+
System.out.println("Reconnecting to " + ip + ":" + port + "...");
98+
Display.refresh();
99+
ssh2.connect(ip, port);
100+
Display.FRAME.getContentPane().add(new JLabel("Logging in as user 'root'..."));
101+
System.out.println("Logging in as user 'root'...");
102+
Display.refresh();
103+
ssh2.authPassword("root", rootPass);
104+
Session session2 = ssh2.startSession();
105+
JOptionPane.showMessageDialog(null, "Please make sure your device is unlocked and on the home screen.");
106+
Display.FRAME.getContentPane().add(new JLabel("Dumping your device's Keychain... (if this blocks, make sure your device is unlocked)"));
107+
System.out.println("Dumping your device's Keychain... (if this blocks, make sure your device is unlocked)");
108+
Display.refresh();
109+
Session.Command cmd = session2.exec("./../mobile/Documents/keychain_dumper");
110+
String keychain = IOUtils.readFully(cmd.getInputStream()).toString();
111+
Display.FRAME.getContentPane().add(new JLabel("Disconnecting..."));
112+
System.out.println("Disconnecting...");
113+
Display.refresh();
114+
ssh2.disconnect();
115+
ssh2.close();
116+
Display.FRAME.getContentPane().add(new JLabel("Parsing Keychain dump..."));
117+
System.out.println("Parsing Keychain dump...");
118+
Display.refresh();
119+
String[] list = keychain.split("ParentalControls")[1].split("\n");
120+
String password = null;
121+
for (int i = 0; i < 20; i++) {
122+
if (list[i].startsWith("Keychain Data: ")) {
123+
password = list[i].split(": ")[1];
124+
break;
125+
}
126+
}
127+
Display.FRAME.getContentPane().add(new JLabel("Found Screen Time passcode! Passcode: " + password));
128+
System.out.println("Found Screen Time passcode! Passcode: " + password);
129+
Display.refresh();
130+
JButton button = new JButton("Back");
131+
button.addActionListener(new BackListener());
132+
Display.FRAME.getContentPane().add(button);
133+
Display.refresh();
134+
JOptionPane.showMessageDialog(null, "Found Screen Time passcode! Passcode: " + password);
135+
}
136+
} catch (Exception ex) {
137+
handleException(ex, true);
138+
Display.FRAME.getContentPane().add(new JLabel("Failed to retrieve Screen Time passcode! If you're sure you've done everything correctly, create an issue on GitHub."));
139+
JButton button = new JButton("Back");
140+
button.addActionListener(new BackListener());
141+
Display.FRAME.getContentPane().add(button);
142+
Display.refresh();
143+
}
144+
}
145+
}.start();
146+
}
147+
}
39148
public class ItunesBackupListener implements ActionListener {
40149
public void actionPerformed(ActionEvent ev) {
41150
try {
@@ -128,6 +237,14 @@ public static void refresh() {
128237
Display.FRAME.revalidate();
129238
Display.FRAME.repaint();
130239
}
240+
public static void refreshThread() {
241+
new Thread() {
242+
@Override
243+
public void run() {
244+
Display.refresh();
245+
}
246+
}.start();
247+
}
131248
public static class BackListener implements ActionListener {
132249
public void actionPerformed(ActionEvent ev) {
133250
Display.FRAME.getContentPane().removeAll();

0 commit comments

Comments
 (0)