forked from ios7hash/ios7hash
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
200 lines (189 loc) · 14.5 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<html>
<head>
<title>Recover iOS7+ Restrictions Passcodes</title>
<style>
body,div,p,a,td,input {font-family: Arial, Helvetica, sans-serif; font-size: 10pt;}
h1 {font-size: 14pt; text-align: center;}
h2 {font-size: 12pt; text-align: center;}
#footer {font-size: 8pt; text-align: center; padding: 0 10 10 10}
#salt_status {color: Red; font-size: 8pt; text-align: left}
#passcode_status {color: Red; font-size: 8pt; text-align: left}
#status {background-color: #C1C1FF; padding: 10 10 10 10;}
</style>
</head>
<body>
<h1>
iOS Restrictions Passcode Cracker<br>A JavaScript implementation using <a href="http://code.google.com/p/crypto-js/" target="_blank">CryptoJS</a>
</h1>
<h2>
Lesson Learned: I chose a bad site name fully expecting Apple to change their restrictions code hashing algorithm in the next iOS version... But this site works for iOS 7, 8, and 9!<br>
<br>Special thanks to these folks: <a href="https://hashcat.net/forum/thread-2892.html" target="_blank">Hashcat</a> and <a href="https://github.com/magnumripper/JohnTheRipper/commit/3e080d833b419cb7748e92e4ded11352b692abb1" target="_blank">John the Ripper</a>
<br>who figured out the encryption scheme & a way to break it VERY FAST!
<br>This is a much slower way, but accessible by all through a simple webpage!
<br><br>I am hosting the code on <a href="https://github.com/ios7hash/ios7hash/tree/gh-pages" target="_blank">GitHub</a> so you can help make it better!
</h2>
<h4><center>
iOS7+ encrypts the Restrictions Passcode using pbkdf2-hmac-sha1, which is quite strong!
<br>The problem is that the keyspace (0000 to 9999) is very small!
<br>
<br>NOTE: Nothing is trasmitted to the server, Javascript does all the work within your browser.
<br>To speed up the search, you can open multiple windows and use different starting & ending codes.
</center></h4>
<div></div>
<form name="pbkdf2form">
<table>
<tr><td>RestrictionsPasswordKey:</td><td colspan=2><input id="key" type="text" size="33"></td></tr>
<tr><td>RestrictionsPasswordSalt:</td><td><input id="salt" type="text" size="14"></td><td id="salt_status"></td></tr>
<tr><td>Starting Passcode:</td><td><input id="password" value="0000" type="text" size="14"></td><td id="passcode_status"></td>
<td>Last Search Code:</td><td><input id="passend" value="9999" type="text" size="11"></td></tr>
<tr><td></td><td><input type="button" value="Test Single Code" onclick="test_code()"></td>
<td><input type="button" value="Search for Code" onclick="find_code()"></td><td></td>
<td><input type="button" value="Stop, I give up" onclick="stop_searching()"></td></tr>
</table>
</form>
<div id="status"></div>
<h4>Notes:</h4>
If this site helps you or you have questions, let me know: <b><u>ios7hash (at) derson.us</u></b><br>
<br>You will need access to iOS backup files or a jailbroken device to find the encrypted keys.
<br>From a jailbroken device, you need this file: <b>com.apple.restrictionspassword.plist</b>
<br>
<br>On Windows or a Mac, the file can be found in an <i><u>unencrypted</u></i> iTunes backup of your device:
<br>On Windows, the file is located here: "%AppData%\Apple Computer\MobileSync\Backup\" xxxRandomxxx\
<br>Mac: ~/Library/Application Support/MobileSync/Backup/ where the "~" represents your Home folder.
<br>-- note, if you don't see Library in your Home folder, hold Option and click the Go menu.
<br>The file you need has this crazy name: <b>398bc9c2aeeab4cb0c12ada0f52eea12cf14f40b</b>
<br>
<br>If your backups are encrypted, there are other tools that can open the encrypted files...
<br>
<br>Within that file, you should find text like this:
<xmp> <dict>
<key>RestrictionsPasswordKey</key>
<data>
M/p4734c8/SOXZnGgZot+BciAW0=
</data>
<key>RestrictionsPasswordSalt</key>
<data>
aSbUXg==
</data>
</dict>
</xmp>
The key is: <b>M/p4734c8/SOXZnGgZot+BciAW0=</b> and the salt is: <b>aSbUXg==</b>
<br>You can copy & paste these keys above to watch the script work. (hint: 0001)
<br>The script will automatically stop & a pop-up will appear with your code.
<br>
<br><b>If you have questions or need additional directions, check out a great <a href="https://nbalkota.wordpress.com/2014/04/05/recover-your-forgotten-ios-7-restrictions-pin-code" target="_blank">blog by nbalkota</a>.</b>
<br>
<br>There are many tools available to read/decrypt iTunes backups, <a href="http://www.google.com/#q=itunes+backup+software" target="_blank">search Google</a>.
<br>My favorite is <b><a href="http://www.icopybot.com/itunes-backup-manager.htm" target="_blank">iBackupBot</a></b> because it has a built in viewer & can decrypt backups.
<br>
<img src="https://cloud.githubusercontent.com/assets/7176773/2621962/a3c8f8c4-bc7f-11e3-9e35-845904385d85.jpg">
<script>
function main_func()
{
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(g,j){var e={},d=e.lib={},m=function(){},n=d.Base={extend:function(a){m.prototype=this;var c=new m;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
q=d.WordArray=n.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=j?c:4*a.length},toString:function(a){return(a||l).stringify(this)},concat:function(a){var c=this.words,p=a.words,f=this.sigBytes;a=a.sigBytes;this.clamp();if(f%4)for(var b=0;b<a;b++)c[f+b>>>2]|=(p[b>>>2]>>>24-8*(b%4)&255)<<24-8*((f+b)%4);else if(65535<p.length)for(b=0;b<a;b+=4)c[f+b>>>2]=p[b>>>2];else c.push.apply(c,p);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=g.ceil(c/4)},clone:function(){var a=n.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b<a;b+=4)c.push(4294967296*g.random()|0);return new q.init(c,a)}}),b=e.enc={},l=b.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f<a;f++){var d=c[f>>>2]>>>24-8*(f%4)&255;b.push((d>>>4).toString(16));b.push((d&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f<c;f+=2)b[f>>>3]|=parseInt(a.substr(f,
2),16)<<24-4*(f%8);return new q.init(b,c/2)}},k=b.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f<a;f++)b.push(String.fromCharCode(c[f>>>2]>>>24-8*(f%4)&255));return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f<c;f++)b[f>>>2]|=(a.charCodeAt(f)&255)<<24-8*(f%4);return new q.init(b,c)}},h=b.Utf8={stringify:function(a){try{return decodeURIComponent(escape(k.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return k.parse(unescape(encodeURIComponent(a)))}},
u=d.BufferedBlockAlgorithm=n.extend({reset:function(){this._data=new q.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=h.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var b=this._data,d=b.words,f=b.sigBytes,l=this.blockSize,e=f/(4*l),e=a?g.ceil(e):g.max((e|0)-this._minBufferSize,0);a=e*l;f=g.min(4*a,f);if(a){for(var h=0;h<a;h+=l)this._doProcessBlock(d,h);h=d.splice(0,a);b.sigBytes-=f}return new q.init(h,f)},clone:function(){var a=n.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});d.Hasher=u.extend({cfg:n.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){u.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,d){return(new a.init(d)).finalize(b)}},_createHmacHelper:function(a){return function(b,d){return(new w.HMAC.init(a,
d)).finalize(b)}}});var w=e.algo={};return e}(Math);
(function(){var g=CryptoJS,j=g.lib,e=j.WordArray,d=j.Hasher,m=[],j=g.algo.SHA1=d.extend({_doReset:function(){this._hash=new e.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(d,e){for(var b=this._hash.words,l=b[0],k=b[1],h=b[2],g=b[3],j=b[4],a=0;80>a;a++){if(16>a)m[a]=d[e+a]|0;else{var c=m[a-3]^m[a-8]^m[a-14]^m[a-16];m[a]=c<<1|c>>>31}c=(l<<5|l>>>27)+j+m[a];c=20>a?c+((k&h|~k&g)+1518500249):40>a?c+((k^h^g)+1859775393):60>a?c+((k&h|k&g|h&g)-1894007588):c+((k^h^
g)-899497514);j=g;g=h;h=k<<30|k>>>2;k=l;l=c}b[0]=b[0]+l|0;b[1]=b[1]+k|0;b[2]=b[2]+h|0;b[3]=b[3]+g|0;b[4]=b[4]+j|0},_doFinalize:function(){var d=this._data,e=d.words,b=8*this._nDataBytes,l=8*d.sigBytes;e[l>>>5]|=128<<24-l%32;e[(l+64>>>9<<4)+14]=Math.floor(b/4294967296);e[(l+64>>>9<<4)+15]=b;d.sigBytes=4*e.length;this._process();return this._hash},clone:function(){var e=d.clone.call(this);e._hash=this._hash.clone();return e}});g.SHA1=d._createHelper(j);g.HmacSHA1=d._createHmacHelper(j)})();
(function(){var g=CryptoJS,j=g.enc.Utf8;g.algo.HMAC=g.lib.Base.extend({init:function(e,d){e=this._hasher=new e.init;"string"==typeof d&&(d=j.parse(d));var g=e.blockSize,n=4*g;d.sigBytes>n&&(d=e.finalize(d));d.clamp();for(var q=this._oKey=d.clone(),b=this._iKey=d.clone(),l=q.words,k=b.words,h=0;h<g;h++)l[h]^=1549556828,k[h]^=909522486;q.sigBytes=b.sigBytes=n;this.reset()},reset:function(){var e=this._hasher;e.reset();e.update(this._iKey)},update:function(e){this._hasher.update(e);return this},finalize:function(e){var d=
this._hasher;e=d.finalize(e);d.reset();return d.finalize(this._oKey.clone().concat(e))}})})();
(function(){var g=CryptoJS,j=g.lib,e=j.Base,d=j.WordArray,j=g.algo,m=j.HMAC,n=j.PBKDF2=e.extend({cfg:e.extend({keySize:4,hasher:j.SHA1,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(e,b){for(var g=this.cfg,k=m.create(g.hasher,e),h=d.create(),j=d.create([1]),n=h.words,a=j.words,c=g.keySize,g=g.iterations;n.length<c;){var p=k.update(b).finalize(j);k.reset();for(var f=p.words,v=f.length,s=p,t=1;t<g;t++){s=k.finalize(s);k.reset();for(var x=s.words,r=0;r<v;r++)f[r]^=x[r]}h.concat(p);
a[0]++}h.sigBytes=4*c;return h}});g.PBKDF2=function(d,b,e){return n.create(e).compute(d,b)}})();
(function(){var h=CryptoJS,i=h.lib.WordArray;h.enc.Base64={stringify:function(b){var e=b.words,f=b.sigBytes,c=this._map;b.clamp();for(var b=[],a=0;a<f;a+=3)for(var d=(e[a>>>2]>>>24-8*(a%4)&255)<<16|(e[a+1>>>2]>>>24-8*((a+1)%4)&255)<<8|e[a+2>>>2]>>>24-8*((a+2)%4)&255,g=0;4>g&&a+0.75*g<f;g++)b.push(c.charAt(d>>>6*(3-g)&63));if(e=c.charAt(64))for(;b.length%4;)b.push(e);return b.join("")},parse:function(b){var b=b.replace(/\s/g,""),e=b.length,f=this._map,c=f.charAt(64);c&&(c=b.indexOf(c),-1!=c&&(e=c));
for(var c=[],a=0,d=0;d<e;d++)if(d%4){var g=f.indexOf(b.charAt(d-1))<<2*(d%4),h=f.indexOf(b.charAt(d))>>>6-2*(d%4);c[a>>>2]|=(g|h)<<24-8*(a%4);a++}return i.create(c,a)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();
var key = CryptoJS.enc.Base64.parse(document.pbkdf2form.key.value).toString();
var salt = document.pbkdf2form.salt.value;
var i = document.pbkdf2form.password.value;
var stopnow=0;
var end = ("0000" + document.pbkdf2form.passend.value).slice(-4);
var this_object=this;
// Sanity checks
function sanity_check()
{
i=document.pbkdf2form.password.value;
var valid=1;
document.getElementById("passcode_status").innerHTML = "";
document.getElementById("salt_status").innerHTML = "";
if (isNaN(i) || i<0 || i>9999)
{
document.getElementById("passcode_status").innerHTML = "invalid";
valid=0;
}
if (!document.pbkdf2form.salt.value) {
document.getElementById("salt_status").innerHTML = "invalid";
valid=0;
}
if (valid==0)
{
document.getElementById("status").style.backgroundColor="yellow";
display_message("You can use this however you like, but there should be a valid Salt<br>and the Starting Passcode should be between 0000 and 9999");
alert("I understand and will click Stop if needed!");
}
}
function display_message(msg) { document.getElementById("status").innerHTML = msg; }
this.try_code = function()
{
var code = CryptoJS.PBKDF2(pass, CryptoJS.enc.Base64.parse(salt), {keySize: 5, iterations: 1000});
display_message("Passcode: <b>"+pass+"</b> with salt <b>"+salt+"</b> creates base64 key: <b>"+code.toString(CryptoJS.enc.Base64)+"</B>");
//alert("pass:"+pass+" end:"+end+" key:"+key+" code:"+code+" stopnow:"+stopnow);
if (code.toString()==key) {
display_message("<B>FOUND!! Passcode: "+pass+"</b> with salt <b>"+salt+"</b> creates base64 key: <b>"+code.toString(CryptoJS.enc.Base64)+"</B>");
document.getElementById("status").style.backgroundColor="yellow";
alert("The passcode is: " + pass);
} else if (pass.toString()==end.toString() || stopnow==1) {
display_message("Stopping... Passcode: <b>"+pass+"</b> with salt <b>"+salt+"</b> creates base64 key: <b>"+code.toString(CryptoJS.enc.Base64)+"</B>");
} else { //try again
i++;
pass = ("0000" + i).slice(-4);
document.pbkdf2form.password.value = pass;
setTimeout(function() { this_object.try_code(); }, 0);
}
}
this.stop_code = function()
{
stopnow=1;
document.getElementById("passcode_status").innerHTML = "";
document.getElementById("salt_status").innerHTML = "";
}
this.startnow = function()
{
sanity_check();
i=document.pbkdf2form.password.value;
pass = ("0000" + i).slice(-4);
end = ("0000" + document.pbkdf2form.passend.value).slice(-4);
salt = document.pbkdf2form.salt.value;
key = CryptoJS.enc.Base64.parse(document.pbkdf2form.key.value).toString();
stopnow=0;
document.getElementById("status").style.backgroundColor="#C1C1FF";
setTimeout(function() { this_object.try_code(); }, 0);
}
this.tryone = function()
{
sanity_check();
i=document.pbkdf2form.password.value;
pass = i;
end = ("0000" + i).slice(-4);
salt = document.pbkdf2form.salt.value;
key = CryptoJS.enc.Base64.parse(document.pbkdf2form.key.value).toString();
stopnow=1;
document.getElementById("status").style.backgroundColor="#C1C1FF";
setTimeout(function() { this_object.try_code(); }, 0);
}
}
var myfunc = new main_func();
function find_code(){ myfunc.startnow(); }
function stop_searching(){ myfunc.stop_code(); }
function test_code(){ myfunc.tryone(); }
</script>
</body>
</html>