Sovrascrivere un indirizzo di memoria

Salve a tutti,

sto cercando di sovrascrivere l'indirizzo di memoria del return con un altro indirizzo di memoria.
Per fare questo ho creato un buffer overflow con questo codice:

void readSerialString () { 
char buffer[8]; char smallBuffer[4]={0,0,0,0};

int sb;
if(Serial.available()) {
    while (Serial.available()){
        sb = Serial.read();
        buffer[indexB] = sb;
        indexB++;
    }
}
if( indexB > 0) {
    strcpy(smallBuffer,buffer);
    Serial.print("You said: ");
    for(count=0; count < indexB; count++) {
        Serial.print( smallBuffer[count] );
    }
    count = 0;
    indexB  = 0;
    Serial.println();
}

}

Ma non riesco ad andare avanti...

DarkCoffee:
sto cercando di sovrascrivere l'indirizzo di memoria del return con un altro indirizzo di memoria

Non mi pare tu stia lavorando con i puntatori. Cos'è che vuoi fare, scusa? Mica l'ho capito.
A me pare che tu stia copiando un array in un altro e poi lo ristampi.

Qui è tutto il codice:

#define F_CPU=16000000
#define ARDUINO 100
#include "Arduino.h"
#include <stdio.h>

int  indexB  = 0;
int  count = 0;

void setup();
void loop();
void readSerialString ();
void printHacked();


void setup(){
	Serial.begin(115200);
	Serial.println("Hello World");
}

void loop(){
	readSerialString();
	Serial.println ("-");
	delay(1500);
}

void readSerialString () {
	char buffer[8];
	char smallBuffer[4]={0,0,0,0};

	int sb;
	if(Serial.available()) {
		while (Serial.available()){
			sb = Serial.read();
			buffer[indexB] = sb;
			indexB++;
		}
	}
	if( indexB > 0) {
		strcpy(smallBuffer,buffer);
		Serial.print("You said: ");
		for(count=0; count < indexB; count++) {
			Serial.print( smallBuffer[count] );
		}
		count = 0;
		indexB  = 0;
		Serial.println();
	}
}

void printHacked(){
	Serial.println("Hacked!");
}

sto cercando di fare una cosa simile a "Exploiting stack buffer overflows" che puoi vedere qui: Stack buffer overflow - Wikipedia

Ma perché o per cosa vuoi farlo?
Ciao Uwe

Sto lavorando ad un progetto all'università.
L'idea è di attaccare il codice sulla board in modo da gestire il flusso di memoria.

x iscrizione

Scusa, non ho capito cosa vuoi dire...

tranquillo, significa che sono interessato al topic, e quindi mi ritrovero' le risposte automaticamente in alto a destra, sezione Replies.
Del topic in se non so nulla :slight_smile:

DarkCoffee:
Sto lavorando ad un progetto all'università.
L'idea è di attaccare il codice sulla board in modo da gestire il flusso di memoria.

More informations please

Credo che ci sia alla base un concetto errato.
Un conto è far girare un programma su un computer con un sistema operativo che sovrintende al controllo degli accessi alla memoria, un conto è far girare un programma su un microcontrollore dove non c'è sistema operativo e dove il controllo sulla memoria lo deve fare l'utente stesso in fase di stesura di codice.

