HW CTF, Reverse Engineering

« Older   Newer »
  Share  
Elemento 38
view post Posted on 23/4/2018, 19:19




Dopo aver seguito un corso di sicurezza hardware e software, mi sono interessato a piccole sfide CTF (Capture-The-Flag).
In pratica, si ha accesso ad un sistema (sito web, programma compilato, pin di un microcontrollore, ...) e attraverso la costruzione di input speciali l'obiettivo è trovare la "flag" dentro al sistema (che alla fine e' come se fosse un password segreta).

Semplicemente, questi sono problemi di penetration testing, in cui si vuole forzare un programma/sistema a fare cose che non dovrebbe. Ad esempio, nel programma qua sotto e' possibile chiamare la funzione in grassetto anche se non viene usata da nessuna parte!

SPOILER (click to view)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

char greeting[] = "Hello theren1. Receive wisdomn2. Add wisdomnSelection >";
char prompt[] = "Enter some wisdomn";
char pat[] = "Achievement unlocked!n";
char secret[] = "secret key";

int infd = 0; /* stdin */
int outfd = 1; /* stdout */

#define DATA_SIZE 128

typedef struct _WisdomList {
struct _WisdomList *next;
char data[DATA_SIZE];
} WisdomList;

struct _WisdomList *head = NULL;

typedef void (*fptr)(void);

void write_secret(void) { <------------
write(outfd, secret, sizeof(secret));
return;
}


void pat_on_back(void) {
write(outfd, pat, sizeof(pat));
return;
}

void get_wisdom(void) {
char buf[] = "no wisdomn";
if(head == NULL) {
write(outfd, buf, sizeof(buf)-sizeof(char));
} else {
WisdomList *l = head;
while(l != NULL) {
write(outfd, l->data, strlen(l->data));
write(outfd, "n", 1);
l = l->next;
}
}
return;
}

void put_wisdom(void) {
char wis[DATA_SIZE] = {0};
int r;

r = write(outfd, prompt, sizeof(prompt)-sizeof(char));
if(r < 0) {
return;
}

r = (int)gets(wis);
if (r == 0)
return;

WisdomList *l = malloc(sizeof(WisdomList));

if(l != NULL) {
memset(l, 0, sizeof(WisdomList));
strcpy(l->data, wis);
if(head == NULL) {
head = l;
} else {
WisdomList *v = head;
while(v->next != NULL) {
v = v->next;
}
v->next = l;
}
}

return;
}

fptr ptrs[3] = { NULL, get_wisdom, put_wisdom };

int main(int argc, char *argv[]) {

while(1) {
char buf[1024] = {0};
int r;
fptr p = pat_on_back;
r = write(outfd, greeting, sizeof(greeting)-sizeof(char));
if(r < 0) {
break;
}
r = read(infd, buf, sizeof(buf)-sizeof(char));
if(r > 0) {
buf[r] = '�';
int s = atoi(buf);
fptr tmp = ptrs[s];
tmp();
} else {
break;
}
}

return 0;
}


Esercizi come questo sono molto interessanti, perche' richiedono di capire come funziona il sistema prima di "attaccarlo".
Poco tempo fa mi sono iscritto a questo sito https : // microcorruption . com / che usa come sistema un microcontrollore (MSP430), e l'obiettivo e' fare entrare il programma nella funzione che usa un interrupt per aprire una serratura.

