“少上网多读书” – arttnba3

结构体,函数以及变量

结构体多起来之后有点乱,整理在这里

struct cred

4.4.72

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
struct cred {
atomic_t usage; /* 0 4 */
kuid_t uid; /* 4 4 */
//不知道什么用,参考作用
kgid_t gid; /* 8 4 */
kuid_t suid; /* 12 4 */
//被保存的,用于恢复上一个进程权限
kgid_t sgid; /* 16 4 */
kuid_t euid; /* 20 4 */
//对用户权限起决定性作用
kgid_t egid; /* 24 4 */
kuid_t fsuid; /* 28 4 */
kgid_t fsgid; /* 32 4 */
unsigned int securebits; /* 36 4 */
kernel_cap_t cap_inheritable; /* 40 8 */
kernel_cap_t cap_permitted; /* 48 8 */
kernel_cap_t cap_effective; /* 56 8 */
/* --- cacheline 1 boundary (64 bytes) --- */
kernel_cap_t cap_bset; /* 64 8 */
kernel_cap_t cap_ambient; /* 72 8 */
unsigned char jit_keyring; /* 80 1 */

/* XXX 7 bytes hole, try to pack */

struct key * session_keyring; /* 88 8 */
struct key * process_keyring; /* 96 8 */
struct key * thread_keyring; /* 104 8 */
struct key * request_key_auth; /* 112 8 */
void * security; /* 120 8 */
/* --- cacheline 2 boundary (128 bytes) --- */
struct user_struct * user; /* 128 8 */
struct user_namespace * user_ns; /* 136 8 */
struct group_info * group_info; /* 144 8 */
struct callback_head rcu __attribute__((__aligned__(8))); /* 152 16 */

/* size: 168, cachelines: 3, members: 25 */
/* sum members: 161, holes: 1, sum holes: 7 */
/* forced alignments: 1 */
/* last cacheline: 40 bytes */
} __attribute__((__aligned__(8)));

root无视权限限制,要想打开只有一种办法就是提权,所以gid相关不重要

tty_struct tty_operations