Se tu su un computer crei un array e poi cerchi di andare fuori dai suoi limiti credo (ma non lo so con certezza non essendo un sistemista) che sia lo stesso sistema operativo che vede accedere ad un'area di memoria non assegnata a quel programma a bloccare il software, e poi quindi generare l'errore di overflow.
Su un microcontrollore, invece, puoi benissimo accedere al di fuori di un array. Non riceverai nessun tipo di errore perché non c'è nessuno a dirti che hai fatto una cosa che non potevi fare. Te ne potresti accorgere, però, per via di effetti indesiderati che la tua azione potrebbe provocare. Tu sai che un microcontrollore come l'Atmel Atmega328P lavora con architettura Harvard, quindi ha la memoria del programma (Flash) separata dalla memoria dei dati (SRAM). In questa ultima memoria il micro crea le variabili del programma, tiene l'heap per l'allocazione dinamica delle risorse e crea lo stack. Accedendo al di fuori dei limiti di un array potresti semplicemente andare a leggere/scrivere in un'area di SRAM inutilizzata che però contiene dati precedentemente salvati lì. Scrivendoci sopra non avresti nessun problema, leggendoci potresti tirare fuori informazioni senza senso che potrebbero alterare il tuo programma. Oppure potresti anche andare a scrivere su parti usate dal resto del programma oppure dalla stessa CPU, ad esempio potresti scrivere su una porzione dello stack! Pensa se in quel momento il chip avesse salvato i registri per una chiamata ad una ISR, tu andresti ad alterare lo stato salvato del micro. Al ripristino, le conseguenze potrebbero essere qualunque, anche un improvviso blocco e reset.

A me è capitato l'altro giorno. Lavoravo ad un progetto molto complesso e leggevo/scrivere diverse decine di dati dalla EEPROM . Mi sono accorto che all'avvio il progetto funzionanva come doveva, mentre al successivo reset perdevo l'uso di una fila di pulsantini di una tastierina 4x4 collegata :wink: Alla fine ho capito che al primo avvio scrivevo le info sulla EEPROM e contemporaneamente caricavo i dati in un array, mentre al reset seguente andavo a caricare i dati in un array al di fuori dei suoi limiti, ed il chip si comportava nel modo che ti ho descritto :wink:

Grazie per l'aiuto!

Il progetto su cui sto lavorando è far un attacco sulla board (precisamente una atmega2560), utilizzando proprio il buffer overflow.
Quello che devo fare è sovrascrivere lo stack fino al raggiungimento del return address e quindi sovrascriverlo con un puntatore.
Secondo te è possibile farlo?
Il return address dovrebbe essere salvato nello stack, come i dati del buffer che vado a scrivere, giusto?

ma vista la struttura della ram basta scrivere uno sketch che la riempie ed hai il tuo bel crash :slight_smile: perche' va a sovrascrivere lo stack

perchè quando sovrascrivo il return address con un puntatore ad un altro punto della memoria posso far partire una parte del programma che non era previsto.

ok, alzo le mani allora, non e' il mio campo, Leo di certo sapra' risponderti
ma e' a titolo di studio ? credo stiamo parlando di una specie di virus ? integri nello sketch un qualcosa e solo tu poi saprai come arrivare a farlo partire ?

