1 of 104

Linux & Security

2021-11-15 @ KNI Kernel AGH UST

By Disconnect3d

1

2 of 104

# whoami

  • Absolwent (mgr inż) WFiIS AGH
  • Kiedyś prezes KNI Kernel :)
  • Senior Security Engineer @ Trail of Bits
  • Kapitan teamu CTFowego justCatTheFish

�@disconnect3d_pl�https://disconnect3d.pl/

3 of 104

#sponsors

3

4 of 104

4

5 of 104

Trail of Bits

Blog: https://blog.trailofbits.com/ oraz https://trailofbits.com/

  • Assurance (AppSec, Cryptography, Blockchain)
  • Engineering
  • Research & Development

Sporo klientów/produktów:�Kubernetes, HashiCorp, Microsoft, Zoom, Parity, blockchainy, etc.

Publikacje: https://github.com/trailofbits/publications

Ofc zatrudniamy, również na płatne staże (full remote): https://jobs.lever.co/trailofbits/

5

6 of 104

6

7 of 104

User Space vs Kernel Space

7

8 of 104

User Space vs Kernel Space

8

9 of 104

User Space vs Kernel Space

9

IZOLACJA

+ kernel może “wszystko”

10 of 104

Jak to właściwie jest odseparowane?

==> ficzery architektur procesorów!

10

11 of 104

Intel Architecture Protection Rings

Via https://en.wikipedia.org/wiki/Protection_ring

11

12 of 104

Intel Architecture Protection Rings

Via https://en.wikipedia.org/wiki/Protection_ring

12

FWIW de facto tylko ring0 i ring3 są używane �w Linuxie*

13 of 104

ARM privilege/exception levels

13

14 of 104

ARM privilege/exception levels

14

Kernel space

User space

15 of 104

Wywołania systemowe�(syscalle)

czyli sposób na gadanie z kernelem

15

16 of 104

Syscalle

  1. Wywołania systemowe aka “syscalle”
    1. fopen (3) woła open (2)
  2. Możemy to podejrzeć
    • Strace, ltrace
    • Bonus (unrelated): pspy
  3. Syscall table ftw
  4. Ciekawe syscalle:
    • ioctl - customowa komunikacja z urządzeniami
    • socket - może załadować moduł kernela jako efekt uboczny

16

#include <stdio.h>

int main() {

FILE* fp = fopen("plik", "w");

// TODO: check fp == NULL

fwrite("content", 4, 1, fp);

fclose(fp);

}

17 of 104

Syscalle

  • Wywołania systemowe aka “syscalle”
    • fopen (3) woła open (2) albo openat(2)

17

#include <stdio.h>

int main() {

FILE* fp = fopen("plik", "w");

// TODO: check fp == NULL

fwrite("content", 4, 1, fp);

fclose(fp);

}

* zadziała tylko jak jest wyłączone FULL RELRO

18 of 104

Syscalle

  • Wywołania systemowe aka “syscalle”
    • fopen (3) woła open (2) albo openat(2)
  • Możemy je podejrzeć
    • Strace, ltrace*
      1. strace strace 🙃
    • Bonus (unrelated): pspy
  • Syscall table ftw
  • Ciekawe syscalle:
    • ioctl - customowa komunikacja z urządzeniami
    • socket - może załadować moduł kernela jako efekt uboczny

18

#include <stdio.h>

int main() {

FILE* fp = fopen("plik", "w");

// TODO: check fp == NULL

fwrite("content", 4, 1, fp);

fclose(fp);

}

* zadziała tylko jak jest wyłączone FULL RELRO

19 of 104

Syscalle

19

#include <stdio.h>

int main() {

FILE* fp = fopen("plik", "w");

// TODO: check fp == NULL

fwrite("content", 4, 1, fp);

fclose(fp);

}

* zadziała tylko jak jest wyłączone FULL RELRO

20 of 104

Syscalle

20

#include <stdio.h>