4.4.72

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
struct tty_struct {
int magic; /* 0 4 */
struct kref kref; /* 4 4 */
struct device * dev; /* 8 8 */
struct tty_driver * driver; /* 16 8 */
const struct tty_operations * ops; /* 24 8 */
// 修改这个
int index; /* 32 4 */

/* XXX 4 bytes hole, try to pack */

struct ld_semaphore ldisc_sem; /* 40 48 */
/* --- cacheline 1 boundary (64 bytes) was 24 bytes ago --- */
struct tty_ldisc * ldisc; /* 88 8 */
struct mutex atomic_write_lock; /* 96 40 */

/* XXX last struct has 4 bytes of padding */

/* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
struct mutex legacy_mutex; /* 136 40 */

/* XXX last struct has 4 bytes of padding */

struct mutex throttle_mutex; /* 176 40 */

/* XXX last struct has 4 bytes of padding */

/* --- cacheline 3 boundary (192 bytes) was 24 bytes ago --- */
struct rw_semaphore termios_rwsem; /* 216 40 */
/* --- cacheline 4 boundary (256 bytes) --- */
struct mutex winsize_mutex; /* 256 40 */

/* XXX last struct has 4 bytes of padding */

spinlock_t ctrl_lock; /* 296 4 */
spinlock_t flow_lock; /* 300 4 */
struct ktermios termios; /* 304 44 */
/* --- cacheline 5 boundary (320 bytes) was 28 bytes ago --- */
struct ktermios termios_locked; /* 348 44 */
/* --- cacheline 6 boundary (384 bytes) was 8 bytes ago --- */
struct termiox * termiox; /* 392 8 */
char name[64]; /* 400 64 */
/* --- cacheline 7 boundary (448 bytes) was 16 bytes ago --- */
struct pid * pgrp; /* 464 8 */
struct pid * session; /* 472 8 */
long unsigned int flags; /* 480 8 */
int count; /* 488 4 */
struct winsize winsize; /* 492 8 */

/* Bitfield combined with next fields */

long unsigned int stopped:1; /* 496:32 8 */
long unsigned int flow_stopped:1; /* 496:33 8 */

/* XXX 30 bits hole, try to pack */

/* Force alignment to the next boundary: */
long unsigned int :0;

long unsigned int unused:62; /* 504: 0 8 */

/* XXX 2 bits hole, try to pack */

/* --- cacheline 8 boundary (512 bytes) --- */
int hw_stopped; /* 512 4 */

/* Bitfield combined with previous fields */

long unsigned int ctrl_status:8; /* 512:32 8 */
long unsigned int packet:1; /* 512:40 8 */

/* XXX 23 bits hole, try to pack */

/* Force alignment to the next boundary: */
long unsigned int :0;

long unsigned int unused_ctrl:55; /* 520: 0 8 */

/* XXX 9 bits hole, try to pack */

unsigned int receive_room; /* 528 4 */
int flow_change; /* 532 4 */
struct tty_struct * link; /* 536 8 */
struct fasync_struct * fasync; /* 544 8 */
int alt_speed; /* 552 4 */

/* XXX 4 bytes hole, try to pack */

wait_queue_head_t write_wait; /* 560 24 */
/* --- cacheline 9 boundary (576 bytes) was 8 bytes ago --- */
wait_queue_head_t read_wait; /* 584 24 */
struct work_struct hangup_work; /* 608 32 */
/* --- cacheline 10 boundary (640 bytes) --- */
void * disc_data; /* 640 8 */
void * driver_data; /* 648 8 */
struct list_head tty_files; /* 656 16 */
int closing; /* 672 4 */

/* XXX 4 bytes hole, try to pack */

unsigned char * write_buf; /* 680 8 */
int write_cnt; /* 688 4 */

/* XXX 4 bytes hole, try to pack */

struct work_struct SAK_work; /* 696 32 */
/* --- cacheline 11 boundary (704 bytes) was 24 bytes ago --- */
struct tty_port * port; /* 728 8 */

/* size: 736, cachelines: 12, members: 47 */
/* sum members: 696, holes: 4, sum holes: 16 */
/* sum bitfield members: 128 bits, bit holes: 4, sum bit holes: 64 bits */
/* paddings: 4, sum paddings: 16 */
/* last cacheline: 32 bytes */
};
struct tty_operations {
struct tty_struct * (*lookup)(struct tty_driver *, struct inode *, int); /* 0 8 */
int (*install)(struct tty_driver *, struct tty_struct *); /* 8 8 */
void (*remove)(struct tty_driver *, struct tty_struct *); /* 16 8 */
int (*open)(struct tty_struct *, struct file *); /* 24 8 */
void (*close)(struct tty_struct *, struct file *); /* 32 8 */
void (*shutdown)(struct tty_struct *); /* 40 8 */
void (*cleanup)(struct tty_struct *); /* 48 8 */
int (*write)(struct tty_struct *, const unsigned char *, int); /* 56 8 */
// 可以修改这个,直接调用write就可以触发
/* --- cacheline 1 boundary (64 bytes) --- */
int (*put_char)(struct tty_struct *, unsigned char); /* 64 8 */
void (*flush_chars)(struct tty_struct *); /* 72 8 */
int (*write_room)(struct tty_struct *); /* 80 8 */
int (*chars_in_buffer)(struct tty_struct *); /* 88 8 */
int (*ioctl)(struct tty_struct *, unsigned int, long unsigned int); /* 96 8 */
//目前用的情况是想使用work_for_cpu_fn这个函数的时候会,同时可以符合work_for_cpu_fn的rdi参数要求,
long int (*compat_ioctl)(struct tty_struct *, unsigned int, long unsigned int); /* 104 8 */
void (*set_termios)(struct tty_struct *, struct ktermios *); /* 112 8 */
void (*throttle)(struct tty_struct *); /* 120 8 */
/* --- cacheline 2 boundary (128 bytes) --- */
void (*unthrottle)(struct tty_struct *); /* 128 8 */
void (*stop)(struct tty_struct *); /* 136 8 */
void (*start)(struct tty_struct *); /* 144 8 */
void (*hangup)(struct tty_struct *); /* 152 8 */
int (*break_ctl)(struct tty_struct *, int); /* 160 8 */
void (*flush_buffer)(struct tty_struct *); /* 168 8 */
void (*set_ldisc)(struct tty_struct *); /* 176 8 */
void (*wait_until_sent)(struct tty_struct *, int); /* 184 8 */
/* --- cacheline 3 boundary (192 bytes) --- */
void (*send_xchar)(struct tty_struct *, char); /* 192 8 */
int (*tiocmget)(struct tty_struct *); /* 200 8 */
int (*tiocmset)(struct tty_struct *, unsigned int, unsigned int); /* 208 8 */
int (*resize)(struct tty_struct *, struct winsize *); /* 216 8 */
int (*set_termiox)(struct tty_struct *, struct termiox *); /* 224 8 */
int (*get_icount)(struct tty_struct *, struct serial_icounter_struct *); /* 232 8 */
const struct file_operations * proc_fops; /* 240 8 */

/* size: 248, cachelines: 4, members: 31 */
/* last cacheline: 56 bytes */
};

