Post

(kernel) current 구조체 / cred 수정

struct task_struct current

/v4.13.8/source/include/linux/sched.h#L519

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
   

struct task\_struct {
#ifdef CONFIG\_THREAD\_INFO\_IN\_TASK
/\*
\* For reasons of header soup (see current\_thread\_info()), this
\* must be the first element of task\_struct.
\*/
struct thread\_info
thread\_info;
#endif
/\* -1 unrunnable, 0 runnable, >0 stopped: \*/
volatile long
state;
.....................................................................
#ifdef CONFIG\_CC\_STACKPROTECTOR
/\* Canary value for the -fstack-protector GCC feature: \*/
unsigned long
stack\_canary;
#endif
.....................................................................
/\* Process credentials: \*/

  

/\* Tracer's credentials at attach: \*/
const struct cred \_\_rcu
\*ptracer\_cred;

  

/\* Objective and real subjective task credentials (COW): \*/
const struct cred \_\_rcu
\*real\_cred;

  

/\* Effective (overridable) subjective task credentials (COW): \*/
const struct cred \_\_rcu
\*cred;
.....................................................................
struct thread\_struct
thread;
};
  • current 구조체는 별 다른 선언 없이 바로 접근 할 수 있다.

cred 수정

const로 선언되어 있기 때문에 current->cred로 접근해서는 수정할 수 없다. 그러나 이런 식으로 우회할 수 있다.

1
2
3
4
5
6
7
8
9
asmlinkage void modi\_cred(void){
struct cred \_\_rcu \*fake\_cred = current->cred;
printk("before cred uid : %d\n", fake\_cred->uid);
fake\_cred->uid.val = 0;
fake\_cred->gid.val = 0;
fake\_cred->euid.val = 0;
fake\_cred->egid.val = 0;
printk("after cred uid : %d\n", fake\_cred->uid);
}

Note ) sys\_write()같이 다양한 권한의 프로세스에서 매우 빈번하게 호출되는 함수를 hooking해 cred를 수정할 경우, sys_write()를 호출하는 모든 프로세스의 cred가 변경되기 때문에 hooking 코드에 별 문제가 없어도 Oops가 발생할 수 있다.

real_cred VS cred

LINUX에서는 한 task가 다른 task에 접근할 때 작용하는 권한과, 다른 task가 이 task에 접근하기 위해서 가지고 있어야 하는 권한을 분리해 놓았다.

real_cred : The objective context of a task. These parts are used when some other task is attempting to affect this one.

다른 task가 이 task에 접근하기 위해서 가지고 있어야 하는 권한을 의미한다.

cred : The subjective context. These details are used when the task is acting upon another object, be that a file, a task, a key or whatever.

이 task가 다른 task에 접근하거나, 특정 작업을 수행할 때 행사하는 권한을 의미한다. 일시적으로 다른 security context를 가리키도록 override 될 수 있으나 기본적으로 current->cred == current->real_cred다.

따라서, 권한 상승의 경우 cred로 접근해야 하는게 맞지만 일반적인 경우 둘은 같은 구조체를 가리키고 있기 때문에 둘 중 어느 쪽으로 접근해서 수정해도 권한 상승이 가능하다.

This post is licensed under CC BY 4.0 by the author.