int main() {

FILE* fp = fopen("plik", "w");

// TODO: check fp == NULL

fwrite("content", 4, 1, fp);

fclose(fp);

}

* zadziała tylko jak jest wyłączone FULL RELRO

21 of 104

21

22 of 104

Socket ładujący moduł kernela

#include <sys/socket.h>

#include <netatalk/at.h>

�int main() {

int ddp_socket = socket(AF_APPLETALK, SOCK_DGRAM, 0);

printf("ddp_socket = %d\n", ddp_socket);

}

// DEMO

22

23 of 104

Socket ładujący moduł kernela

#include <sys/socket.h>

#include <netatalk/at.h>

�int main() {

int ddp_socket = socket(AF_APPLETALK, SOCK_DGRAM, 0);

printf("ddp_socket = %d\n", ddp_socket);

}

23

24 of 104

User w Linuxie

24

25 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ ps auxf

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.0 0.0 164728 11128 ? Ss 18:05 0:00 /sbin/init splash

root 2 0.0 0.0 0 0 ? S 18:05 0:00 [kthreadd]

root 3 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [rcu_gp]

root 4 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [rcu_par_gp]

root 6 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [kworker/0:0H-events_highpri]

[...]

root 1904 0.0 0.0 3148532 12600 ? Sl 18:05 0:01 /opt/teamviewer/tv_bin/teamviewerd -d

dc 2274 0.0 0.0 16240 9676 ? Ss 18:06 0:00 /lib/systemd/systemd --user

dc 5302 0.0 0.0 739576 45856 ? Sl 18:07 0:00 | \_ update-notifier

dc 2520 1.4 0.2 3905684 368372 ? Ssl 18:06 0:36 \_ /usr/bin/gnome-shell

dc 2541 0.0 0.0 320992 11724 ? Sl 18:06 0:00 | \_ ibus-daemon --panel disable --xim

dc 2546 0.0 0.0 243612 7504 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-dconf

dc 2547 0.0 0.0 279276 30560 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-extension-gtk3

dc 2810 0.0 0.0 169780 7384 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-engine-simple

dc 6412 0.1 0.0 771148 71224 ? Sl 18:10 0:03 | \_ /usr/bin/python3 /usr/bin/terminator

dc 6437 0.0 0.0 17396 6016 pts/0 Ss 18:10 0:00 | | \_ /bin/bash

dc 9009 0.0 0.0 18892 4256 pts/0 R+ 18:46 0:00 | | | \_ ps auxf

25

26 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ ps auxf

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.0 0.0 164728 11128 ? Ss 18:05 0:00 /sbin/init splash

root 2 0.0 0.0 0 0 ? S 18:05 0:00 [kthreadd]

root 3 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [rcu_gp]

root 4 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [rcu_par_gp]

root 6 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [kworker/0:0H-events_highpri]

[...]

root 1904 0.0 0.0 3148532 12600 ? Sl 18:05 0:01 /opt/teamviewer/tv_bin/teamviewerd -d

dc 2274 0.0 0.0 16240 9676 ? Ss 18:06 0:00 /lib/systemd/systemd --user

dc 5302 0.0 0.0 739576 45856 ? Sl 18:07 0:00 | \_ update-notifier

dc 2520 1.4 0.2 3905684 368372 ? Ssl 18:06 0:36 \_ /usr/bin/gnome-shell

dc 2541 0.0 0.0 320992 11724 ? Sl 18:06 0:00 | \_ ibus-daemon --panel disable --xim

dc 2546 0.0 0.0 243612 7504 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-dconf

dc 2547 0.0 0.0 279276 30560 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-extension-gtk3

dc 2810 0.0 0.0 169780 7384 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-engine-simple

dc 6412 0.1 0.0 771148 71224 ? Sl 18:10 0:03 | \_ /usr/bin/python3 /usr/bin/terminator

dc 6437 0.0 0.0 17396 6016 pts/0 Ss 18:10 0:00 | | \_ /bin/bash

