
Crittografia end-to-end per sessioni tty multi-hop o portshell + forwarding di porte TCP/UDP
Questo progetto - così come il suo progetto gemello crash - fa parte della mia suite di strumenti anti-censura che permette di configurare shell crittografate funzionanti e inoltri TCP/UDP in ambienti ostili alla censura. È utile anche per la computer forensics per estrarre dati da dispositivi tramite UART o adb quando non sono disponibili altri mezzi.
Ricerca DNS e sessione SSH inoltrate attraverso una connessione UART verso un Pi
PSC permette di crittografare end-to-end sessioni di shell, con singolo o multipli salti, essendo
indipendente dal trasporto sottostante, purché sia affidabile e possa inviare/ricevere
dati codificati in Base64 senza modificarli/filtrarli. Oltre alla pty e2e che
ricevi (ad esempio all'interno di una port-shell), puoi inoltrare connessioni TCP e UDP,
similmente al parametro -L di OpenSSH. Questo funziona in modo trasparente
e senza la necessità di un indirizzo IP assegnato localmente al punto di partenza.
Ciò consente a forenser e pen-tester di creare connessioni di rete, ad esempio tramite:
adb shell, se l'adbd OEM non supporta l'inoltro TCPImmagina di avere una sessione ppp invisibile all'interno della tua sessione shell, senza che il peer remoto supporti effettivamente ppp.
Funziona su Linux, Android, OSX, Windows, FreeBSD, NetBSD e (possibilmente) OpenBSD.
PSC include anche il supporto proxy SOCKS4 e SOCKS5 per avere sessioni di navigazione web reali tramite port-shell o modem dial-up in remoto.
Modifica il Makefile per impostare le tue chiavi pre-condivise, come definite all'inizio del Makefile.
Poi esegui semplicemente make su Linux e OSX.
Su BSD devi installare GNU make e invocare gmake invece.
Su Windows devi installare cygwin e selezionare
i pacchetti appropriati gcc, gcc-g++, make e git.
Su Linux, PSC userà pseudo terminali Unix98, su altri sistemi userà pty POSIX, ma questo dovrebbe essere trasparente per te. Ho aggiunto una volta il supporto per pty 4.4BSD e SunOS ai tempi della pietra per un motivo particolare, quindi potrebbe compilarsi anche con Solaris.
orgogliosamente sponsorizzato da:
Semplice e diretto. Sulla tua macchina locale, esegui pscl e passa qualsiasi
porta TCP o UDP che desideri inoltrare dal sito remoto a un indirizzo
particolare. Ad esempio:
linux:~ > ./pscl -T 1234:[192.168.0.254]:22 -U 1234:[8.8.8.8]:53
PortShellCrypter [pscl] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: impostata porta TCP locale 1234 per proxy verso 192.168.0.254:22 @ remoto.
pscl: impostata porta UDP locale 1234 per proxy verso 8.8.8.8:53 @ remoto.
pscl: In attesa che appaia la sessione [pscr] ...
linux:~ >
[ UART / SSH / ... login al lato remoto ... ]
Sul sito remoto (l'ultimo salto) con la sessione shell, indipendentemente dal fatto che sia in
una port-shell, SSH, login console, ecc., esegui pscr:
linux:~ > ./pscr
PortShellCrypter [pscr] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: Vista sequenza STARTTLS, abilito la crittografia.
linux:~ >
Una volta eseguito pscr, entrambi i lati stabiliscono un handshake crittografico e posano un ulteriore
protocollo sulla tua sessione esistente che è trasparente per te. Puoi quindi connetterti
a 127.0.0.1:1234 sulla tua macchina locale per raggiungere 192.168.0.254:22 tramite
TCP o il resolver 8.8.8.8 tramite UDP. Questo funziona anche con indirizzi [IPv6],
se il sito remoto ha connettività IPv6. In realtà, puoi anche usarlo per tradurre
software IPv4 in IPv6, poiché ti connetti sempre a 127.0.0.1 sul lato locale.
Puoi passare più parametri -T e -U. Se perdi traccia del fatto che la tua sessione
sia già crittografata e2e, puoi inviare un SIGUSR1 al processo pscl locale, e ti
dirà lo stato.
PSC è utile anche se vuoi usare tor da una shell SSH remota, dove puoi
inoltrare la porta socks5 e la porta DNS all'indirizzo 127.0.0.1 dell'host remoto.
Poiché SSH non inoltra pacchetti UDP, normalmente useresti due connettori socat
o simili per risolvere tramite il nodo tor. PSC ha il vantaggio di mantenere i confini
dei datagrammi UDP, mentre socat su SSH -L può rompere i confini dei datagrammi
e creare richieste DNS malformate.
La sessione sarà crittografata con aes_256_ctr di una PSK che scegli nel
Makefile. Questo schema crittografico è malleabile, ma aggiungere dati AAD o OAD
aumenta la dimensione del pacchetto, dove ogni byte conta poiché nelle sessioni interattive
e a causa della codifica Base64, ogni carattere digitato causa già molti più dati da inviare.
Le sessioni UART possono essere utilizzate tramite screen ma ad esempio non tramite minicom poiché
minicom crea finestre invisibili con righe di stato e agisce come un filtro
che distrugge il protocollo di PSC. PSC cerca di rilevare il filtraggio e può convivere con
una certa quantità di danneggiamento dei dati, ma in alcune situazioni non è possibile recuperare.
Simile con tmux. Dovresti evitare di impilare gestori di pty con PSC che
alterano/gestiscono troppo i dati in arrivo.
La variabile d'ambiente SHELL deve essere impostata sia per pscl che per pscr affinché
PSC sappia quale shell eseguire sulla pty. SHELL è impostata di default nella maggior parte degli
ambienti, ma in caso contrario, PSC deve essere eseguito come SHELL=/bin/bash pscl
ecc.
pscl supporta anche l'inoltro di connessioni TCP tramite SOCKS4 (-4 porta) e SOCKS5
(-5 porta). Questo imposta porta come porta SOCKS per le connessioni TCP, così ad esempio puoi
navigare reti remote da una sessione port-shell senza la necessità di aprire nessun'altra
connessione durante un pen-test. Se passi -N a pscl, abilita la risoluzione dei nomi DNS
sul lato remoto, quindi puoi usare anche Chrome con esso. Ma attenzione: C'è un problema di privacy
con i browser che cercano di risolvere una sequenza di nomi DNS all'avvio che
non è sotto il tuo controllo. Inoltre, se il tuo lato remoto ha una configurazione DNS danneggiata, la tua
shell di digitazione potrebbe bloccarsi per diversi secondi se i pacchetti di risposta DNS mancano. Non esistono
buone funzioni di risoluzione asincrona incorporabili e portabili, quindi ho dovuto fare affidamento su
getaddrinfo() in un unico thread al prezzo di possibili blocchi di diversi secondi
se esistono problemi DNS. Ecco perché la risoluzione dei nomi deve essere abilitata esplicitamente. pscr
cerca comunque di minimizzare questo potenziale problema con cache di ricerca DNS, quindi nella maggior parte
delle situazioni dovrebbe funzionare senza problemi.
Se passi -X indirizzo-IP (deve essere il primo argomento), puoi associare il tuo proxy locale
a un indirizzo diverso da 127.0.0.1, così puoi condividere il proxy nella tua rete locale.
psc offre funzionalità per inoltrare connessioni TCP o blob di dati binari da/verso dispositivi
remoti attraverso più salti, anche se non è possibile installare il binario pscr sul
sito remoto. Questo è molto utile per scopi forensi se non hai alcun mezzo per
scaricare altrimenti artefatti dal dispositivo (che può essere un telefono connesso via UART, ad esempio)
o hai bisogno di inoltrare connessioni senza toccare il filesystem per non distruggere le prove sul sistema
o quando il root-FS è montato in sola lettura e non puoi caricare il tuo set di strumenti.
Questa è una funzionalità davvero interessante, poiché puoi vedere la tua connessione TCP saltare attraverso la tua tty locale verso una macchina remota senza la necessità di installare nulla in remoto.
Questo funziona esclusivamente tramite il punkrock locale della pty e il passaggio di un comando di rimbalzo a pscl che esso
rilascerà sulla shell remota (senza pscr in esecuzione) e un po' di magia del motore di stato che filtra e
gestisce i dati sul lato locale. Di solito questo richiede di impostare prima la pty remota in modalità raw
prima di emettere il comando effettivo e alcuni altri dettagli che vengono passati a -B. L'
argomento è suddiviso nelle seguenti parti:
:, ad es. 1234:.stty -echo raw o
python -c "import tty;tty.setraw(0)" (fai attenzione agli apici, poiché anche -B deve
essere quotato) o qualsiasi altra cosa simile.pscl di iniziare a inviare dati per evitare una race condition tra
l'effettivo stty e l'inizio del comando, ad es. un echo GO è perfetto.nc 127.0.0.1 22 per rimbalzare la porta locale 1234 sul server SSH del remoto.pscl di ripristinare lo stato della tty.
echo FIN farà al caso. Raccomandato, altrimenti potresti avere problemi a riconoscere la fine del
tuo comando.Esempi:
Se vuoi inoltrare una connessione TCP, questo esempio richiede stty e nc installati sul
dispositivo, ma teoricamente potrebbe essere qualsiasi altra cosa che faccia l'equivalente.
Avvia una sessione locale:
./pscl -B '1234:[stty -echo raw;echo GO;nc example.com 22;echo FIN]'
Questo emetterà il comando stty -echo raw;echo GO;nc example.com 22;echo FIN al dispositivo
remoto se ti connetti localmente alla porta 1234 e poi inoltrerà semplicemente qualsiasi dato che vede avanti e indietro
limitando la velocità del traffico in modo da non superare la velocità della tty del dispositivo (115200 è il default).
Quando la sessione pscl è avviata, connettiti al dispositivo remoto tramite UART, ssh -e none ... o
qualsiasi altro metodo e una volta che hai la shell remota, digita anche localmente:
ssh [email protected] -p 1234 per rimbalzare la connessione SSH dalla tua macchina locale attraverso il dispositivo
remoto verso la destinazione example.com. Ovviamente la variante pscr è preferita poiché -B può solo
rimbalzare una singola connessione alla volta (anche se puoi passare più comandi -B per diversi
inoltri) e c'è il rischio di bloccare la shell dopo la sessione TCP poiché la pty è in modalità raw -echo
e a seconda che il peer remoto finale chiuda anche la connessione, potrebbe accadere
che la shell rimanga bloccata dopo. Se ti capita di vedere una notifica pscl che la connessione
è terminata e vedi un prompt, dovresti fare reset, in modo che una nuova connessione possa essere avviata.
Mentre i dati vengono inoltrati, vedrai notifiche -B e > in ASCII 7bit in pscl che
sono solo locali per un debug e un rilevamento del progresso più facili.
Nota che la connessione al sito remoto deve essere pulita a 8 bit, cioè il canale ssh, telnet, UART o
qualunque altro non deve gestire sequenze di escape (a differenza di quando si usa pscr). Per le connessioni ssh
questo significa che devi usare ssh -e none nella sessione pscl.
Successivamente, alcuni esempi per gestire il trasferimento di file binari dove rfile indica il file remoto e lfile il file locale.
Per avviare una sessione per scaricare file remoti, localmente:
./pscl -B '1234:[stty -echo raw;echo GO;dd of=rfile.bin bs=1 count=7350;echo FIN]'
Dove devi specificare la quantità di dati che il lato remoto si aspetta. Funzionerebbe anche
senza (ad es. cat>...) ma poi la sessione si bloccherà dopo che la trasmissione è terminata poiché
cat è in attesa infinita di input. Usando dd count=..., otterrai un'uscita pulita e verrai informato
di ciò dal marcatore FIN.
Quindi, ssh o qualsiasi altra cosa necessaria per ottenere una shell sul dispositivo remoto dalla sessione pscl
appena avviata. Su un secondo terminale localmente:
dd if=lfile.bin|nc 127.0.0.1 1234
che si connetterà alla porta locale 1234 di pscl e attiverà il comando di dump sul lato remoto,
inoltrando i dati binari del file locale lfile.bin al file remoto rfile.bin. A causa della limitazione della velocità
ciò può richiedere un po' di tempo e ti fidi solo dello schermo di avanzamento di psc per sapere se il trasferimento è finito.
Il comando locale dd ...|nc ... ti mostrerà solo lo stato locale che può ingoiare interi file
in millisecondi a causa dei buffer TCP locali mentre il file viene ancora trasferito attraverso la pty.
Quindi assicurati di premere Ctrl-C solo quando lo schermo di pscl ti dice che è finito o vedi
il marcatore di fine FIN che viene rimandato nella sessione dd ...|nc ....
Allo stesso modo, comandi simili potrebbero essere usati per trasferire dati binari da un dispositivo remoto alla macchina locale per scopi forensi. Di nuovo, avvia la sessione localmente:
./pscl -B '1234:[stty -echo raw;echo GO;dd if=rfile.bin]' oppure
./pscl -B '1234:[stty -echo raw;echo GO;cat rfile.bin]'
Poi, ssh al dispositivo remoto per ottenere la shell, poi di nuovo localmente:
nc 127.0.0.1 1234|dd of=lfile.bin bs=1 count=7350
Per ottenere rfile.bin di dimensione 7350 copiato nel file locale lfile.bin
Se stty -echo raw non è disponibile sul dispositivo, qualcosa come
python -c "import tty;tty.setraw(0)" funziona anche. Nota che sul dispositivo remoto devi avere
una tty (non solo una port-shell) quando usi comandi di rimbalzo, poiché il comando stty per impostare la modalità raw
richiede una vera tty.
Se psc funziona su una connessione seriale, i bit persi possono rovinare tutto il divertimento. Se esegui
senza controllo di flusso hardware, alla fine sperimenterai perdita di bit e connessioni bloccate, in particolare
poiché non c'è limitazione quando il dispositivo sta inviando dati nella tua direzione quando usi
comandi di rimbalzo. Scaricare dati sul dispositivo funziona meglio poiché questi dati passano attraverso
i limiti di velocità di pscl.
Tuttavia, ecco alcuni suggerimenti che hanno funzionato per me in circostanze in cui non è
possibile usare pscr sul dispositivo e controllo di flusso hardware. Questo vale solo quando si usano UART, poiché questo
è un canale di trasporto potenzialmente inaffidabile.
pscr sul dispositivo in modo da poter impostare la limitazione della velocità per i dati inviati nella tua direzione.
Poiché la direzione verso il dispositivo è sempre limitata in velocità, puoi usare comandi di rimbalzo per
scaricare un binario pscr cross-compilato sul dispositivo e avviare una sessione bidirezionale limitata in velocità con esso.tio -o 1 o -o 2 per aggiungere ritardi tra i byte di output inviati38400 anche se la linea seriale è impostata a 115200)psc con -DRESPECT_UART_BUFSIZE=4096, tuttavia ciò renderà la sessione molto lentaAll'interno della cartella contrib troverai anche una patch tio-noprefix per disabilitare l'elaborazione dei caratteri di escape,
ma questa patch è necessaria solo per versioni più vecchie, poiché upstream ha già accettato e
integrato questa patch. Raccomando davvero di usare tio quando si usano UART.
Quando usi comandi di rimbalzo attraverso tio, devi aggiungere al tuo file ~/.tioconfig:
[default]
prefix-ctrl-key = none
che disabilita la gestione degli ESC e ti fornisce un canale pulito a 8 bit.
Puoi inviare SIGUSR1 a pscl in modo che ti dica se la sessione è crittografata. Se il remoto
pscr muore o esce senza possibilità di segnalarlo alla parte locale, pscl rimarrà
in modalità crittografia e quindi si bloccherà. In questo caso puoi forzare un reset alla modalità testo semplice
inviando SIGUSR2, in modo che una nuova sessione possa essere avviata.
A partire dalla versione 0.64, psc supporta socket di scripting, quindi non hai più bisogno di screen per
ottenere/inviare file o scaricare buffer di appunti sulla console remota. Invece, avvii la tua sessione
locale in questo modo:
~ > ./pscl -S ~/psc.script_sock
Puoi quindi procedere e usarlo come prima. Se hai bisogno di 'incollare' qualcosa, fai come:
~ > ./pscsh -S ~/psc.script_sock -f script_/helloworld
Questo 'digiterà' il contenuto di script_/helloworld sulla console. Durante lo scripting,
lo stdin di pscl viene bloccato in modo che l'input iniettato non si mescoli con eventuali
digitazioni. Se -S viene omesso in pscsh, viene usato automaticamente ~/psc.script_sock.
Per motivi di sicurezza, gli script devono iniziare con il prefisso script_.
Come bonus, pscr ora contiene la capacità di codificare/decodificare file in base64, anche con
caratteri CR incorporati per comodità. È compatibile con uuencode -m.
; e racchiusi tra parentesi.