Recent Posts
Recent Comments
Link
«   2024/11   »
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
Tags
more
Archives
Today
Total
관리 메뉴

CIDY

[System_Hacking] Tasks 본문

Hack/DreamHack

[System_Hacking] Tasks

CIDY 2023. 5. 20. 04:07

task


리눅스의 태스크는 프로그램 실행 단위를 말한다. 사용자가 어떤 프로그램을 실행하면 태스크가 생성되고, 그 프로그램의 코드가 실행된다. 리눅스에서는 하나의 프로세스와 스레드가 각각의 태스크가 된다.

 

대부분 운영체제는 여러 태스크를 생성해두고, 각 태스크에 실행 시간을 배분하는 방식으로 태스크를 관리한다. 다수의 태스크를 관리하는것을 멀티 태스킹(Multitasking), 실행 시간을 배분하는 것을 스케줄링(Scheduling)이라고 한다.

 

각 태스크는 커널 메모리에 task_struct구조체로 표현되는데, 이 구조체에는 태스크의 여러 정보가 저장되어 있다. 그 중에는 사용자 신원, 권한에 대한 정보도 포함되어 있어서, 이를 조작하는 것이 커널 익스플로잇의 목표가 되기도 한다.

 

 

리눅스 권한


리눅스는 운영체제의 사용자를 32비트 정수값인 UID(User ID)로 식별한다. 명시적 허용이 없는 한, 각 사용자는 다른 사용자의 자원에 접근할 수 없다.(권한 분리) 하지만 UID값으로 0을 갖는 root사용자는 최고 관리자(superuser)로, 다른 사용자의 자원에 임의로 접근할 수 있다.

 

출처 : dreamhack.io

권한 상승(root권한 탈취)은 커널 익스플로잇의 주된 목적 중 하나이다. 이를 LPE(Local Privilege Escalation)이라고 한다. 권한 상승 방법은 다양한데, 그 중 하나가 태스크 구조체 조작이다.

 

태스크 구조체는 커널 메모리에 위치하여 태스크의 신원 정보 등을 기록해둔다. 가령 uid=1000인 사용자가 사용하는 쉘 프로그램은 신원 정보가 uid=1000으로 기록되어 있다. 만약 이를 0으로 조작할 수 있다면 사용자는 root유저가 될 수 있을 것이다.

 

따라서 오직 커널 권한의 프로세스만이 커널 메모리를 읽거나 조작할 수 있도록 엄격하게 관리하고 있다. (root권한의 프로세스도 커널 메모리에 접근하는 것은 불가하다.)

 

 

태스크 구조체


리눅스 커널은 task_struct구조체에 정보를 담고 있다. 이 구조체는 커널 메모리에 존재하며, 프로세스의 메모리 맵, 파일 디스크립터, 프로세스 권한 등의 정보를 저장한다.

 

// Permal link: https://github.com/torvalds/linux/blob/219d54332a09e8d8741c1e1982f5eae56099de85/include/linux/sched.h#L624:L1284
struct task_struct {
...
	volatile long			state;
...
	struct list_head		tasks;
...
	struct mm_struct		*mm;
...
	/* Effective (overridable) subjective task credentials (COW): */
	const struct cred __rcu		*cred;
...
	char				comm[TASK_COMM_LEN];
...
	/* Open file information: */
	struct files_struct		*files;
	
...
}

task_struct구조체는 리눅스 커널 소스 트리에서 include/linux/sched.h 에 저장되어 있다.

state 현재 태스크 실행 상태. 0은 실행 중이거나 실행(스케줄) 가능한 상태, 양수면 태스크 정지 or 대기 중
tasks 태스크 연결 리스트 노드(커널에 존재)
mm mm_struct는 사용자 메모리 영역(주소공간) 정보를 담은 구조체이다. (보통 같은 프로세스의 스레드는 모두 mm이 같다.)
cred 현재 태스크의 신원 정보를 가리키는 포인터
comm 실행 파일 or 스레드 이름을 저장
files 열린 파일 디스크립터 정보들. 보통 같은 프로세스 내의 스레드는 모두 files가 같다.

 