dc 9009 0.0 0.0 18892 4256 pts/0 R+ 18:46 0:00 | | | \_ ps auxf

26

27 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ ps auxf

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.0 0.0 164728 11128 ? Ss 18:05 0:00 /sbin/init splash

root 2 0.0 0.0 0 0 ? S 18:05 0:00 [kthreadd]

root 3 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [rcu_gp]

root 4 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [rcu_par_gp]

root 6 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [kworker/0:0H-events_highpri]

[...]

root 1904 0.0 0.0 3148532 12600 ? Sl 18:05 0:01 /opt/teamviewer/tv_bin/teamviewerd -d

dc 2274 0.0 0.0 16240 9676 ? Ss 18:06 0:00 /lib/systemd/systemd --user

dc 5302 0.0 0.0 739576 45856 ? Sl 18:07 0:00 | \_ update-notifier

dc 2520 1.4 0.2 3905684 368372 ? Ssl 18:06 0:36 \_ /usr/bin/gnome-shell

dc 2541 0.0 0.0 320992 11724 ? Sl 18:06 0:00 | \_ ibus-daemon --panel disable --xim

dc 2546 0.0 0.0 243612 7504 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-dconf

dc 2547 0.0 0.0 279276 30560 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-extension-gtk3

dc 2810 0.0 0.0 169780 7384 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-engine-simple

dc 6412 0.1 0.0 771148 71224 ? Sl 18:10 0:03 | \_ /usr/bin/python3 /usr/bin/terminator

dc 6437 0.0 0.0 17396 6016 pts/0 Ss 18:10 0:00 | | \_ /bin/bash

dc 9009 0.0 0.0 18892 4256 pts/0 R+ 18:46 0:00 | | | \_ ps auxf

27

28 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ ps auxf

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0.0 0.0 164728 11128 ? Ss 18:05 0:00 /sbin/init splash

root 2 0.0 0.0 0 0 ? S 18:05 0:00 [kthreadd]

root 3 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [rcu_gp]

root 4 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [rcu_par_gp]

root 6 0.0 0.0 0 0 ? I< 18:05 0:00 \_ [kworker/0:0H-events_highpri]

[...]

root 1904 0.0 0.0 3148532 12600 ? Sl 18:05 0:01 /opt/teamviewer/tv_bin/teamviewerd -d

dc 2274 0.0 0.0 16240 9676 ? Ss 18:06 0:00 /lib/systemd/systemd --user

dc 5302 0.0 0.0 739576 45856 ? Sl 18:07 0:00 | \_ update-notifier

dc 2520 1.4 0.2 3905684 368372 ? Ssl 18:06 0:36 \_ /usr/bin/gnome-shell

dc 2541 0.0 0.0 320992 11724 ? Sl 18:06 0:00 | \_ ibus-daemon --panel disable --xim

dc 2546 0.0 0.0 243612 7504 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-dconf

dc 2547 0.0 0.0 279276 30560 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-extension-gtk3

dc 2810 0.0 0.0 169780 7384 ? Sl 18:06 0:00 | | \_ /usr/libexec/ibus-engine-simple

dc 6412 0.1 0.0 771148 71224 ? Sl 18:10 0:03 | \_ /usr/bin/python3 /usr/bin/terminator

dc 6437 0.0 0.0 17396 6016 pts/0 Ss 18:10 0:00 | | \_ /bin/bash

dc 9009 0.0 0.0 18892 4256 pts/0 R+ 18:46 0:00 | | | \_ ps auxf

28

29 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

29

30 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

30

31 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

31

32 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

32

33 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

33

34 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

^-- opis formatu w: man 5 passwd

34

35 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

^-- opis formatu w: man 5 passwd

dc@dc:~$ cat /etc/shadow

cat: /etc/shadow: Permission denied

dc@dc:~$ sudo cat /etc/shadow

root:!:18859:0:99999:7:::

daemon:*:18737:0:99999:7:::

