tcpsnitch
adalah alat penelusuran yang dirancang untuk menyelidiki interaksi antara aplikasi dan tumpukan TCP/IP. tcpsnitch
menjalankan perintah yang ditentukan hingga keluar dan mencegat semua panggilan fungsi libc di soket internet.
Untuk memulai dengan lembut, seseorang dapat menjalankan perintah berikut untuk melacak program curl
:
$ tcpsnitch curl google.com
Untuk setiap soket internet yang dibuka, tcpsnitch
membuat daftar pemanggilan fungsi yang diurutkan (pemanggilan fungsi disebut peristiwa di sisa dokumen ini). Untuk setiap kejadian, tcpsnitch
mencatat argumen, nilai yang dikembalikan, dan berbagai informasi seperti stempel waktu saat ini atau id thread. Secara khusus, acara connect()
mungkin terlihat seperti ini di jejak soket:
{
"type" : " connect " ,
"timestamp_usec" : 1491043720731853 ,
"return_value" : 0 ,
"success" : true ,
"thread_id" : 17313 ,
"details" : {
"addr" : {
"sa_family" : " AF_INET " ,
"ip" : " 127.0.1.1 " ,
"port" : " 53 "
}
}
}
Pelacakan soket ditulis ke file teks yang setiap barisnya merupakan objek JSON yang mewakili satu peristiwa. Kepala jejak tersebut bisa seperti ini:
{ "type" : " socket " , "timestamp_usec" : 1491043720731840 , "return_value" : 6 , "success" : true , "thread_id" : 17313 , "details" : { "sock_info" : { "domain" : " AF_INET " , "type" : " SOCK_DGRAM " , "protocol" : 0 , "SOCK_CLOEXEC" : false , "SOCK_NONBLOCK" : true }}}
{ "type" : " ioctl " , "timestamp_usec" : 1491043720765019 , "return_value" : 0 , "success" : true , "thread_id" : 17313 , "details" : { "request" : " FIONREAD " }}
{ "type" : " recvfrom " , "timestamp_usec" : 1491043720765027 , "return_value" : 44 , "success" : true , "thread_id" : 17313 , "details" : { "bytes" : 2048 , "flags" : { "MSG_CMSG_CLOEXEC" : false , "MSG_DONTWAIT" : false , "MSG_ERRQUEUE" : false , "MSG_OOB" : false , "MSG_PEEK" : false , "MSG_TRUNC" : false , "MSG_WAITALL" : false }, "addr" : { "sa_family" : " AF_INET " , "ip" : " 127.0.1.1 " , "port" : " 53 " }}}
{ "type" : " ioctl " , "timestamp_usec" : 1491043720770075 , "return_value" : 0 , "success" : true , "thread_id" : 17313 , "details" : { "request" : " FIONREAD " }}
{ "type" : " recvfrom " , "timestamp_usec" : 1491043720770094 , "return_value" : 56 , "success" : true , "thread_id" : 17313 , "details" : { "bytes" : 65536 , "flags" : { "MSG_CMSG_CLOEXEC" : false , "MSG_DONTWAIT" : false , "MSG_ERRQUEUE" : false , "MSG_OOB" : false , "MSG_PEEK" : false , "MSG_TRUNC" : false , "MSG_WAITALL" : false }, "addr" : { "sa_family" : " AF_INET " , "ip" : " 127.0.1.1 " , "port" : " 53 " }}}
Karena satu perintah dapat melakukan fork pada banyak proses (dan tcpsnitch
mengikuti fork), semua jejak soket milik proses tertentu disatukan dalam sebuah direktori, yang diberi nama sesuai dengan proses yang dilacak. Di dalam direktori tersebut, jejak soket diberi nama berdasarkan urutan pembukaannya oleh proses.
Secara default, jejak disimpan dalam direktori acak di bawah /tmp
dan secara otomatis diunggah ke www.tcpsnitch.org, sebuah platform yang dirancang untuk memusatkan, memvisualisasikan, dan menganalisis jejak. Perhatikan bahwa semua jejak yang diunggah bersifat publik dan tersedia bagi siapa saja untuk berkonsultasi dan mengunduh.
Seperti yang terlihat pada cuplikan kode berikutnya, tcpsnitch
memberi Anda URL tempat pelacakan Anda tersedia.
$ tcpsnitch curl google.com
Trace saved in /tmp/tmp.4ERKizKyU3.
Uploading trace....
Trace successfully uploaded at https://tcpsnitch.org/app_traces/20.
Trace archive will be imported shortly. Refresh this page in a few minutes...
Perhatikan bahwa diperlukan beberapa menit untuk mengimpor jejak (yaitu mengekstrak arsip jejak dan memasukkan semua kejadian ke dalam database). Setelah diimpor, mungkin diperlukan beberapa menit lagi untuk menghitung analisis kuantitatif penelusuran.
Terakhir, tcpsnitch
juga memungkinkan untuk mengekstrak opsi soket TCP_INFO
pada interval yang ditentukan pengguna dan mencatat jejak .pcap
untuk setiap soket individual. Lihat bagian penggunaan untuk informasi lebih lanjut.
tcpsnitch
memungkinkan pelacakan aplikasi di:
Karena tcpsnitch
bekerja dengan mencegat panggilan ke fungsi libc menggunakan variabel lingkungan LD_PRELOAD
, penelusuran tidak dapat dilakukan untuk aplikasi yang terhubung secara statis dengan libc.
Catatan: Di Linux, Chrome (dan aplikasi berbasis Chromium apa pun seperti Electron, Opera, dll...) diketahui TIDAK kompatibel.
Bagi pengguna yang ingin melacak aplikasi Android, gulir ke bawah ke bagian "Kompilasi untuk Android".
Diuji pada Ubuntu 16 & 14, Debian 8, Elementary 0.4, Mint 18
sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt-get install make gcc gcc-multilib libc6-dev libc6-dev:i386 libjansson-dev libjansson-dev:i386 libpcap0.8 libpcap0.8:i386 libpcap0.8-dev
Diuji pada Fedora 25 & CentOS 7
sudo yum install make gcc glibc-devel glibc-devel.i686 libgcc libgcc.i686 libpcap-devel.x86_64 libpcap-devel.i686 jansson jansson.i686 && curl -O http://www.digip.org/jansson/releases/jansson-2.10.tar.bz2 && bunzip2 -c jansson-2.10.tar.bz2 | tar xf - && rm -f jansson-2.10.tar.bz2 && cd jansson-2.10 && ./configure && make && sudo make install && cd .. && rm -rf jansson-2.10
Bangun & pasang:
./configure
make
sudo make install
Penggunaan: tcpsnitch [<options>] <cmd> [<cmd_args>]
di mana:
<options>
adalah opsi tcpsnitch
<cmd>
adalah perintah untuk menelusuri (wajib)<cmd_args>
adalah argumen dari <cmd>
. Berikut adalah contoh sederhana dengan curl
dan semua opsi default:
tcpsnitch curl google.com
Seseorang mungkin mengeluarkan tcpsnitch -h
untuk mendapatkan informasi lebih lanjut tentang opsi yang didukung. Yang paling penting adalah sebagai berikut:
-b
dan -u
digunakan untuk mengekstraksi TCP_INFO
pada interval yang ditentukan pengguna. Lihat bagian "Mengekstrak TCP_INFO
" untuk info lebih lanjut.-c
digunakan untuk menangkap jejak pcap
dari soket. Lihat bagian "Pengambilan paket" untuk info lebih lanjut.-a
dan -k
digunakan untuk menelusuri aplikasi Android. Lihat bagian "Penggunaan Android" untuk info lebih lanjut.-n
nonaktifkan pengunggahan jejak otomatis.-d
menyetel direktori tempat jejak akan ditulis (bukan direktori acak di /tmp
).-f
mengatur tingkat verbositas log yang disimpan ke file. Secara default, hanya pesan WARN dan ERROR yang ditulis ke log. Ini terutama berguna untuk melaporkan bug dan debugging.-l
mirip dengan -f
tetapi menyetel verbositas log pada STDOUT, yang secara default hanya menampilkan pesan ERROR. Ini digunakan untuk tujuan debugging.-t
mengontrol frekuensi di mana peristiwa dibuang ke file. Secara default, peristiwa ditulis ke file setiap 1000 milidetik.-v
sangat tidak berguna saat ini, tetapi seharusnya menempatkan tcpsnitch
dalam mode verbose dengan gaya strace
. Masih harus diimplementasikan (saat ini hanya menampilkan nama event).TCP_INFO
-b <bytes>
dan -u <usec>
memungkinkan untuk mengekstrak nilai opsi soket TCP_INFO
untuk setiap soket pada interval yang ditentukan pengguna. Perhatikan bahwa nilai TCP_INFO
muncul seperti peristiwa lainnya di jejak JSON dari socekt.
-b <bytes>
, TCP_INFO
dicatat setiap <bytes>
yang dikirim+diterima pada soket.-u <usec>
, TCP_INFO
dicatat setiap <usec>
mikro-detik.TCP_INFO
dicatat ketika salah satu dari dua kondisi cocok. Secara default opsi ini dinonaktifkan. Perhatikan juga bahwa tcpsnitch
hanya memeriksa kondisi ini ketika fungsi yang diganti dipanggil.
Opsi -c
mengaktifkan penangkapan jejak .pcap
untuk setiap soket. Perhatikan bahwa Anda harus memiliki izin yang sesuai untuk dapat menangkap lalu lintas pada antarmuka (lihat man pcap
untuk informasi lebih lanjut tentang izin tersebut).
Fitur ini tidak tersedia untuk Android saat ini.
Penggunaan di Android merupakan proses dua langkah, sangat mirip dengan penggunaan di Linux. Pertama, atur tcpsnitch
dan luncurkan aplikasi yang akan dilacak dengan opsi yang sesuai, kemudian jejak tersebut ditarik dari perangkat dan disalin ke mesin host.
Semua opsi didukung di Android, kecuali opsi -c
untuk menangkap jejak .pcap
.
Beberapa langkah penyiapan awal harus dilakukan sekali di perangkat:
adb devices
dan pastikan ponsel Anda terlihat (Anda akan melihat device
di kolom kedua). Ketika perangkat dapat diakses melalui adb
, penggunaannya hampir sama seperti di Linux:
tcpsnitch
biasa dengan opsi -a
untuk menunjukkan bahwa Anda ingin melacak aplikasi pada perangkat Android yang terhubung. Perhatikan bahwa argumen <cmd>
harus cocok dengan nama paket yang diinstal pada perangkat melalui grep
sederhana. Misalnya, untuk melacak aplikasi Firefox yang nama paketnya adalah org.firefox.com
, seseorang dapat mengeluarkan tcpsnitch -a firefox
. tcpsnitch
akan memberi tahu Anda tentang paket cocok yang ditemukan dan segera memulai aplikasi.tcpsnitch -k <package>
untuk mematikan aplikasi dan menghentikan proses penelusuran. Jejaknya akan diambil dari perangkat dan disimpan di disk Anda di /tmp
sebelum diunggah ke www.tcpsnitch.org. Penting: Anda harus me-restart perangkat Android Anda untuk menonaktifkan pelacakan sepenuhnya. Karena tcpsnitch
menggunakan properti Android untuk menyiapkan pustaka LD_PRELOAD
, dan properti ini tidak dapat disetel, reboot perangkat harus dilakukan untuk menghapus properti tersebut (mungkin ada yang tahu solusi yang lebih baik?).
Berikut ini contoh lengkap untuk menelusuri Firefox:
$ tcpsnitch -a firefox
Found Android package: ' org.mozilla.firefox ' .
Uploading tcpsnitch library to /data/libtcpsnitch.so.0.1-arm.
Start package ' org.mozilla.firefox ' .
Execute ' ./tcpsnitch -k firefox ' to terminate the capture.
# INTERACTING WITH APPLICATION
$ tcpsnitch -k firefox
Found Android package: ' org.mozilla.firefox ' .
Pulling trace from Android device....
Trace saved in /tmp/tmp.MidCH9rm3x.
Uploading trace....
Trace successfully uploaded at https://tcpsnitch.org/app_traces/21.
Trace archive will be imported shortly. Refresh this page in a few minutes...
Perhatikan bahwa jika ada beberapa kecocokan untuk suatu paket, paket pertama yang cocok akan digunakan. Oleh karena itu, Anda mungkin perlu lebih spesifik untuk menghindari konflik. Anda dapat menjalankan adb shell pm list packages
untuk mendapatkan nama semua paket yang diinstal pada perangkat Anda.
Perhatikan juga bahwa satu perangkat harus terlihat oleh adb
.
Untuk melacak aplikasi Android, tcpsnitch
harus dikompilasi dengan Android Native Development Kit (NDK). Kompilasinya lebih rumit dan penyiapannya memerlukan perangkat Android yang telah di-root.
Pada dasarnya, ini melibatkan langkah-langkah berikut:
libjansson
dan libpcap
dengan NDK, dan jadikan perpustakaan terkompilasi dan file header tersedia untuk toolchain mandiri.tcpsnitch
dengan toolchain mandiri dan siapkan perangkat Android.Bagian berikut memberikan contoh kompleks yang memandu Anda melalui semua langkah.
Beberapa asumsi:
<NDK_PATH>
.<TCPSNITCH_PATH>
.Pertama, mari kita definisikan beberapa variabel:
export TCPSNITCH=<TCPSNITCH_PATH>
export NDK=<NDK_PATH>
# Where the standalone toolchain WILL be created
export TOOLCHAIN=<TOOLCHAIN_PATH>
Sekarang, mari kita mulai dengan membuat toolchain mandiri untuk perangkat ARM yang menjalankan Android API 23 (versi 6.0, Marshmallow). Pemetaan antara versi Android dan API level ada di halaman berikut.
$NDK/build/tools/make_standalone_toolchain.py --arch arm --api 23 --install-dir $TOOLCHAIN
Kita sekarang harus mengkompilasi libjansson
dan libpcap
dengan NDK. Ketika ini selesai, kita harus menginstal file header dan perpustakaan yang dikompilasi di "sysroot" di toolchain mandiri kita.
Mari kita mulai dengan libjansson
:
git clone https://github.com/akheron/jansson && cd jansson
# Configuration file which we don't use, we may leave it empty
touch src/jansson_private_config.h
sed -i 's/BUILD_SHARED_LIBRARY/BUILD_STATIC_LIBRARY/g' Android.mk
$NDK/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
cp obj/local/armeabi/libjansson.a $TOOLCHAIN/sysroot/usr/lib/
cp src/jansson.h android/jansson_config.h $TOOLCHAIN/sysroot/usr/include/
cd .. && rm -rf jansson
Sekarang, mari kita atasi libpcap
:
git clone https://github.com/the-tcpdump-group/libpcap && cd libpcap
export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
./configure --host=arm-linux --with-pcap=linux --prefix=/usr
# You will need to install some missing dependencies (e.g. `flex` & `bison`)
sudo apt-get install flex bison
# Reissue ./configure untill all dependencies are met
./configure --host=arm-linux --with-pcap=linux --prefix=/usr
# Compile && install in toolchain
make && sudo make install DESTDIR=$TOOLCHAIN/sysroot
cd .. && rm -rf libpcap
Kami sekarang siap untuk mengkompilasi tcpsnitch
:
# First, let's fix the buggy `tcp.h` header from the NDK
sed -i 's/include <linux/tcp.h>/include <sys/cdefs.h>n#include <linux/tcp.h>/g' $TOOLCHAIN/sysroot/usr/include/netinet/tcp.h
# Configure the compiler
export CC_ANDROID=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
# Build & install tcpsnitch
make android && sudo make install
Anda siap berangkat! Lihat bagian penggunaan Android untuk cara mulai melacak aplikasi.
Fitur menarik dari linker dinamis Linux ( ld.so
) adalah kemampuan untuk menghubungkan perpustakaan bersama yang ditentukan pengguna sebelum perpustakaan yang ditentukan dalam daftar dependensi suatu program. Fitur ini dapat dikontrol dengan variabel lingkungan LD_PRELOAD
yang berisi daftar perpustakaan tambahan (mungkin kosong) yang ditentukan pengguna. Secara khusus, variabel LD_PRELOAD
ini mungkin memaksa penghubung dinamis untuk menghubungkan perpustakaan bersama yang ditentukan pengguna sebelum perpustakaan libc
. Akibatnya, fungsi apa pun yang ditentukan dalam pustaka yang ditentukan pengguna ini akan diutamakan daripada fungsi dengan tanda tangan yang sama yang ditentukan dalam libc
.
Implikasinya di sini adalah memungkinkan untuk mencegat panggilan ke fungsi pembungkus panggilan sistem. Kita hanya perlu menambahkan pustaka bersama khusus yang mendefinisikan ulang fungsi pembungkus panggilan sistem ini menjadi LD_PRELOAD
. Pustaka shim seperti itu kemudian secara transparan mencegat pemanggilan fungsi libc
dan melakukan beberapa pemrosesan sebelum memanggil fungsi pembungkus libc
asli.
wrong ELF class
ini? Tidak ada hal buruk, ini bisa diabaikan. Pustaka bersama tcpsnitch
dikompilasi untuk arsitektur 32-bit dan 64-bit. Saat menelusuri suatu perintah, kedua perpustakaan dimuat dalam variabel lingkungan LD_PRELOAD
karena tidak ada cara mudah untuk mengetahui arsitektur biner perintah (seringkali berupa skrip shell yang mengeksekusi biner lain). Tautan dinamis kemudian menangani pemuatan perpustakaan yang kompatibel dan mengabaikan yang kedua (tetapi masih menimbulkan kesalahan).
Ayo berdiskusi tentang tcpsnitch
di https://gitter.im/Tcpsnitch.
Email penulis adalah gregory.vanderschueren[at]gmail.com