Si si è a titolo di studio, esattamente per la tesi =(
Comunque grazie per cercarmi di aiutare!

Uhm.. non credo che tu possa fare quello che vuoi. Non sono un esperto come mi dipinge Testato, però nell'Atmega le variabili statiche sono salvate nella prima parte della SRAM mentre lo stack è creato a partire dall'ultima locazione di SRAM a crescere verso il basso.
In mezzo c'è l'heap e l'area che raccoglie le variabili non inizializzate del programma. E la memoria libera.

sram.jpeg

Ma se creo una funzione mettiamo caso in c, senza pensare all'arduino language, in questo modo:

getInput(){
  char buff[8];
  getc(buff);
  putc(buff);
}

int main(){
  getInput();
  return 0;
}

la memoria sarà buff(8 byte), indirizzo del fp(2 byte), return address(2 byte). Quindi se sovrascrivo il buff mettendo 10caratteri da tastiera dovrei arrivare al return address, giusto?
Ora, vorrei applicarlo usando l'arduino language o comunque il c dentro un programmino arduino per la mia atmega2560.

Solo una precisazione, non esiste un "Arduino language".
In uno sketch Arduino si scrive in C o C++ in quanto il tutto viene compilato dal avr-gcc (compilatore gnu c per gli avr).
Arduino ha dietro un framework chiamato Wire, un insieme di librerie e un main che "nasconde" la solita struttura main() di un qualsiasi programma C e che richiama una volta la setup() e in un ciclo infinito la loop().
I sorgenti di questi codici sono nelle cartelle dell'IDE (....\arduino-IDE\hardware\arduino\cores\arduino). Ci troverai anche un bel main.c

#include <Arduino.h>
int main(void)
{  init();
#if defined(USBCON)
	USBDevice.attach();
#endif
	setup();
   	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
	return 0;
}

Hai partecipato a questa discussione (vedo un Darkcoffee)?

Sembra l'unica cosa che si trovi in internet sull'argomento

E poi mi sembra che il grande @Gammon del forum ti ha trovato la soluzione :
http://forum.arduino.cc/index.php?topic=182559.msg1356108#msg1356108

Però quel che non mi è chiaro è la motivazione su un Atmel. Il codice che viene iniettato è comunque nel tuo sketch.
Di solito un attacco del genere su PC viene fatto da un codice sul codice di un altro programma.
Al limite mi viene in mente un attacco del genere ad un Arduino su cui gira un server (Ethernet library) e attraverso http gli passi richieste anomale.

nid69ita:
Solo una precisazione, non esiste un "Arduino language".
In uno sketch Arduino si scrive in C o C++ in quanto il tutto viene compilato dal avr-gcc (compilatore gnu c per gli avr).
Arduino ha dietro un framework chiamato Wire, un insieme di librerie e un main che "nasconde" la solita struttura main() di un qualsiasi programma C e che richiama una volta la setup() e in un ciclo infinito la loop().
I sorgenti di questi codici sono nelle cartelle dell'IDE (....\arduino-IDE\hardware\arduino\cores\arduino). Ci troverai anche un bel main.c

#include <Arduino.h>

int main(void)
{  init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
  for (;:wink: {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}

mmm, sono un po' confusa.
Dalla pagina di arduino, ho letto questo

Can I program the Arduino board in C?
In fact, you already are; the Arduino language is merely a set of C/C++ functions that can be called from your code. Your sketch undergoes minor changes (e.g. automatic generation of function prototypes) and then is passed directly to a C/C++ compiler (avr-g++). All standard C and C++ constructs supported by avr-g++ should work in Arduino. For more details, see the page on the Arduino build process.

Mentre qui c'è una serie di funzioni, strutture e variabili: Arduino - Home
Inoltre quando ho voluto usere printf e scanf ho dovuto configurare l'uart e aprire stdout e stdin.

nid69ita:
Hai partecipato a questa discussione (vedo un Darkcoffee)?
atmega - Exploiting stack buffer overflows on an Arduino - Electrical Engineering Stack Exchange
Sembra l'unica cosa che si trovi in internet sull'argomento

E poi mi sembra che il grande @Gammon del forum ti ha trovato la soluzione :
Handle memory - #39 by nickgammon - Programming Questions - Arduino Forum

Però quel che non mi è chiaro è la motivazione su un Atmel. Il codice che viene iniettato è comunque nel tuo sketch.
Di solito un attacco del genere su PC viene fatto da un codice sul codice di un altro programma.
Al limite mi viene in mente un attacco del genere ad un Arduino su cui gira un server (Ethernet library) e attraverso http gli passi richieste anomale.

Si, la discussione su electronics.stackexchange l'ho aperta io. Le risposte sono stati interessanti, il paper che mi ha proposto Warren Young l'avevo già letto. Il problema è che ho bisogno di trovare la strada giusta, perchè non riesco, in modo pratico, ad andare avanti.
E' vero, Gammon mi sta aiutando, è molto bravo e spiega bene.
Spero che con questo forum, molto preparato, riesco ad uscire da questo problema.

Inizialmente sto creando io la vulnerabilità, dopo che questo primo esperimento è stato fatto, dovrei cercarlo di applicarlo ad un programma che mi hanno dato loro. Ed infatti, proprio in questo programma c'è l'invio di messaggi tramite tcp. Quindi l'idea è quella di mandare un pacchetto con una grandezza giusta e con il giusto payload.