bin:*:18737:0:99999:7:::

sys:*:18737:0:99999:7:::

[...]

dc:$6$joW3tLtIp1eZE2/y$w5y**REDACTED**zQn2pUoK3.:18859:0:99999:7:::

35

36 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

^-- opis formatu w: man 5 passwd

dc@dc:~$ cat /etc/shadow

cat: /etc/shadow: Permission denied

dc@dc:~$ sudo cat /etc/shadow

root:!:18859:0:99999:7:::

daemon:*:18737:0:99999:7:::

bin:*:18737:0:99999:7:::

sys:*:18737:0:99999:7:::

[...]

dc:$6$joW3tLtIp1eZE2/y$w5y**REDACTED**zQn2pUoK3.:18859:0:99999:7:::

36

37 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

^-- opis formatu w: man 5 passwd

dc@dc:~$ cat /etc/shadow

cat: /etc/shadow: Permission denied

dc@dc:~$ sudo cat /etc/shadow

root:!:18859:0:99999:7:::

daemon:*:18737:0:99999:7:::

bin:*:18737:0:99999:7:::

sys:*:18737:0:99999:7:::

[...]

dc:$6$joW3tLtIp1eZE2/y$w5y**REDACTED**zQn2pUoK3.:18859:0:99999:7:::

37

38 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

^-- opis formatu w: man 5 passwd

dc@dc:~$ cat /etc/shadow

cat: /etc/shadow: Permission denied

dc@dc:~$ sudo cat /etc/shadow

root:!:18859:0:99999:7:::

daemon:*:18737:0:99999:7:::

bin:*:18737:0:99999:7:::

sys:*:18737:0:99999:7:::

[...]

dc:$6$joW3tLtIp1eZE2/y$w5y**REDACTED**zQn2pUoK3.:18859:0:99999:7:::

38

39 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

^-- opis formatu w: man 5 passwd

dc@dc:~$ cat /etc/shadow

cat: /etc/shadow: Permission denied

dc@dc:~$ sudo cat /etc/shadow

root:!:18859:0:99999:7:::

daemon:*:18737:0:99999:7:::

bin:*:18737:0:99999:7:::

sys:*:18737:0:99999:7:::

[...]

dc:$6$joW3tLtIp1eZE2/y$w5y**REDACTED**zQn2pUoK3.:18859:0:99999:7:::

39

40 of 104

Nazwa usera to tylko abstrakcja

dc@dc:~$ cat /etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

[...]

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin

syslog:x:104:110::/home/syslog:/usr/sbin/nologin

_apt:x:105:65534::/nonexistent:/usr/sbin/nologin

dc:x:1000:1000:dc,,,:/home/dc:/bin/bash

[...]

^-- opis formatu w: man 5 passwd

dc@dc:~$ cat /etc/shadow

cat: /etc/shadow: Permission denied

dc@dc:~$ sudo cat /etc/shadow

root:!:18859:0:99999:7:::

daemon:*:18737:0:99999:7:::

bin:*:18737:0:99999:7:::

sys:*:18737:0:99999:7:::

[...]

dc:$6$joW3tLtIp1eZE2/y$w5y**REDACTED**zQn2pUoK3.:18859:0:99999:7:::

^-- opis formatu w: man 5 shadow

Również:

  • man 3 crypt
  • man 5 crypt
  • Regex pola z hasłem
  • “$6$” === sha512crypt here
  • ...ale można używać gorszych algorytmów
    • Niektóre IoT...

40

41 of 104

Wracając do “nazwa usera to tylko abstrakcja”

41

42 of 104

W kernel nie ma nazwy użytkowników:�jest za to struct_task i cred

42

43 of 104

struct task_struct

