AppArmor
Tip
AWS ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:HackTricks Training GCP Red Team Expert (GRTE)
Azure ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks μ§μνκΈ°
- ꡬλ κ³ν νμΈνκΈ°!
- **π¬ λμ€μ½λ κ·Έλ£Ή λλ ν λ κ·Έλ¨ κ·Έλ£Ήμ μ°Έμ¬νκ±°λ νΈμν° π¦ @hacktricks_liveλ₯Ό νλ‘μ°νμΈμ.
- HackTricks λ° HackTricks Cloud κΉνλΈ λ¦¬ν¬μ§ν 리μ PRμ μ μΆνμ¬ ν΄νΉ νΈλ¦μ 곡μ νμΈμ.
κΈ°λ³Έ μ 보
AppArmorλ νλ‘κ·Έλ¨λ³ νλ‘νμ ν΅ν΄ νλ‘κ·Έλ¨μ μ¬μ©ν μ μλ 리μμ€λ₯Ό μ ννλλ‘ μ€κ³λ 컀λ ν₯μ κΈ°λ₯μΌλ‘, μ κ·Ό μ μ΄ μμ±μ μ¬μ©μ λμ νλ‘κ·Έλ¨μ μ§μ μ°κ²°νμ¬ κ°μ μ κ·Ό μ μ΄(MAC)λ₯Ό ν¨κ³Όμ μΌλ‘ ꡬνν©λλ€. μ΄ μμ€ν μ λΆν μ€μ νλ‘νμ 컀λμ λ‘λνμ¬ μλνλ©°, μ΄λ¬ν νλ‘νμ νλ‘κ·Έλ¨μ΄ μ κ·Όν μ μλ 리μμ€(μ: λ€νΈμν¬ μ°κ²°, μμ μμΌ μ κ·Ό λ° νμΌ κΆν)λ₯Ό κ·μ ν©λλ€.
AppArmor νλ‘νμλ λ κ°μ§ μ΄μ λͺ¨λκ° μμ΅λλ€:
- κ°μ λͺ¨λ: μ΄ λͺ¨λλ νλ‘ν λ΄μμ μ μλ μ μ± μ μ κ·Ήμ μΌλ‘ μννλ©°, μ΄λ¬ν μ μ± μ μλ°νλ νλμ μ°¨λ¨νκ³ syslog λλ auditdμ κ°μ μμ€ν μ ν΅ν΄ μλ° μλλ₯Ό κΈ°λ‘ν©λλ€.
- λΆλ§ λͺ¨λ: κ°μ λͺ¨λμ λ¬λ¦¬ λΆλ§ λͺ¨λλ νλ‘νμ μ μ± μ λ°νλ νλμ μ°¨λ¨νμ§ μμ΅λλ€. λμ , μ΄λ¬ν μλλ₯Ό μ μ± μλ°μΌλ‘ κΈ°λ‘νλ μ νμ μννμ§ μμ΅λλ€.
AppArmorμ κ΅¬μ± μμ
- 컀λ λͺ¨λ: μ μ± μνμ λ΄λΉν©λλ€.
- μ μ± : νλ‘κ·Έλ¨ λμ λ° λ¦¬μμ€ μ κ·Όμ λν κ·μΉκ³Ό μ νμ μ§μ ν©λλ€.
- νμ: μ μ± μ 컀λμ λ‘λνμ¬ μν λλ λ³΄κ³ ν©λλ€.
- μ νΈλ¦¬ν°: AppArmorμ μνΈμμ©νκ³ κ΄λ¦¬νκΈ° μν μΈν°νμ΄μ€λ₯Ό μ 곡νλ μ¬μ©μ λͺ¨λ νλ‘κ·Έλ¨μ λλ€.
νλ‘ν κ²½λ‘
AppArmor νλ‘νμ μΌλ°μ μΌλ‘ _/etc/apparmor.d/_μ μ μ₯λ©λλ€.sudo aa-statusλ₯Ό μ¬μ©νλ©΄ μΌλΆ νλ‘νμ μν΄ μ νλ λ°μ΄λ리λ₯Ό λμ΄ν μ μμ΅λλ€. λμ΄λ κ° λ°μ΄λ리μ κ²½λ‘μμ λ¬Έμ β/βλ₯Ό μ μΌλ‘ λ³κ²½νλ©΄ μΈκΈλ ν΄λ λ΄μ AppArmor νλ‘ν μ΄λ¦μ μ»μ μ μμ΅λλ€.
μλ₯Ό λ€μ΄, _/usr/bin/man_μ λν AppArmor νλ‘νμ _/etc/apparmor.d/usr.bin.man_μ μμΉν©λλ€.
λͺ λ Ήμ΄
aa-status #check the current status
aa-enforce #set profile to enforce mode (from disable or complain)
aa-complain #set profile to complain mode (from diable or enforcement)
apparmor_parser #to load/reload an altered policy
aa-genprof #generate a new profile
aa-logprof #used to change the policy when the binary/program is changed
aa-mergeprof #used to merge the policies
νλ‘ν μμ±
- μν₯μ λ°λ μ€ν νμΌμ λνλ΄κΈ° μν΄ μ λ κ²½λ‘μ μμΌλμΉ΄λκ° νμΌμ μ§μ νλ λ° νμ©λ©λλ€.
- λ°μ΄λλ¦¬κ° νμΌμ λν΄ κ°μ§ μ κ·Όμ λνλ΄κΈ° μν΄ λ€μ μ κ·Ό μ μ΄λ₯Ό μ¬μ©ν μ μμ΅λλ€:
- r (μ½κΈ°)
- w (μ°κΈ°)
- m (μ€ν κ°λ₯ν λ©λͺ¨λ¦¬ λ§΅)
- k (νμΌ μ κΈ)
- l (νλ λ§ν¬ μμ±)
- ix (μ νλ‘κ·Έλ¨μ΄ μ μ± μ μμλ°μ λ€λ₯Έ νλ‘κ·Έλ¨μ μ€ν)
- Px (νκ²½μ μ 리ν ν λ€λ₯Έ νλ‘νμμ μ€ν)
- Cx (νκ²½μ μ 리ν ν μμ νλ‘νμμ μ€ν)
- Ux (νκ²½μ μ 리ν ν μ ν μμ΄ μ€ν)
- λ³μλ νλ‘νμμ μ μν μ μμΌλ©° νλ‘ν μΈλΆμμ μ‘°μν μ μμ΅λλ€. μ: @{PROC} λ° @{HOME} (νλ‘ν νμΌμ #include <tunables/global> μΆκ°)
- νμ© κ·μΉμ 무μνκΈ° μν΄ κ±°λΆ κ·μΉμ΄ μ§μλ©λλ€.
aa-genprof
νλ‘ν μμ±μ μ½κ² μμνκΈ° μν΄ apparmorκ° λμμ μ€ μ μμ΅λλ€. apparmorκ° λ°μ΄λ리μ μν΄ μνλ μμ
μ κ²μ¬νκ³ μ΄λ€ μμ
μ νμ©νκ±°λ κ±°λΆν μ§ κ²°μ ν μ μκ² ν΄μ€λλ€.
λ¨μ§ λ€μμ μ€ννλ©΄ λ©λλ€:
sudo aa-genprof /path/to/binary
κ·Έλ° λ€μ, λ€λ₯Έ μ½μμμ λ°μ΄λλ¦¬κ° μΌλ°μ μΌλ‘ μνν λͺ¨λ μμ μ μνν©λλ€:
/path/to/binary -a dosomething
κ·Έλ° λ€μ 첫 λ²μ§Έ μ½μμμ βsβλ₯Ό λλ₯΄κ³ κΈ°λ‘λ μμ μμ 무μ, νμ© λλ κΈ°νλ₯Ό μ νν©λλ€. μλ£λλ©΄ βfβλ₯Ό λλ¬ μ νλ‘νμ΄ _/etc/apparmor.d/path.to.binary_μ μμ±λ©λλ€.
Note
νμ΄ν ν€λ₯Ό μ¬μ©νμ¬ νμ©/κ±°λΆ/κΈ°νλ₯Ό μ νν μ μμ΅λλ€.
aa-easyprof
μ΄μ§ νμΌμ apparmor νλ‘ν ν νλ¦Ώμ λ€μκ³Ό κ°μ΄ μμ±ν μ μμ΅λλ€:
sudo aa-easyprof /path/to/binary
# vim:syntax=apparmor
# AppArmor policy for binary
# ###AUTHOR###
# ###COPYRIGHT###
# ###COMMENT###
#include <tunables/global>
# No template variables specified
"/path/to/binary" {
#include <abstractions/base>
# No abstractions specified
# No policy groups specified
# No read paths specified
# No write paths specified
}
Note
κΈ°λ³Έμ μΌλ‘ μμ±λ νλ‘νμμλ μ무κ²λ νμ©λμ§ μμΌλ―λ‘ λͺ¨λ κ²μ΄ κ±°λΆλ©λλ€. μλ₯Ό λ€μ΄, μ΄μ§ νμΌμ΄
/etc/passwdλ₯Ό μ½μ μ μλλ‘/etc/passwd r,μ κ°μ μ€μ μΆκ°ν΄μΌ ν©λλ€.
κ·Έλ° λ€μ enforce μ νλ‘νμ μ¬μ©ν μ μμ΅λλ€.
sudo apparmor_parser -a /etc/apparmor.d/path.to.binary
λ‘κ·Έμμ νλ‘ν μμ
λ€μ λꡬλ λ‘κ·Έλ₯Ό μ½κ³ μ¬μ©μκ° κ°μ§λ κΈμ§λ νλ μ€ μΌλΆλ₯Ό νμ©ν κ²μΈμ§ λ¬Όμ΄λ΄ λλ€:
sudo aa-logprof
Note
νμ΄ν ν€λ₯Ό μ¬μ©νμ¬ νμ©/κ±°λΆ/κΈ°ν μνλ νλͺ©μ μ νν μ μμ΅λλ€.
νλ‘ν κ΄λ¦¬
#Main profile management commands
apparmor_parser -a /etc/apparmor.d/profile.name #Load a new profile in enforce mode
apparmor_parser -C /etc/apparmor.d/profile.name #Load a new profile in complain mode
apparmor_parser -r /etc/apparmor.d/profile.name #Replace existing profile
apparmor_parser -R /etc/apparmor.d/profile.name #Remove profile
Logs
Example of AUDIT and DENIED logs from /var/log/audit/audit.log of the executable service_bin:
type=AVC msg=audit(1610061880.392:286): apparmor="AUDIT" operation="getattr" profile="/bin/rcat" name="/dev/pts/1" pid=954 comm="service_bin" requested_mask="r" fsuid=1000 ouid=1000
type=AVC msg=audit(1610061880.392:287): apparmor="DENIED" operation="open" profile="/bin/rcat" name="/etc/hosts" pid=954 comm="service_bin" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
μ΄ μ 보λ₯Ό λ€μμ μ¬μ©νμ¬ μ»μ μλ μμ΅λλ€:
sudo aa-notify -s 1 -v
Profile: /bin/service_bin
Operation: open
Name: /etc/passwd
Denied: r
Logfile: /var/log/audit/audit.log
Profile: /bin/service_bin
Operation: open
Name: /etc/hosts
Denied: r
Logfile: /var/log/audit/audit.log
AppArmor denials: 2 (since Wed Jan 6 23:51:08 2021)
For more information, please see: https://wiki.ubuntu.com/DebuggingApparmor
Dockerμ Apparmor
dockerμ νλ‘νμΌ docker-profileμ΄ κΈ°λ³Έμ μΌλ‘ λ‘λλλ λ°©μμ μ£Όλͺ©νμΈμ:
sudo aa-status
apparmor module is loaded.
50 profiles are loaded.
13 profiles are in enforce mode.
/sbin/dhclient
/usr/bin/lxc-start
/usr/lib/NetworkManager/nm-dhcp-client.action
/usr/lib/NetworkManager/nm-dhcp-helper
/usr/lib/chromium-browser/chromium-browser//browser_java
/usr/lib/chromium-browser/chromium-browser//browser_openjdk
/usr/lib/chromium-browser/chromium-browser//sanitized_helper
/usr/lib/connman/scripts/dhclient-script
docker-default
κΈ°λ³Έμ μΌλ‘ Apparmor docker-default νλ‘νμ https://github.com/moby/moby/tree/master/profiles/apparmorμμ μμ±λ©λλ€.
docker-default νλ‘ν μμ½:
- λͺ¨λ λ€νΈμνΉμ λν μ κ·Ό
- λ₯λ ₯μ΄ μ μλμ΄ μμ§ μμ (κ·Έλ¬λ μΌλΆ λ₯λ ₯μ κΈ°λ³Έ κΈ°λ³Έ κ·μΉμ ν¬ν¨νμ¬ μ¬ μ μμ, μ¦ #include <abstractions/base>)
- /proc νμΌμ λν μ°κΈ°λ νμ©λμ§ μμ
- /proc λ° /sysμ λ€λ₯Έ νμ λλ ν 리/νμΌμ λν μ½κΈ°/μ°κΈ°/μ κΈ/λ§ν¬/μ€ν μ κ·Όμ΄ κ±°λΆλ¨
- λ§μ΄νΈλ νμ©λμ§ μμ
- Ptraceλ κ°μ apparmor νλ‘νμ μν΄ μ νλ νλ‘μΈμ€μμλ§ μ€νν μ μμ
docker 컨ν μ΄λλ₯Ό μ€ννλ©΄ λ€μ μΆλ ₯μ λ³Ό μ μμ΄μΌ ν©λλ€:
1 processes are in enforce mode.
docker-default (825)
apparmorλ κΈ°λ³Έμ μΌλ‘ 컨ν μ΄λμ λΆμ¬λ κΆνμ μ°¨λ¨ν©λλ€. μλ₯Ό λ€μ΄, κΈ°λ³Έμ μΌλ‘ docker apparmor νλ‘νμ΄ μ΄ μ κ·Όμ κ±°λΆνκΈ° λλ¬Έμ SYS_ADMIN κΆνμ΄ λΆμ¬λλλΌλ /proc λ΄λΆμ μ°κΈ° κΆνμ μ°¨λ¨ν μ μμ΅λλ€:
docker run -it --cap-add SYS_ADMIN --security-opt seccomp=unconfined ubuntu /bin/bash
echo "" > /proc/stat
sh: 1: cannot create /proc/stat: Permission denied
You need to disable apparmor to bypass its restrictions:
apparmorμ μ νμ μ°ννλ €λ©΄ λΉνμ±νν΄μΌ ν©λλ€:
docker run -it --cap-add SYS_ADMIN --security-opt seccomp=unconfined --security-opt apparmor=unconfined ubuntu /bin/bash
κΈ°λ³Έμ μΌλ‘ AppArmorλ 컨ν μ΄λκ° λ΄λΆμμ ν΄λλ₯Ό λ§μ΄νΈνλ κ²μ κΈμ§ν©λλ€, μ¬μ§μ΄ SYS_ADMIN κΆνμ΄ μμ΄λ κ·Έλ μ΅λλ€.
컨ν μ΄λμ κΆνμ μΆκ°/μ κ±°ν μ μμ§λ§ (μ¬μ ν AppArmor λ° Seccompμ κ°μ λ³΄νΈ λ°©λ²μ μν΄ μ νλ©λλ€):
--cap-add=SYS_ADMINSYS_ADMINκΆν λΆμ¬--cap-add=ALLλͺ¨λ κΆν λΆμ¬--cap-drop=ALL --cap-add=SYS_PTRACEλͺ¨λ κΆν μ κ±°νκ³SYS_PTRACEλ§ λΆμ¬
Note
μΌλ°μ μΌλ‘ docker 컨ν μ΄λ λ΄λΆμμ νΉκΆ κΆνμ΄ μμ§λ§ μ΅μ€νλ‘μμ μΌλΆκ° μλνμ§ μλ κ²½μ°, μ΄λ docker apparmorκ° μ΄λ₯Ό λ°©μ§νκ³ μκΈ° λλ¬Έμ λλ€.
μμ
(μμλ μ¬κΈ°μμ κ°μ Έμ΄)
AppArmor κΈ°λ₯μ μ€λͺ νκΈ° μν΄, λ€μκ³Ό κ°μ μ€μ μΆκ°νμ¬ μλ‘μ΄ Docker νλ‘ν βmydockerβλ₯Ό μμ±νμ΅λλ€:
deny /etc/* w, # deny write for all files directly in /etc (not in a subdir)
νλ‘νμ νμ±ννλ €λ©΄ λ€μμ μνν΄μΌ ν©λλ€:
sudo apparmor_parser -r -W mydocker
νλ‘νμ λμ΄νλ €λ©΄ λ€μ λͺ λ Ήμ μ€νν μ μμ΅λλ€. μλ λͺ λ Ήμ λ΄ μλ‘μ΄ AppArmor νλ‘νμ λμ΄νκ³ μμ΅λλ€.
$ sudo apparmor_status | grep mydocker
mydocker
μλμ κ°μ΄, AppArmor νλ‘νμΌμ΄ β/etcβμ λν μ°κΈ° μ κ·Όμ λ°©μ§νκ³ μκΈ° λλ¬Έμ β/etc/βλ₯Ό λ³κ²½νλ €κ³ ν λ μ€λ₯κ° λ°μν©λλ€.
$ docker run --rm -it --security-opt apparmor:mydocker -v ~/haproxy:/localhost busybox chmod 400 /etc/hostname
chmod: /etc/hostname: Permission denied
AppArmor Docker Bypass1
μ΄λ€ apparmor νλ‘νμΌμ΄ 컨ν μ΄λλ₯Ό μ€ννκ³ μλμ§ νμΈνλ €λ©΄ λ€μμ μ¬μ©νμΈμ:
docker inspect 9d622d73a614 | grep lowpriv
"AppArmorProfile": "lowpriv",
"apparmor=lowpriv"
κ·Έλ° λ€μ, λ€μ λͺ λ Ήμ΄λ₯Ό μ€ννμ¬ μ¬μ© μ€μΈ μ νν νλ‘νμ μ°Ύμ μ μμ΅λλ€:
find /etc/apparmor.d/ -name "*lowpriv*" -maxdepth 1 2>/dev/null
μ΄μν κ²½μ°μ apparmor λ컀 νλ‘νμ μμ νκ³ λ€μ λ‘λν μ μμ΅λλ€. μ νμ μ κ±°νκ³ βμ°νβν μ μμ΅λλ€.
AppArmor Docker Bypass2
AppArmorλ κ²½λ‘ κΈ°λ°μ
λλ€. μ΄λ **/proc**μ κ°μ λλ ν 리 λ΄μ νμΌμ 보νΈνκ³ μμμ§λΌλ, 컨ν
μ΄λκ° μ΄λ»κ² μ€νλ μ§λ₯Ό ꡬμ±ν μ μλ€λ©΄, νΈμ€νΈμ proc λλ ν 리λ₯Ό **/host/proc**μ λ§μ΄νΈν μ μμΌλ©°, κ·Έλ¬λ©΄ λ μ΄μ AppArmorμ μν΄ λ³΄νΈλμ§ μμ΅λλ€.
AppArmor Shebang Bypass
μ΄ λ²κ·Έμμ νΉμ 리μμ€μ ν¨κ» perl μ€νμ λ°©μ§νκ³ μλλΌλ, 첫 λ²μ§Έ μ€μ **#!/usr/bin/perl**μ μ§μ ν μ
Έ μ€ν¬λ¦½νΈλ₯Ό μμ±νκ³ νμΌμ μ§μ μ€ννλ©΄, μνλ κ²μ μ€νν μ μλ μλ₯Ό λ³Ό μ μμ΅λλ€. μ:
echo '#!/usr/bin/perl
use POSIX qw(strftime);
use POSIX qw(setuid);
POSIX::setuid(0);
exec "/bin/sh"' > /tmp/test.pl
chmod +x /tmp/test.pl
/tmp/test.pl
Tip
AWS ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:HackTricks Training GCP Red Team Expert (GRTE)
Azure ν΄νΉ λ°°μ°κΈ° λ° μ°μ΅νκΈ°:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks μ§μνκΈ°
- ꡬλ κ³ν νμΈνκΈ°!
- **π¬ λμ€μ½λ κ·Έλ£Ή λλ ν λ κ·Έλ¨ κ·Έλ£Ήμ μ°Έμ¬νκ±°λ νΈμν° π¦ @hacktricks_liveλ₯Ό νλ‘μ°νμΈμ.
- HackTricks λ° HackTricks Cloud κΉνλΈ λ¦¬ν¬μ§ν 리μ PRμ μ μΆνμ¬ ν΄νΉ νΈλ¦μ 곡μ νμΈμ.


