[C] Exploit

Hi,kann mir jemand sagen wie ich diesen Code,wenn ich die Stack Adresse kenne exploiten kann,damit ich die cin.get() Anweisung überspringen kann?Wenn man unter cout<<*ka schreibt *ka += 9,dann wird die cin.get() Anweisung übersprungen!Wie kann man das schaffen ohne diese Anweisung zu schreiben?

Betriebssystem:Windows,Compiler DevC++

Code:
#include <iostream.h>

void fuckn(char *s)
{
     char buffer[8];
     int *ka = (int*)&s-1;
     cout << *ka;

     strcpy(buffer,s);

     }

int main()
{
   char ka[100];memset(ka,0,sizeof(ka));
    
    cin >> ka;
    
    fuckn(ka);
    
    cin.get();
    cin.get();
    
    cout << "\a\a\a";
    
    system("PAUSE");
    return 0;
}

Ich habe versucht bei cin>>ka folgendes einzugeben:

buffer vollschreiben: 12345678 ,dann Stack Pointer schreiben (Adresse von cout<<*ka um 9 erhöht)


Funktioniert aber nicht???
Normalerweise müsste doch nach "12345678" buffer voll sein und der andere Teil wird in den Stack Pointer geschrieben?

Wenn jemand das weiß,bitte Quellcode schicken.
 
Zuletzt bearbeitet:
Eigentlich ist Dev C++ kein Compiler :wink:
Normalerweise müsste doch nach "12345678" buffer voll sein und der andere Teil wird in den Stack Pointer geschrieben?
Wie kommst Du darauf? Als Programmierer hast Du erstmal keinen/kaum Einfluss, welcher Maschinencode am Ende generiert wird (ja, die C++ ler hören es nicht gerne ;) ). Insbesondere was Funktions/Variablenadressen oder Puffergrößen angeht. Alle "Tricks" diesbezüglich sind höchst compilerabhängig :wink:

Der Compiler kann z.B aus Optimierungsgründen (geschweige denn BoF Schutz) die Puffergröße erhöhen. Oder gleich die Funktion "wegoptimieren" und den Inhalt inlinen.

Lass Dir mal den Assemblycode ausgeben:
gcc -S -c deinedatei.cpp
wobei ich hier reines C vorziehen würde (und schon gar nicht DevC++ Aufruf, da dieser per Default nur 1 Asm Datei generiert, in der man nichts mehr findet) ;)

Edit:
fast vergessen:
üblicherweise sieht die vom Compiler generierte Funktions-entrysequenz
http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames
so aus:
Code:
push ebp
mov ebp, esp
sub esp, X  <--- reserviere Speicher für lokale Variablen
d.h noch bevor irgendwelche Buffer angelegt werden, wird der Wert von EBP auf dem Stack gespeichert.

Der Stack schaut dann so aus:
1. direkt nach Funktionscall, aber vor der Ausführung des Funktionscodes:
Code:
...
leer
leer <---
leer <--- frei durch die Funktion nutzbar

Rücksprungsadresse <-- ESP zeigt darauf
arg1
arg2
arg3

2.nachdem der Stackframe eingerichtet, aber noch bevor der Speicher für lokale Variablen reserviert wurde:
Code:
leer
leer
alter EBP Wert  <--- ESP und EBP 
Rücksprungsadresse
arg1
arg2
arg3
3. Und so sieht es nach der Speicherreservierung aka "SUB ESP, X" aus:
Code:
leer   <--- ESP
...
leer
leer
alter EBP Wert  <--- EBP zeigt darauf
Rücksprungsadresse
arg1
arg2
arg3
Das sorgt dafür, dass Operationen auf dem Stack die lokalen Variablen nicht beeinträchtigen. Und i.R wird auf diese(lokalen Variablen) über
[EBP - X] zugegriffen.
D.h Du musst nicht nur den Buffer überschreiben, sondern auch noch "andere" Werte.


Hier mal der Code, den mir GCC 4.2 für die Funktion generiert:
Code:
0040143C  /$  55            PUSH EBP
0040143D  |.  89E5          MOV EBP,ESP
0040143F  |.  83EC 18       SUB ESP,18   <---- deutlich größer, als 8 Chars==Bytes + 1DWORD==4 Bytes für den int *ka00401442    8D45 08         LEA EAX,DWORD PTR SS:[EBP+8]
00401445    83E8 04         SUB EAX,4
00401448    8945 FC         MOV DWORD PTR SS:[EBP-4],EAX
0040144B    8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]
0040144E    8B00            MOV EAX,DWORD PTR DS:[EAX]
00401450    894424 04       MOV DWORD PTR SS:[ESP+4],EAX
00401454    C70424 B4344700 MOV DWORD PTR SS:[ESP],a.004734B4
0040145B    E8 10A60300     CALL a.0043BA70
; hier kommt der strcpy Aufruf:
00401460    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]   <-- lade Argumen (char *s)
00401463    894424 04       MOV DWORD PTR SS:[ESP+4],EAX  <-- "pushe" diesen auf den Stack
00401467    8D45 F4         LEA EAX,DWORD PTR SS:[EBP-C]     <-- Adresse des Buffers
0040146A    890424          MOV DWORD PTR SS:[ESP],EAX
0040146D    E8 AE760000     CALL <JMP.&msvcrt.strcpy>
00401472    C9              LEAVE
00401473    C3              RETN
Man sieht:
1) dass deutlich mehr Speicher reserviert wird, als benötigt
2) intern befindet sich der "buffer" an [EBP-C]. D.h dass bis zur "Stack Base" noch 0xC == 12 Bytes Platz ist. Zudem noch 4 Bytes für den alten EBP Wert -> 12+4 == 16 Bytes, bevor man anfängt, die Rücksprungsadresse zu überschreiben ;)
 
Zurück
Oben