struct task_struct {

int exit_code;

pid_t pid;

/* 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;

/* Used by LSM modules for access restriction: */

void *security;

/* CPU-specific state of this task: */

struct thread_struct thread;

https://elixir.bootlin.com/linux/v5.15.2/source/include/linux/sched.h#L723

43

=== struktura która istnieje dla każdego procesu/wątku (+wątków kernela)

44 of 104

struct task_struct

struct task_struct {

int exit_code;

pid_t pid;

/* 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;

/* Used by LSM modules for access restriction: */

void *security;

/* CPU-specific state of this task: */

struct thread_struct thread;

https://elixir.bootlin.com/linux/v5.15.2/source/include/linux/sched.h#L723

44

=== czyli to co zwraca funkcja “main” w C

45 of 104

struct task_struct

struct task_struct {

int exit_code;

pid_t pid;

/* 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;

/* Used by LSM modules for access restriction: */

void *security;

/* CPU-specific state of this task: */

struct thread_struct thread;

https://elixir.bootlin.com/linux/v5.15.2/source/include/linux/sched.h#L723

45

=== Process Identifier (PID)

46 of 104

Problemy z PIDami...

46

47 of 104

Problemy z PIDami...

47

48 of 104

Problemy z PIDami...

48

== PIDy są inkrementalne (na Linuxie)

49 of 104

Problemy z PIDami...

49

== PIDy są inkrementalne (na Linuxie)

  • $ sysctl kernel.pid_max

kernel.pid_max = 32768

50 of 104

Problemy z PIDami...

50

== PIDy są inkrementalne (na Linuxie)

  • $ sysctl kernel.pid_max

kernel.pid_max = 32768

Co gdy wykorzystamy?

51 of 104

Problemy z PIDami...

51

== PIDy są inkrementalne (na Linuxie)

  • $ sysctl kernel.pid_max

kernel.pid_max = 32768

Co gdy wykorzystamy?

int main() {

while (1) {

int p = fork();

if (p <= 0) break;

printf("PID = %d\n", p);

wait(NULL);

}

}

// może wymagać uruchomienia kilka razy / przykład via https://saelo.github.io/presentations/warcon18_dont_trust_the_pid.pdf

52 of 104

Problemy z PIDami...

52

== PIDy są inkrementalne (na Linuxie)

  • $ sysctl kernel.pid_max

kernel.pid_max = 32768

Co gdy wykorzystamy?

...

PID = 32765

PID = 32766

PID = 32767

PID = 300

PID = 301

PID = 302

PID = 303

...

int main() {

while (1) {

int p = fork();

if (p <= 0) break;

printf("PID = %d\n", p);

wait(NULL);

}

}

// może wymagać uruchomienia kilka razy / przykład via https://saelo.github.io/presentations/warcon18_dont_trust_the_pid.pdf

“overflow”

53 of 104

Problemy z PIDami...

53

  • $ sysctl kernel.pid_max

kernel.pid_max = 32768

  • Sporo akcji w systemie wykonuje się ”na PIDach”

(wysyłanie sygnałów, wyświetlanie o nich info, ptrace, dodawanie do cgroup, itd.)

== PIDy są inkrementalne (na Linuxie)

54 of 104

===> pid-reuse attack

  1. Jakaś usługa robi:� int pid = client->pid;� if (security_check(action, pid)) {� perform_action(client);� }

Przykład za https://saelo.github.io/presentations/warcon18_dont_trust_the_pid.pdf

54

55 of 104

===> pid-reuse attack

  • Jakaś usługa robi:� int pid = client->pid;� if (security_check(action, pid)) {� perform_action(client);� }

2. Co jeśli PO security_check dany PID umrze i pojawi się inny na jego miejscu?

Przykład za https://saelo.github.io/presentations/warcon18_dont_trust_the_pid.pdf

55

56 of 104

===> pid-reuse attack

  • Jakaś usługa robi:� int pid = client->pid;� if (security_check(action, pid)) {� perform_action(client);� }

2. Co jeśli PO security_check dany PID umrze i pojawi się inny na jego miejscu?

3. ...i jeśli perform_action daje coś danemu PIDowi? :)

Przykład za https://saelo.github.io/presentations/warcon18_dont_trust_the_pid.pdf

56

57 of 104

===> pid-reuse attack

