Code anhängen



  • Der Trick bei den sogenannten Exploits ist der, dass man die Rücksprung Adresse einer Funktion überschreibt (die wird ja von call auf den Stack gepusht) und somist dafür sorgt, dass die Funktion an die Stelle des eigenen Codes springt, dann führt das OS den Code in dem glauben aus, dass dieser zum Programm gehört, deswegen stürzt dieses nicht ab.

    Stack

    [data0][data1][data2][data3][data4]...[data200][ret]
    

    [dataX] sind Daten auf dem Stack
    [ret] ist die Rücksprungadresse

    nun schreibt man in data0 einfach den eigenen Binär Code (mit entsprechenden NOPs aufgefüllt, damit die Adresse nicht 100% genau sein muss und der komplette Code ausgeführt wird (sonst springt jemand eine Anweisung zuweit und der Exploit läuft schief)) dann füllt man die letzten Bytes mit der Rücksprungadresse zum eigenen Code (das muss man ein bisschen raten) und schon springt das Programm beim Rücksprung aus der Funktion nicht zu der Anweisung nach der Funktion, sondern zu dem Exploit Code (auch Shellcode genannt).

    In irgend einer Ausgabe des Phrack Magazins (ist ein Online Hacker Magazin, dass aber oft interessante Artikel enthält, auch wenn man nicht l337 ist ;)) ich glaube 0x42 oder so, gibt es einen guten Artikel zu dem Thema.



  • Also, irgendwie so:

    ;Functionsparameter
    push 1234h
    push 4321h
    call MeineFunction
    

    und die Function sieht dann so aus:

    MeineFunction:
    ; Ich hole meine Parameter
    pop ax
    pop bx
    ; und pop'e einmal zuviel:
    pop dx
    ; steht jetzt in dx meine ruecksprungaddresse?
    push 09F5h
    ;jetzt springt er nach ret zu 09F5h? Oder nicht?
    push bx
    push ax
    ret
    

    Hoffe ich habe jetzt nicht zuviel falsch gemacht, also bitte nicht anprangern,
    ich habe schon seit urzeiten kein assembler mehr geschrieben, also das beispiel wimmelt wahrscheinlich von Fehlern.

    gruesse

    [ Dieser Beitrag wurde am 16.11.2002 um 08:46 Uhr von mADC++er editiert. ]



  • müsste er eigentlich

    schau dir am besten mal den Artickel an



  • Jupp, hab ich!!

    Danke für den Tipp, die Zeitung ist wirklich nicht schlecht, obwohl
    Schrotflintenmunition basteln nicht unbedingt mein Spezialgebiet ist 😉

    greets



  • Original erstellt von mADC++er:
    **Also, irgendwie so:

    ;Functionsparameter
    push 1234h
    push 4321h
    call MeineFunction
    

    und die Function sieht dann so aus:

    MeineFunction:
    ; Ich hole meine Parameter
    pop ax
    pop bx
    ; und pop'e einmal zuviel:
    pop dx
    ; steht jetzt in dx meine ruecksprungaddresse?
    push 09F5h
    ;jetzt springt er nach ret zu 09F5h? Oder nicht?
    push bx
    push ax
    ret
    

    Hoffe ich habe jetzt nicht zuviel falsch gemacht, also bitte nicht anprangern,
    ich habe schon seit urzeiten kein assembler mehr geschrieben, also das beispiel wimmelt wahrscheinlich von Fehlern.**

    Jo, das stimmt net ganz. So, wie der Code jetzt aussieht, holst Du zuerst in ax die Ruecksprungaddresse vom Stack, in bx und dx die beiden Parameter.
    Dann legst Du 09F5h auf den Stack und dahinter bx und ax (4321h u. in ax die Ruecksprungaddresse).
    D.h. mit dem ret springt die CPU wieder genau dahin, wo sie hinspringen wuerde, wenn Du den Stack nicht manipuliert haettest, naemlich zu der Anweisung hinter dem call.



  • Ja du hast recht,

    die addresse wird ja erst nach 1234h und 4321h in den Stack gepusht.
    Mir fehlt noch ein bisschen di Übung aber ich krieg das schon hin.

    Muss ich dann immer in einer Function zuerst die Ruecksprungaddresse sichern (zB in AX) , bevor ich mir die Parameter hole, und nachher wieder zurücktun,
    als letzte operation vor dem ret also nochmal push ax?

    Und zusammengenommen muss ich in einer Funktion soviel push'es wie pop's drin haben?

    [ Dieser Beitrag wurde am 16.11.2002 um 12:11 Uhr von mADC++er editiert. ]



  • Ich wuerde der Einfachheit halber vorschlagen, dass Du die Parameter nicht mittels pop vom Stack holst, sondern mit mov.
    Ein Beispiel:

    push 1234h
    push 5678h
    call MyProc
    
    ...
    
    Proc MyProc NEAR
    
    push bp
    mov bp,sp
    add bp,0004h ;das gepushte bp und die Ruecksprungaddresse ueberspringen
    ;bp zeigt jetzt auf den ersten Parameter.
    mov ax,[word ptr ss:bp] ;1. Parameter nach ax (ax=5678h)
    mov bx,[word ptr ss:bp+02h] ;2. Parameter nach bx (bx=1234h)
    pop bp ;bp wieder herstellen
    ret 04h ;zurueckspringen und dabei Parameter (4Byte) vom Stack loeschen...
    
    ENDP MyProc
    

    [ Dieser Beitrag wurde am 16.11.2002 um 12:57 Uhr von Nobuo T editiert. ]



  • Noch ein schöner Bericht über Buffer Overflows:
    http://ouah.sysdoor.net/bofstd.pdf

    [ Dieser Beitrag wurde am 16.11.2002 um 13:57 Uhr von TriPhoenix editiert. ]



  • Ich kann ja hier mal kurz erläutern wie Viren ihren Code anhängen:

    COM Datei: Einfach den Code ans Ende hängen. Ersten drei bytes der Datei ans Ende kopieren und dann mit einem Sprung auf das Angehängte überschreiben.

    MZ EXE Datei: Wieder den Code ans Ende hängen. Im Header die Größe
    der Datei in Paragraphen ändern und den EntryPoint ändern (natürlich wieder vorher die überschriebenen Werte sichern)

    PE EXE Datei: Entweder eine neue Section für den Code erstellen oder den Code an die letzte Section anhängen. Wahlweise auch vorhandenen Code überschreiben und vorher wie eben beschrieben sichern. Section characteristics sollten soweit geändert werden, dass 'writeable' und 'contains code' aktiviert ist. Imagegröße und Codegröße sollten im Optional Image Header ebenfalls geändert werden. Entrypoint muss sowieso geändert werden.

    Natürlich gibt es da auch noch andere Möglichkeiten, aber das ist zuviel zu erklären.



  • Und wieder ein Bericht über Buffer-Overflows 😃

    Ich denke den soltle ruhig jeder lesen, weils hier darum geht, wie man die wichtigsten Fehler vermeidet.
    http://www.core-sec.com/examples/core_vulnerabilities.pdf




Anmelden zum Antworten