work_for_cpu_fn

4.4.72

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static void work_for_cpu_fn(struct work_struct *work)
{
struct work_for_cpu *wfc = container_of(work, struct work_for_cpu, work);

wfc->ret = wfc->fn(wfc->arg);
}
#define container_of(ptr, type, member) ({ \
const typeof(((type *)0)->member)*__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); })
struct work_for_cpu {
struct work_struct work; /* 0 32 */
long int (*fn)(void *); /* 32 8 */
// ^[4]
void * arg; /* 40 8 */
long int ret; /* 48 8 */

/* size: 56, cachelines: 1, members: 4 */
/* last cacheline: 56 bytes */
};

需要设置好参数指向的结构体

seq_file

4.4.72

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
struct seq_file {
char * buf; /* 0 8 */
size_t size; /* 8 8 */
size_t from; /* 16 8 */
size_t count; /* 24 8 */
size_t pad_until; /* 32 8 */
loff_t index; /* 40 8 */
loff_t read_pos; /* 48 8 */
u64 version; /* 56 8 */
/* --- cacheline 1 boundary (64 bytes) --- */
struct mutex lock; /* 64 40 */

/* XXX last struct has 4 bytes of padding */

const struct seq_operations * op; /* 104 8 */
int poll_event; /* 112 4 */

/* XXX 4 bytes hole, try to pack */

void * private; /* 120 8 */

/* size: 128, cachelines: 2, members: 12 */
/* sum members: 124, holes: 1, sum holes: 4 */
/* paddings: 1, sum paddings: 4 */
};

seq_file结构体是由特定内存池分配不好控制
但是会从kmalloc-32当中分配内存来储存struct seq_operations

allinone.sh

kernel_unpack & kernel_run

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
printf "\x1b[33;3m"
printf "\t\t\tKERNEL_UNPACK & KERNEL_RUN\x0a" # this is a command
printf "\x1b[0m"
#printf "\x1b[34;1mhint"
#ls # hint
#printf "\x0a\x1b[0m"

######################### your dirname ##########################
DIRNAME="core"

error(){
printf "\x1b[31;1m"
printf "ERROR: "
printf "%s" "$1"
printf "\x1b[0m\x0a"
}

underline(){
printf "\x1b[33;1m"
printf "[*]: "
printf "%s" "$1"
printf "\x1b[0m\x0a"
}