  • Jakaś usługa robi:� int pid = client->pid;� if (security_check(action, pid)) {� perform_action(client);� }

2. Co jeśli PO security_check dany PID umrze i pojawi się inny na jego miejscu?

3. ...i jeśli perform_action daje coś danemu PIDowi? :)

===> jeśli atakujący umie sprawić, żeby PID umarł po security_check i

i stworzyć własny proces z danym PID, to może np. zyskać uprawnienia

Przykład za https://saelo.github.io/presentations/warcon18_dont_trust_the_pid.pdf

57

58 of 104

Ja zapobiegać pid-reuse?

TL;DR: pidfd

...taki nowy ficzer kernela, ale nie działa ze wszystkim jeszcze

See also:

LWN: Adding the pidfd abstraction to the kernel

LWN: Completing the pidfd API

58

59 of 104

Wracając do�struct task_struct

59

60 of 104

struct task_struct

struct task_struct {

int exit_code;

pid_t pid;

/* 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;

/* Used by LSM modules for access restriction: */

void *security;

/* CPU-specific state of this task: */

struct thread_struct thread;

https://elixir.bootlin.com/linux/v5.15.2/source/include/linux/sched.h#L723

60

struct cred od “credentials”

Tu siedzi info o “użytkownikach”

61 of 104

struct task_struct

struct task_struct {

int exit_code;

pid_t pid;

/* 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;

/* Used by LSM modules for access restriction: */

void *security;

/* CPU-specific state of this task: */

struct thread_struct thread;

https://elixir.bootlin.com/linux/v5.15.2/source/include/linux/sched.h#L723

61

Dodatkowe info o procesie, używane przez LSMy typu AppArmor/SELinux/Yama etc

62 of 104

struct cred

62

63 of 104

struct cred

63

FWIW tylko debug...

64 of 104

struct cred

64

65 of 104

struct cred

65

66 of 104

struct cred

66

67 of 104

struct cred

67

68 of 104

struct cred

68

69 of 104

struct cred

69

70 of 104

Pliki, uprawnienia

  • suid + sgid + sticky�+ Unix Domain Sockets�+dziwne przypadki… :D

70

71 of 104

Pliki, ich typy i uprawnienia

71

72 of 104

Pliki, ich typy i uprawnienia

72

Typ pliku

73 of 104

Pliki, ich typy i uprawnienia

73

katalog d

unix domain socket s

fifo (named pipe) p

link symboliczny l�zwykły plik -

urządzenie znakowe c

urządzenie blokowe b

Typ pliku

74 of 104

Pliki, ich typy i uprawnienia

74

Uprawnienia� (owner/group/others)

75 of 104

Pliki, ich typy i uprawnienia

75

owner + group

76 of 104

Pliki, ich typy i uprawnienia

76

Rozmiar pliku�LUB

Major + minor device number�(potrzebne do utworzenia pliku urządzenia � przez mknod)

77 of 104

Uprawnienia plików tzn. to całe:

- rwx rw- ---�(owner group other)

�ma 12 bitów

(Mimo że wydawałoby się że 3*3=9)

77

78 of 104

Uprawnienia plików mają 12 bitów

OWNER GROUP OTHER

Bity: 0 0 0 1 1 0 1 1 0 1 0 0

r w x r w x r w x

Inspired by https://twitter.com/b0rk/status/982641594305273856/photo/1

78

79 of 104

Uprawnienia plików mają 12 bitów

OWNER GROUP OTHER

Bity: 0 0 0 1 1 0 1 1 0 1 0 0

r w x r w x r w x

Inspired by https://twitter.com/b0rk/status/982641594305273856/photo/1

79

Read => 4 R+W+X = 7

Write => 2 R+W = 6

eXecute => 1 R = 4

80 of 104

Uprawnienia plików mają 12 bitów

OWNER GROUP OTHER

Bity: 0 0 0 1 1 0 1 1 0 1 0 0

r w x r w x r w x

0 5 5 4

Inspired by https://twitter.com/b0rk/status/982641594305273856/photo/1

80

81 of 104

Btw. jak ustawiamy uprawnienia?

81

82 of 104

Bash: chmod 740 plik

Python: os.chmod("plik", 740)

Go: os.Chmod("plik", 740)

Java: N sposobów...

82

83 of 104

83

84 of 104

Bash: chmod 740 plik

Python: os.chmod("plik", 740)

Go: os.Chmod("plik", 740)

Java: N sposobów...

84

Coś w tym złego?

(DEMO)

85 of 104

Bash: chmod 740 plik

Python: os.chmod("plik", 740)

Go: os.Chmod("plik", 740)

Java: N sposobów...

85

Coś w tym złego?

86 of 104

Czy ktoś tak robi?

86

87 of 104

87

88 of 104

Tak w ogóle kiedy są sprawdzane �uprawnienia do plików?

Przy open?�Czy przy read/write?

88

89 of 104

Tak w ogóle kiedy są sprawdzane �uprawnienia do plików?

Przy open?�Czy przy read/write?

