mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/linux-hardening/privilege-escalation/docker-security/na
This commit is contained in:
parent
7791de8491
commit
34fd14a951
@ -4,7 +4,7 @@
|
||||
|
||||
## Temel Bilgiler
|
||||
|
||||
Linux'taki zaman ad alanı, sistemin monotonik ve önyükleme zamanı saatlerine göre ad alanı başına kaydırmalar sağlar. Genellikle Linux konteynerlerinde, bir konteyner içindeki tarih/saatin değiştirilmesi ve bir kontrol noktasından veya anlık görüntüden geri yüklendikten sonra saatlerin ayarlanması için kullanılır.
|
||||
Linux'taki zaman ad alanı, sistemin monotonik ve önyükleme zamanı saatlerine göre ad alanı başına ofsetler sağlar. Genellikle Linux konteynerlerinde, bir konteyner içindeki tarih/saatin değiştirilmesi ve bir kontrol noktasından veya anlık görüntüden geri yüklendikten sonra saatlerin ayarlanması için kullanılır.
|
||||
|
||||
## Laboratuvar:
|
||||
|
||||
@ -24,19 +24,19 @@ Yeni bir `/proc` dosya sisteminin örneğini `--mount-proc` parametresi ile mont
|
||||
|
||||
1. **Sorun Açıklaması**:
|
||||
|
||||
- Linux çekirdeği, bir sürecin `unshare` sistem çağrısını kullanarak yeni ad alanları oluşturmasına izin verir. Ancak, yeni bir PID ad alanı oluşturan süreç (bu süreç "unshare" süreci olarak adlandırılır) yeni ad alanına girmez; yalnızca onun çocuk süreçleri girer.
|
||||
- `%unshare -p /bin/bash%` komutunu çalıştırmak, `/bin/bash`'i `unshare` ile aynı süreçte başlatır. Sonuç olarak, `/bin/bash` ve onun çocuk süreçleri orijinal PID ad alanındadır.
|
||||
- Linux çekirdeği, bir sürecin yeni ad alanları oluşturmasına `unshare` sistem çağrısı ile izin verir. Ancak, yeni bir PID ad alanı oluşturma işlemini başlatan süreç (bu süreç "unshare" süreci olarak adlandırılır) yeni ad alanına girmez; yalnızca onun çocuk süreçleri girer.
|
||||
- `%unshare -p /bin/bash%` komutu, `/bin/bash`'i `unshare` ile aynı süreçte başlatır. Sonuç olarak, `/bin/bash` ve onun çocuk süreçleri orijinal PID ad alanında kalır.
|
||||
- Yeni ad alanındaki `/bin/bash`'in ilk çocuk süreci PID 1 olur. Bu süreç sona erdiğinde, başka süreç yoksa ad alanının temizlenmesini tetikler, çünkü PID 1, yetim süreçleri benimseme özel rolüne sahiptir. Linux çekirdeği, bu ad alanında PID tahsisini devre dışı bırakır.
|
||||
|
||||
2. **Sonuç**:
|
||||
|
||||
- Yeni bir ad alanındaki PID 1'in çıkışı, `PIDNS_HASH_ADDING` bayrağının temizlenmesine yol açar. Bu, yeni bir süreç oluşturulurken `alloc_pid` fonksiyonunun yeni bir PID tahsis edememesine neden olur ve "Bellek tahsis edilemiyor" hatasını üretir.
|
||||
- Yeni bir ad alanındaki PID 1'in çıkışı, `PIDNS_HASH_ADDING` bayrağının temizlenmesine yol açar. Bu, yeni bir süreç oluşturulurken `alloc_pid` fonksiyonunun yeni bir PID tahsis etmesini engelleyerek "Bellek tahsis edilemiyor" hatasını üretir.
|
||||
|
||||
3. **Çözüm**:
|
||||
- Sorun, `unshare` ile `-f` seçeneğini kullanarak çözülebilir. Bu seçenek, `unshare`'in yeni PID ad alanını oluşturduktan sonra yeni bir süreç fork etmesini sağlar.
|
||||
- `%unshare -fp /bin/bash%` komutunu çalıştırmak, `unshare` komutunun kendisinin yeni ad alanında PID 1 olmasını sağlar. `/bin/bash` ve onun çocuk süreçleri bu yeni ad alanında güvenli bir şekilde yer alır, PID 1'in erken çıkışını önler ve normal PID tahsisine izin verir.
|
||||
- Sorun, `unshare` ile `-f` seçeneğinin kullanılmasıyla çözülebilir. Bu seçenek, `unshare`'in yeni PID ad alanını oluşturduktan sonra yeni bir süreç fork etmesini sağlar.
|
||||
- `%unshare -fp /bin/bash%` komutunu çalıştırmak, `unshare` komutunun kendisinin yeni ad alanında PID 1 olmasını garanti eder. `/bin/bash` ve onun çocuk süreçleri bu yeni ad alanında güvenli bir şekilde yer alır, PID 1'in erken çıkışını önler ve normal PID tahsisine izin verir.
|
||||
|
||||
`unshare`'in `-f` bayrağı ile çalıştırıldığından emin olarak, yeni PID ad alanı doğru bir şekilde korunur ve `/bin/bash` ile alt süreçlerinin bellek tahsis hatası ile karşılaşmadan çalışmasına olanak tanır.
|
||||
`unshare`'in `-f` bayrağı ile çalıştığından emin olarak, yeni PID ad alanı doğru bir şekilde korunur ve `/bin/bash` ile alt süreçlerinin bellek tahsis hatası ile karşılaşmadan çalışmasına olanak tanır.
|
||||
|
||||
</details>
|
||||
|
||||
@ -59,4 +59,83 @@ sudo find /proc -maxdepth 3 -type l -name time -exec ls -l {} \; 2>/dev/null |
|
||||
```bash
|
||||
nsenter -T TARGET_PID --pid /bin/bash
|
||||
```
|
||||
## Zaman Ofsetlerini Manipüle Etme
|
||||
|
||||
Linux 5.6 ile birlikte, her zaman ad alanı için iki saat sanallaştırılabilir:
|
||||
|
||||
* `CLOCK_MONOTONIC`
|
||||
* `CLOCK_BOOTTIME`
|
||||
|
||||
Her bir ad alanına ait farklar, `/proc/<PID>/timens_offsets` dosyası aracılığıyla açığa çıkar (ve değiştirilebilir):
|
||||
```
|
||||
$ sudo unshare -Tr --mount-proc bash # -T creates a new timens, -r drops capabilities
|
||||
$ cat /proc/$$/timens_offsets
|
||||
monotonic 0
|
||||
boottime 0
|
||||
```
|
||||
Dosya, her bir saat için birer satır içermekte ve **nanosecond** cinsinden ofseti göstermektedir. **CAP_SYS_TIME** _zaman ad alanında_ bulunan süreçler bu değeri değiştirebilir:
|
||||
```
|
||||
# advance CLOCK_MONOTONIC by two days (172 800 s)
|
||||
echo "monotonic 172800000000000" > /proc/$$/timens_offsets
|
||||
# verify
|
||||
$ cat /proc/$$/uptime # first column uses CLOCK_MONOTONIC
|
||||
172801.37 13.57
|
||||
```
|
||||
Eğer duvar saati (`CLOCK_REALTIME`) değişmesini istiyorsanız, yine klasik mekanizmalara (`date`, `hwclock`, `chronyd`, …) güvenmek zorundasınız; bu **ad alanı** değildir.
|
||||
|
||||
|
||||
### `unshare(1)` yardımcı bayrakları (util-linux ≥ 2.38)
|
||||
```
|
||||
sudo unshare -T \
|
||||
--monotonic="+24h" \
|
||||
--boottime="+7d" \
|
||||
--mount-proc \
|
||||
bash
|
||||
```
|
||||
Uzun seçenekler, seçilen delta'ları `timens_offsets`'a otomatik olarak yazar, bu da manuel bir `echo` gerektirmez.
|
||||
|
||||
---
|
||||
|
||||
## OCI & Runtime desteği
|
||||
|
||||
* **OCI Runtime Specification v1.1** (Kasım 2023), konteyner motorlarının taşınabilir bir şekilde zaman sanallaştırması talep edebilmesi için özel bir `time` namespace türü ve `linux.timeOffsets` alanını ekledi.
|
||||
* **runc >= 1.2.0**, spesifikasyonun bu kısmını uygular. Minimal bir `config.json` parçası şöyle görünür:
|
||||
```json
|
||||
{
|
||||
"linux": {
|
||||
"namespaces": [
|
||||
{"type": "time"}
|
||||
],
|
||||
"timeOffsets": {
|
||||
"monotonic": 86400,
|
||||
"boottime": 600
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Sonra konteyneri `runc run <id>` ile çalıştırın.
|
||||
|
||||
> NOT: runc **1.2.6** (Şubat 2025), bir "özel timens ile konteynere exec" hatasını düzeltti; bu hata bir takılmaya ve potansiyel DoS'a yol açabilirdi. Üretimde ≥ 1.2.6 sürümünde olduğunuzdan emin olun.
|
||||
|
||||
---
|
||||
|
||||
## Güvenlik hususları
|
||||
|
||||
1. **Gerekli yetki** – Bir işlemin, offset'leri değiştirmek için kullanıcı/zaman namespace'i içinde **CAP_SYS_TIME** yetkisine ihtiyacı vardır. Bu yetkinin konteynerde (Docker & Kubernetes'te varsayılan) düşürülmesi, müdahaleyi engeller.
|
||||
2. **Duvar saati değişiklikleri yok** – `CLOCK_REALTIME` ana makine ile paylaşıldığı için, saldırganlar yalnızca timens aracılığıyla sertifika ömürlerini, JWT süresini vb. taklit edemez.
|
||||
3. **Log / tespit kaçışı** – `CLOCK_MONOTONIC`'a (örneğin, çalışma süresine dayalı oran sınırlayıcılar) dayanan yazılımlar, namespace kullanıcısı offset'i ayarladığında karışıklık yaşayabilir. Güvenlik açısından önemli zaman damgaları için `CLOCK_REALTIME`'ı tercih edin.
|
||||
4. **Kernel saldırı yüzeyi** – `CAP_SYS_TIME` kaldırılmış olsa bile, kernel kodu erişilebilir kalır; ana makineyi güncel tutun. Linux 5.6 → 5.12, bir dizi timens hata düzeltmesi aldı (NULL-deref, işaretleme sorunları).
|
||||
|
||||
### Güçlendirme kontrol listesi
|
||||
|
||||
* Konteyner çalışma zamanı varsayılan profilinizde `CAP_SYS_TIME`'ı kaldırın.
|
||||
* Çalışma zamanlarını güncel tutun (runc ≥ 1.2.6, crun ≥ 1.12).
|
||||
* `--monotonic/--boottime` yardımcılarına güveniyorsanız util-linux ≥ 2.38 sürümüne sabitleyin.
|
||||
* Güvenlik kritik mantık için **uptime** veya **CLOCK_MONOTONIC** okuyan konteyner içi yazılımları denetleyin.
|
||||
|
||||
## Referanslar
|
||||
|
||||
* man7.org – Zaman namespace'leri kılavuz sayfası: <https://man7.org/linux/man-pages/man7/time_namespaces.7.html>
|
||||
* OCI blog – "OCI v1.1: yeni zaman ve RDT namespace'leri" (15 Kasım 2023): <https://opencontainers.org/blog/2023/11/15/oci-spec-v1.1>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user