get_cpio(){
printf "file .cpio:\x0a"
local idx=1
for file in ./*.cpio;do
printf "\t[%d] " "${idx}"
idx=$((idx+1))
if file "$file" | grep "cpio archive";then
FILE_NAME=$(basename "$file")
#printf "[%d] FILE_NAME is %s\x0a" "${FILE_NAME}"
fi
done
}

get_cpio

if [ "$1" = "new" ];then
if ! mkdir ./$DIRNAME 2>/dev/null;then
error "already md %s" "$DIRNAME"
exit 1
fi
cd ./$DIRNAME
#printf "pls input the file system >>"
#read FILE_NAME
cpio -idv < "../${FILE_NAME}"
######################### your exp.c ##########################
cp ~/pwntoolsallinone/pwwn.c ./pwwn.c
cd ..
if [ ! -f ./vmlinux ];then
if ! vmlinux-to-elf ./bzImage ./vmlinux 2>/dev/null;then
error "get vmlinux failed"
fi
fi
######################### your gdb.sh ##########################
if [ ! -f ./gdb.sh ];then
cp ~/pwntoolsallinone/gdb.sh ./gdb.sh
fi
exit 1
fi

if [ -z "$1" ];then
if ! cd ./$DIRNAME 2>/dev/null;then
error "pls md first !\x0a"
exit 1
fi
######################### your gcc cmd ##########################
if ! gcc -g -o pwwn ./pwwn.c ~/pwnlib.c -I ~ -masm=intel -static;then
exit 1
fi
printf "\x0a"
echo -e "gcc ok"
find . | cpio -ov -H newc > "../${FILE_NAME}"
cd ..
if [ -x ./run.sh ];then
./run.sh
elif [ -x ./start.sh ];then
./start.sh
else
error "no run.sh & start.sh"
fi
exit 1
fi

gdb.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/sh

cat > /tmp/gdb_tmp <<EOF
target remote localhost:1234

add-symbol-file ./vmlinux
add-symbol-file ./core/pwwn

b main
c
EOF
############################# your cmd ###################################
cmd.exe /c start wsl.exe -d Ubuntu-22.04 -- bash -c "gdb -x /tmp/gdb_tmp"

pwwn.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "pwnlib.h"

int fd = 0;

void init_func(){
setvbuf(stdin,NULL,_IONBF,0);
setvbuf(stdout,NULL,_IONBF,0);
setvbuf(stderr,NULL,_IONBF,0);
//fd = open("",O_RWDR);
//if (fd < 0){error("can't open target file");}
}

void main(){
init_func();
underline("end form main");
}

kernel头文件

pwnlib.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#ifndef MYLIB_H
#define MYLIB_H
#define _GNU_SOURCE

#include <sys/syscall.h> // 提供 syscall() 和 __NR_add
#include <stdio.h>
#include <stdlib.h> // malloc() ...
#include <string.h> // strcpy() ...
#include <unistd.h> // getuid() ...
#include <fcntl.h> // fcntl() ...
#include <stdarg.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/tty.h>
#include <pthread.h>
#include <poll.h>
#include <errno.h>
#include <linux/userfaultfd.h>
#include <signal.h>
#include <sched.h>
#include <unistd.h>
#include <keyutils.h>


#include <sys/types.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <poll.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <sys/sem.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <poll.h>
#include <sched.h>
extern size_t user_cs, user_ss, user_sp, user_rflags;

void cprint(const char *prefix, const char *color, const char *fmt, ...);

#define success(fmt, ...) cprint("[+]", "\x1b[3;35m", fmt, ##__VA_ARGS__)
#define underline(fmt, ...) cprint("[*]", "\x1b[3;33m", fmt, ##__VA_ARGS__)
#define log(fmt, ...) cprint("[=]", "\x1b[3;32m", fmt, ##__VA_ARGS__)
#define error(fmt, ...) cprint("[!]", "\x1b[3;31m", fmt, ##__VA_ARGS__)

void debug(void);
void getshell(void);
void save(void);
int64_t key_alloc(void *description,void *payload,size_t payload_len);
int64_t key_read(size_t key_id,void *retbuf,size_t payload_len);
int64_t key_revoke(size_t key_id);
void bind_core(int core);
#endif

pwnlib.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "pwnlib.h"

size_t user_cs, user_rflags, user_sp, user_ss;

void cprint(const char *prefix, const char *color, const char *fmt, ...) {
va_list args;
printf("%s%s", color, prefix);
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
printf("\x1b[0m\n");
}

void save(void){
asm volatile(
"mov user_cs, cs;"
"mov user_ss, ss;"
"mov user_sp, rsp;"
"pushf;"
"pop user_rflags;"
);
log("have saved!");

}
void getshell(void){
if(getuid() != 0){
error("uid is not 0 !!!");
underline("Wating...");
sleep(5);
exit(0);
}
success("welcome ROOT !!!");
system("/bin/sh");
exit(0);
}

void debug(void){
underline("DEBUG!!!");
__asm__(
"xor eax,eax;"
"syscall;"
);
}

// key system

int64_t key_alloc(void *description,void *payload,size_t payload_len){
return syscall(
__NR_add_key,
"user",
description,
payload,
payload_len,
KEY_SPEC_PROCESS_KEYRING
);
}

int64_t key_read(size_t key_id,void *retbuf,size_t retbuf_len){
return syscall(__NR_keyctl,KEYCTL_READ,key_id,retbuf,retbuf_len);
}

int64_t key_revoke(size_t key_id){
return syscall(__NR_keyctl,KEYCTL_REVOKE,key_id,0,0,0);
}

void bind_core(int core){
cpu_set_t cpu_set;

CPU_ZERO(&cpu_set);
CPU_SET(core, &cpu_set);
sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set);

printf("\033[34m\033[1m[*] Process binded to core \033[0m%d\n", core);
}

// key end