  • Istnieje możliwość przesyłania fd po sockecie

89

90 of 104

Wracając do 12 bitów...

90

91 of 104

Uprawnienia plików mają 12 bitów

setgid

|

|

v OWNER GROUP OTHER

Bity: 0 0 0 1 1 0 1 1 0 1 0 0

^ ^ r w x r w x r w x

| |

| sticky

|

setuid

Inspired by https://twitter.com/b0rk/status/982641594305273856/photo/1

91

92 of 104

Uprawnienia plików mają 12 bitów

A tak się to wyświetla w ‘ls’ (gdyby bity były zapalone):

setgid

|

|

v OWNER GROUP OTHER

Bity: 0 0 0 1 1 0 1 1 0 1 0 0

^ ^ r w x r w x r w x

| |

| sticky

|

setuid

Inspired by https://twitter.com/b0rk/status/982641594305273856/photo/1 & pic from https://linuxhandbook.com/suid-sgid-sticky-bit/

92

93 of 104

“Suidowe binarki”

93

94 of 104

“Suidowe binarki”

94

95 of 104

“Suidowe binarki”

  • Uruchamiając taką binarkę euid procesu będzie taki jak owner pliku

95

96 of 104

“Suidowe binarki”

  • Uruchamiając taką binarkę euid procesu będzie taki jak owner pliku

96

97 of 104

“Suidowe binarki”

  • Uruchamiając taką binarkę euid procesu będzie taki jak owner pliku
    • (Chyba że uruchamiamy pod debuggerem)

97

98 of 104

“Suidowe binarki”

  • Uruchamiając taką binarkę euid procesu będzie taki jak owner pliku
    • (Chyba że uruchamiamy pod debuggerem)
    • Jeśli moglibyśmy nadpisać tę binarkę ⇒ możemy zrobić privilege escalation do roota

98

99 of 104

Jak działa su?

99

100 of 104

Inne “cechy” plików...

100

101 of 104

Inne “cechy” plików...

  • Standardowe ACLe: owner/group/other + suid/sgid/sticky bit
  • Atrybuty plików:
    • chattr +i plik - “immutable bit”
    • lsattr
  • Uprawnienia dla konkretnego usera/grupy:
    • setfacl / getfacl
  • Capabilities dla plików:
    • setcap / getcap
  • SELinux context
    • Wyświetlany za pomocą flagi -Z w ls/ps i innych toolach

101

102 of 104

Dziwne przykłady

102

103 of 104

Dziwne przykłady

  • Katalog “-wx” (bez read)
  • Katalog należący do “user” w którym “innyuser” tworzy plik
  • Kwestie otwierania pliku: man 2 open + flagi
    • O_NOFOLLOW

103

104 of 104

That’s all,

Kk thx bye

104