Non so in quanti possano essere interessati, ma trovo molto interessante il problema della sicurezza (soprattutto ora che l'Internet-of-things sta spopolando, e questi esercizi di reverse engineering / penetration testing sono utili per tenere la mente fresca :)
 
Top
view post Posted on 23/4/2018, 21:32
Avatar

GWFstory

Group:
Administrator
Posts:
359
Location:
da qui...., quo, qua. Siete curiosi di saperlo, vero? No? Beh, tanto non ve l'avrei detto.

Status:


Interessante come discorso.

Io ho mio figlio che ogni volta che succede qualcosa di strano parla di "buggato".

Non c'è verso di fargli capire che se uno si schiaccia un dito non è buggato, ma infortunato. :wb:
Non c'è neppure verso di fargli capire che i bug sono degli errori di programmazione, che portano a risultati inattesi, causati dal fatto che il programmatore non ha considerato tutte le condizioni/combinazioni che avrebbe dovuto considerare; :stres:
Quando si verifica una condizione non attesa il programma può fare cose più o meno casuali. :wacko: :blink:

Gli hacker cercano questi bug e riescono a penetrare le difese usando delle specie di bypass al normale flusso di programma.

Comunque devo confessare che ho guardato il listato che hai postato (magari non con l'attenzione che avrei dovuto, ma comunque non mi sono limitato a scrollarlo), e non c'ho capito molto.
Devo dire che non sono molto bravo a capire i listati degli altri senza che mi vengano spiegati nello stesso modo usato con i bambini (P.S. Bambino non sono da almeno 40 anni!!! :cry: :( )

Comunque, tornando al discorso degli hacker, vorrei capire come fanno a scovare i bug di sicurezza: è vero che dei progetti open-source esistono i listati, quindi è abbastanza facile capire i punti deboli, ma in tutti gli altri casi non capisco proprio come ci riescano (forse è per quello che non seguo l'informatica :huh: ).
Anni fa avevo il sito web aziendale, che girava con Joomla 1.x, che fu attaccato varie volte.
Io non mi decidevo ad aggiornarlo perchè migrare alle versioni più recenti di Joomla mi avrebbe costretto a rifarlo (quasi) da zero. Così ciclicamente mi toccava rimetterci le mani, ripulirlo dei file che l'idiota di turno (non saprei come definirlo diversamente, dato che non stava certamente facendo un qualcosa di così epico o avveniristico, visto che nel web si trovavano i tutorial su come riuscire a perforare Joomla 1.x) e sperando che alla fine ripartisse il tutto.
Qualche volta mi accorsi che l'avevano bucato più volte e ognuno aveva lasciato il "ricordino" sotto forma di immagine, testo o altro.

Alla fine l'informatico che ci segue ebbe un'idea semplice ma geniale: ci installò in locale il sito con i relativi data-base e ci fece usare un programma che si chiama HTTtrack, che compila un sito convertendolo in pagine statiche formate da un file .html e uno .pdf. Praticamente il sito diventa un sito statico, senza PHP o script di vario tipo, che però si comporta esattamente come quello originale. Il vantaggio è che le vulnerabilità non ci sono più.

Il tutto avrebbe funzionato per un tempo indefinito, ma alla fine 2-3 anni fa decidemmo di cambiarlo e ora usa un altro sistema di gestione data-base.

Questa è la storia del sito web aziendale..... ma cosa succederebbe per tutte le applicazioni in cloud, per i cosiddetti big-data dell'industria 4.0 (per chi non lo conoscesse si tratta di condividere i dati relativi a produzione, teleassistenza, ecc. sul web per renderli controllabili da remoto)?

Verrebbe un vero e proprio casino, col rischio di bloccare la produzione, di allertare qualcuno anche in caso di macchine perfettamente funzionanti, ecc. Sembra tutto bello, ma lo è (forse) fino a quando funziona tutto bene. Se qualcosa non va (per cause accidentali o anche volute/provocate) si paga dazio, anche perchè non è facile rendere sicuri oggetti che si basano su hardware spartani e con poche risorse, dove le barriere anti-intrusione devono essere limitate nelle funzioni, se non addirittura assenti.

Esistono anche siti che consentono di collegarsi a dispositivi IP (soprattutto webcam) sparse nel mondo (ne vidi uno ma non ricordo come si chiama); la cosa che può sembrare normale, ma dopo tutto stiamo parlando di sistemi di videosorveglianza, che se bucati potrebbero venire disattivati..... Insomma l'IoT è una medaglia a 2 facce: una positiva e l'altra (molto) negativa.
 
Top
Elemento 38
view post Posted on 23/4/2018, 22:07




QUOTE
Comunque, tornando al discorso degli hacker, vorrei capire come fanno a scovare i bug di sicurezza: è vero che dei progetti open-source esistono i listati, quindi è abbastanza facile capire i punti deboli, ma in tutti gli altri casi non capisco proprio come ci riescano (forse è per quello che non seguo l'informatica :huh: ).

Sicuramente serve un po' di esperienza o conoscenza profonda di sistemi operativi, soprattutto la parte dello stack e la chiamata di funzioni, ma molti problemi si possono trovare anche con cose semplici tipo buffer overflow :)
Ad esempio, se un codice usa la funzione C "gets", questo e' quello che dice il manuale:
QUOTE
harrym@harrym-mbp man gets
[...]
SECURITY CONSIDERATIONS
The gets() function cannot be used securely. Because of its lack of bounds checking, and the inability for the calling program to reli-
ably determine the length of the next incoming line, the use of this function enables malicious users to arbitrarily change a running
program's functionality through a buffer overflow attack. It is strongly suggested that the fgets() function be used in all cases. (See
the FSA.)

Praticamente dice cha la funzione gets non deve essere usata, perche' legge tutto l'input fino a quando non trova un carattere "newline" ... anche se la stringa dove vogliamo salvare l'input e' solo di qualche carattere :rolleyes:
 
Top
view post Posted on 24/4/2018, 07:05
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Mi pare anche scanf() sia deprecata per quel motivo.
Ormai non dovrebbe piu' essere usata. Io non la uso.
Comunque per fare queste cose, come detto da Ele, serve veramente molta competenza, ma veramente tanta
 
Top
view post Posted on 24/4/2018, 07:21
Avatar

GWFstory

Group:
Administrator
Posts:
359
Location:
da qui...., quo, qua. Siete curiosi di saperlo, vero? No? Beh, tanto non ve l'avrei detto.

Status:


Certo che basarsi sul fatto che un buffer vada in overflow per scavalcare una sicurezza è tanto ingegnoso quanto approssimativo, dato che, inserendo una stringa troppo lunga, si finirebbe per sovrascrivere le variabili che seguono, ma i risultati sarebbero incerti.

A me è capitato più di una volta di avere problemi durante la stesura di un programma in C solo perchè ad una funzione passavo un parametro che spostava un puntatore al di fuori di un array (es. quando dovevo visualizzare un messaggio su un display LCD gli passavo il puntatore di inizio del testo, ma se sbagliavo valore capitavano cose strane, dato che il puntatore che leggeva nella memoria dei testi finiva per puntare in posti diversi da quelli stabiliti).

Comunque grazie a questa discussione sono riuscito a capire che i sistemi che ho fatto fino ad ora sono generalmente sicuri dato che, non avendo l'interfaccia utente, non si riesce a "bucare" il firmware.

Praticamente risulta che....

Pur senza volerlo ho applicato una delle frasi citate generalmente come leggi di Murphy:

"Arthur Bloch:

“Nessuna pianificazione, per quanto attenta, potrà mai sostituire una bella botta di culo.”
:D


:D E' proprio il mio caso..... :lol:

...e con buona pace di quelli che si considerano programmatori infallibili. -_-

Gli infallibili sono solo quelli che si limitano a dire agli altri cosa devono fare, magari senza capirne nulla, restando in attesa che sbaglino per farglielo notare. <_<
 
Top
view post Posted on 24/4/2018, 10:06
Avatar

Immane Rompiball

Group:
Administrator
Posts:
18,287
Location:
Orlo esterno della cintura di Orione stella 1957

Status:


Io sto odiando di nuovo l'informatica. -_-
Verso la fine degli anni 70 mi ero innamorato perchè tutto aveva un senso, i processori erano "logici" e non "aleatori" come adesso.
O meglio, i sistemi di programmazione fanno "cagare" magari i processori no.
Oramai per aggirare i brevetti di tizio e di caio e fare dei processori veloci si inventano le peggio cose strane. Poi si implementa un
C compiler che rimette tutto apposto (seeee!)
Qualche tempo fa mi capitò un cross compiler in C che produceva del codice per dei microprocessori. Scrissi un programma che mi
portò via un casino di tempo. Questo programma risultò BUGGATO, perchè ogni tanto faceva cose incredibili e poi si piantava.
Non era colpa mia ma non sapevo perchè. Dopo qualche anno di investigazione scoprii che il "BUGGO" era proprio nel compilatore che
inseriva, non ricordo più in che funzione un codice che in qualche caso con qualche dato particolare il casino totale perchè la fun non trovava
mai un RET lo stack andava in coma ed i dati venivano interpretati come codici. Solo dopo tre anni trovai dove qualcuno, ometto gli articoli
per pudicizia, si era dimenticato il RET. Ma ormai, lavoro, investimento e soldi erano stati persi.
Morale della favola. Ogni sistema più è complesso più è sottoposto a contenere degli errori prodotti durante la sua realizzazione e questi
vengono fuori sempre quando meno te lo aspetti. Quindi, invece di impiegare RISC velocissimi con tre istruzioni sole, forse sarebbe meglio
usare dei CISC solo più complessi quanto basta per evitare queste cose. Il problema dei diritti d'autore è un'altra storia.
Poi, un'altra storia sono i programmatori moderni che usano un programma per generare codici di ogni tipo, un'altro per metterli insieme.
Un compilatore, un "appiccicatore" un "semplificatore" un "linkatore" e così via fino ad avere... cosa? E chi se lo ricorda più. Però si può
vendere... :)
 
Web  Top
Elemento 38
view post Posted on 24/4/2018, 14:18




QUOTE
Certo che basarsi sul fatto che un buffer vada in overflow per scavalcare una sicurezza è tanto ingegnoso quanto approssimativo, dato che, inserendo una stringa troppo lunga, si finirebbe per sovrascrivere le variabili che seguono, ma i risultati sarebbero incerti.

La parte interessante e' proprio questa, riuscire a cambiare il funzionamento senza distruggere il sistema :)
QUOTE
Comunque grazie a questa discussione sono riuscito a capire che i sistemi che ho fatto fino ad ora sono generalmente sicuri dato che, non avendo l'interfaccia utente, non si riesce a "bucare" il firmware.

Lascio questo video, dove per uscire da un loop l'utente introduce glitches sull'alimentazione del microcontrollore :D
www.youtube.com/watch?v=6Pf3pY3GxBM
QUOTE
Verso la fine degli anni 70 mi ero innamorato perchè tutto aveva un senso, i processori erano "logici" e non "aleatori" come adesso.

Ma poi non avremmo le gioie dello scoprire bugs come Spectre/Meltdown ... :)
QUOTE
Quindi, invece di impiegare RISC velocissimi con tre istruzioni sole, forse sarebbe meglio usare dei CISC solo più complessi quanto basta per evitare queste cose.

La domanda e', conviene produrre CISC? La complessita' per verificare la parte HW e' molto piu' alta che verificare il compilatore alto livello -> RISC, a mio parere (e puo' essere facilmente aggiustato post-produzione).
 
Top
view post Posted on 24/4/2018, 16:20
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Non mi addentro, cose troppo complicate. Volevo solo dire che ne hai fatta di strada Ele!! Giù il cappello come dice Guido Meda :)
 
Top
Elemento 38
view post Posted on 24/4/2018, 19:34




:lol:
In realtà non sono cose troppo complicate, con un po’ di studio. È difficile trovare corsi sulla sicurezza software (che non sia sicurezze relativa a siti internet), ma queste competizioni CTF aiutano molto perché solitamente chi risolve un problema pubblica online ottime spiegazioni su come riprodurre il tutto!
 
Top
view post Posted on 24/4/2018, 21:36
Avatar

GWFstory

Group:
Administrator
Posts:
359
Location:
da qui...., quo, qua. Siete curiosi di saperlo, vero? No? Beh, tanto non ve l'avrei detto.

Status:


CITAZIONE
Lascio questo video, dove per uscire da un loop l'utente introduce glitches sull'alimentazione del microcontrollore :D
www.youtube.com/watch?v=6Pf3pY3GxBM

Me lo sono guardato ed è interessante. A parte il discorso della lingua inglese, che per me è un po' ostica dal punto di vista dell'ascolto e non mi ha permesso di seguire tutte le spiegazioni, è molto interessante.

Il tizio è riuscito a fare saltare la protezione facendo quello che io ho sempre cercato di evitare quando progetto l'hardware, ovvero la presenza di glitch sull'alimentazione in grado di mettere in crisi il microprocessore/microcontrollore.

Mi ricordo che una volta andai da un cliente a 300Km di distanza che lamentava che una nostra scheda attivava un'elettrovalvola in modo casuale invece di seguire temporizzazioni precise legate ad una fotocellula.
Arrivato sul posto vidi che effettivamente il difetto lamentato era vero e questa elettrovalvola, che attivava uno spruzzo di adesivo, veniva comandata a casaccio, anche quando la fotocellula non veniva attivata.

Avevo con me l'oscilloscopio e andai a verificare l'alimentazione della nostra scheda, che doveva essere alimentata a 24V in corrente continua.
Notai che sul filo del +24V erano presente degli spikes (picchi di tensione) che raggiungevano i 150V.

L'anomalia non era però dipendente da questi spikes, perchè malgrado l'alimentazione pessima la scheda continuava a funzionare correttamente (avevo curato molto bene la sezione di alimentazione e al microcontrollore arrivavano 5V perfetti).
Il problema arrivava invece dalla fotocellula, che gli spikes li digeriva male e sull'uscita generava degli impulsi brevi (dell'ordine delle centinaia di uSec), ma di durata sufficiente ad attivare la scheda, che faceva il suo dovere, comandando la pistola.
Scoprii anche chi era a generare tali spikes: era un motore elettrico comandato da un inverter che, quando sforzava irradiava onde elettromagnetiche ovunque, inducendo i picchi di tensione nei cavi vicini (alla faccia della macchina con marcatura CE).

Avevo così scoperto che la scheda era sufficientemente robusta da potere essere molto maltrattata, ma il problema restava.....

Come finì la storia?
Per i curiosi ecco qui sotto la soluzione.

Misi un condensatore ceramico da 0,1uF fra l'uscita della fotocellula e il negativo dell'alimentazione. Il condensatore aveva una capacità sufficiente a cortocircuitare a massa gli impulsi brevi, ma era praticamente ininfluente sulle attivazione "reali" della fotocellula


In 20 di attività nell'automazione industriale di problemi del genere ne ho trovati a bizzeffe. :blink: :wacko:
 
Top
9 replies since 23/4/2018, 19:19   83 views
  Share