// Permal link: https://github.com/torvalds/linux/blob/219d54332a09e8d8741c1e1982f5eae56099de85/include/linux/cred.h#L111:L153
struct cred {
	atomic_t	usage;
...
	kuid_t		uid;		/* real UID of the task */
	kgid_t		gid;		/* real GID of the task */
	kuid_t		suid;		/* saved UID of the task */
	kgid_t		sgid;		/* saved GID of the task */
	kuid_t		euid;		/* effective UID of the task */
	kgid_t		egid;		/* effective GID of the task */
	kuid_t		fsuid;		/* UID for VFS ops */
	kgid_t		fsgid;		/* GID for VFS ops */
	unsigned	securebits;	/* SUID-less security management */
	kernel_cap_t	cap_inheritable; /* caps our children can inherit */
	kernel_cap_t	cap_permitted;	/* caps we're permitted */
	kernel_cap_t	cap_effective;	/* caps we can actually use */
	kernel_cap_t	cap_bset;	/* capability bounding set */
	kernel_cap_t	cap_ambient;	/* Ambient capability set */
...
}

이 중 권한 상승에 중요한 것은 현재 태스크의 신원 정보 포인터인 cred필드이다. 

usage cred 참조 카운터. 하나의 cred 구조체는 여러 개의 프로세스에서 동시에 사용될 수 있다.
uid 프로세스를 소유하고 있는 사용자 ID(User ID, UID). 0으로 조작하면 그 태스크는 root 권한을 획득할 수 있다.
euid 실효적인 사용자 ID(Effective User ID, EUID). 권한 검사에 실제 사용되는 값으로, 0으로 조작하면 그 태스크는 root 권한을 가진다. (보통 uid와 동일)
gid, egid Real GID, Effective GID이다. (GID : group id, 그룹 식별번호)

 

 

권한 상승


우선 gdb부착 옵션을 넣고 가상 머신을 부팅한 뒤, echo $$ 명령어로 현재 쉘의 pid를 출력하자.

 

그런 다음 gdb에서 위 명령어들로 현재 쉘 task의 task_struct를 조회할 수 있다.

$lx_current() 선택된 CPU 코어의 현재 프로세스 또는 스레드의 태스크 구조체 반환
$lx_task_by_pid(<PID>) 프로세스 식별자(PID)가 <PID> 인 프로세스 또는 스레드의 태스크 구조체 반

위 함수들 역시 vmlinux-gdb.py 스크립트로 사용할 수 있는 것이다. 

 

0x3e8은 1000이다. 위 정보로부터 해당 프로세스 이름이 bash이고, uid가 1000(dreamhack)이라는 것을 확인할 수 있다.

 

gdb로 euid를 0으로 바꿔보자.

 

위 사진은 gdb명령어를 실행하기 전후이다. euid가 root를 뜻하는 0으로 바뀐 것을 볼 수 있다. 

위 상태에서 sudo없이 cat /etc/shadow를 해도 읽을 수 있다. (해당 파일은 root만 읽을 수 있다.)

 

물론 현실에서는 당연히 불가능한 방법이다.

 

 

Ref.


https://dreamhack.io/lecture/courses/56

 

Background: Tasks

리눅스 태스크와 태스크 구조체에 대해 배우고, 태스크 구조체가 조작됐을 때 발생할 수 있는 위험에 대해 배웁니다.

dreamhack.io

 

'Hack > DreamHack' 카테고리의 다른 글

[System_Hacking] awesome-basics  (0) 2023.07.04
[System_Hacking] mmapped  (0) 2023.07.04
[System_Hacking] Linux Exploitation  (0) 2023.05.16
[System_Hacking] Logical Bug  (0) 2023.05.15
[System_Hacking] STB-lsExecutor  (0) 2023.04.09