Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
Code Kitchen Allgemeines Coder-Forum rund um das Programmieren eigenständiger, ausführbarer Programme.

[solved] C: Maschinen-Code ausführen / Speicherzugriffskontrolle

Diskussion: [solved] C: Maschinen-Code ausführen / Speicherzugriffskontrolle im Forum Code Kitchen, in der Kategorie Software Home; Anzeige Hallo, ich beschäftige mich gerade mal wieder mit dem, was unter der Haube der modernen Rechentechnik steckt. Inspiriert, von ...

Antwort
Alt 21.12.11, 22:57   #1 (permalink)
 
Registriert seit: 29.06.10
Thulsadum Leistung: Facit NTK
Likes: 0
erledigt [solved] C: Maschinen-Code ausführen / Speicherzugriffskontrolle

Anzeige

Hallo,

ich beschäftige mich gerade mal wieder mit dem, was unter der Haube der modernen Rechentechnik steckt. Inspiriert, von dem etwas in die Jahre gekommen Artikel Erstellen eines Shellcode - HackerWiki, wollte ich Maschinencode ausführen.

So einfach wie wie im o.g. Artikel geht es leider nicht (mehr), dass man Maschinencode von einem Characterarray in ein Funktionspointer castet und abfeuert.

Ich habe schon herausgefunden, dass man einen seitenalignierten (page aligned klingt doch besser) Speicherbereich benötigt, in welchem man die Daten kopiert und ihn via mprotect ausführbar macht. Dieses minimale Szenario segfaultet bei mir und leider habe ich in diesem Bereich noch nicht so viel Ahnung, dass ich mir selbst zu helfen weiß. Deshalb kommt jetzt hier mein Setup und ich hoffe auf interessante Tipps.

Software   
% nasm -v
NASM version 2.09.10 compiled on Jul 19 2011

% gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/src/gcc-4.6-20111125/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --enable-gnu-unique-object --enable-linker-build-id --with-ppl --enable-cloog-backend=isl --enable-lto --enable-gold --enable-ld=default --enable-plugin --with-plugin-ld=ld.gold --enable-multilib --disable-libssp --disable-libstdcxx-pch --enable-checking=release --with-fpmath=sse
Thread model: posix
gcc version 4.6.2 20111125 (prerelease) (GCC)

% uname -vr
3.1.5-1-ARCH #1 SMP PREEMPT Sat Dec 10 14:43:09 CET 2011


Für die Vollständigkeit die Bedeutung meines Maschinencodes:
Code:
; hello.asm
    mov ecx,msg
    mov edx,msglen
    mov ebx,1 ; STDOUT
    mov eax,4 ; Funktionsnummer: Ausgabe
    int 80h
    mov ebx,0 ; EXITCODE
    mov eax,1 ; Funknr: Exit
    int 80h


msg: db "Hello ya encrypted world!"
msglen: equ $ - msg
Übersetzt mit nasm -f bin -o hello.bin hello.asm.

Mein C-Code:
Code:
// loader.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>


int main(){
// der als hex codierte Inhalt der eben erstellten .bin Datei
        const char *hello = "\x66\xb9\x28\x00\x00\x00\x66\xba\x19\x00\x00\x00\x66\xbb\x01\x00"
                "\x00\x00\x66\xb8\x04\x00\x00\x00\xcd\x80\x66\xbb\x00\x00\x00\x00"
                "\x66\xb8\x01\x00\x00\x00\xcd\x80\x48\x65\x6c\x6c\x6f\x20\x79\x61"
                "\x20\x65\x6e\x63\x72\x79\x70\x74\x65\x64\x20\x77\x6f\x72\x6c\x64"
                "\x21";
        const int len = 65;

        size_t size = sizeof(char) * len;

        printf("pos-hello: %08x\n", (long) hello);

        void* mem = memalign(sysconf(_SC_PAGESIZE), size);
        if(mem == NULL) {
                perror(0);
                return 1;
        }

        printf("pos-mem: %08x\n", (long) mem);

        memcpy(mem, hello, size);
        
        if(mprotect(mem, size, PROT_READ|PROT_WRITE|PROT_EXEC) == -1){
                perror(0); 
                return 1;
        }

        int (*F)() = mem;
        printf("pos-F: %08x\n", (long) F);
        F();
}
Übersetzt mit gcc -o loader loader.c.

Ausgabe des Programmes (und meiner Shell):
Ausgabe   

% ./loader
pos-hello: 00400880
pos-mem: 00fb7000
pos-F: 00fb7000
[1] 27673 segmentation fault ./loader


Also meiner Meinung nach sollte es funktionieren, vielleicht habe ich auch einen trivialen Fehler gemacht und seh ihn nur nicht. Aber viele Augen sehen ja bekanntlich mehr als zwei.

Gruß, Thul

Geändert von Thulsadum (03.01.12 um 23:24 Uhr) Grund: solved
Thulsadum ist offline   Mit Zitat antworten
Alt 21.12.11, 23:38   #2 (permalink)
ss5
 
Registriert seit: 24.12.08
ss5 Leistung: Facit NTK
Likes: 2
Standard

Hi,

Nach einem kurzen Blick darauf fallen mir zwei Sachen auf:
1.) Die vielen 0x66 Prefixes in deinem Shellcode deuten darauf hin, dass du BITS 32 in der hello.asm vergessen hast der Assembler 16-Bit Code generiert.
2.) Shellcode sollte immer positionsunabhängig sein. Dein mov ecx,msg führt dazu, dass ecx dann bei der Ausführung im C-Programm nicht mehr auf die richtige Adresse zeigt. Du kannst das für den Anfang z.b. so lösen

Code:
call over_txt
msg db "Hello SC-World!",0
over_txt:
pop ecx
Bei einem call wird die Rücksprungadresse, in diesem Fall die Adresse von MSG, auf dem Stack abgelegt und dann mit pop ecx wieder ins gewünschte ECX Register geladen.

Ich hoffe, du kommst dem Ziel damit ein Stück näher.

Mfg
ss5 ist offline   Mit Zitat antworten
   
HaBOT
 
- Anzeige -

Werbung ist gerade online    
Alt 21.12.11, 23:51   #3 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 202
Standard

\x66\xb9\x28\x00\x00\x00
66:16/32 Bit Prefix
b9 28: mov ecx, 0x28 <-- String befindet sich also an Adresse 0x28 ?
int 80h <-- 32-bit Interface. Bei 64-bit sollte SYSCALL verwendet werden
Sprich: der Code sollte bei einem 64-bit System auch selbst 64-bittig sein

linuxsyscalls
bzw. in "kurz":
Low-Level Assembler unter Linux
Code:
Syscallnummern SYSCALL

 ; FILE syscall_64_syscall.inc

%define _syscall syscall
%define _nr rax
%define _arg1 rdi
%define _arg2 rsi
%define _arg3 rdx
%define _arg4 rcx
%define _arg5 r8
%define _arg6 r9

%define _sys_read 0
%define _sys_write 1
...
%define _sys_exit 60
Das ganze sollte in diese Richtung gehen (64-Bit Assemby nie ernsthaft betrieben):
Code:
jmp my_code
msg: db "Hello ya encrypted world!"
msglen equ $ - msg
my_code:
    mov rax,1 
    mov rdi,1 ;stdout
    lea rsi,[rel msg]
    mov rdx, msglen
    syscall

    mov rdi,0
    mov rax,60h ; Funknr: Exit
    syscall
    ret
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Alt 22.12.11, 00:09   #4 (permalink)
Themenstarter
 
Registriert seit: 29.06.10
Thulsadum Leistung: Facit NTK
Likes: 0
Standard

Danke Ihr beiden,

ss5s bemerkte Auffälligkeiten haben abhilfe geschaffen. Tatsächlich bräuchte ich die 64 Bit variante, aber die 32 Bit variante tut auch und irgendwie war es doch ein offensichtlicher Fehler den Code nicht frei von Positionierung zu halten.

Jedenfalls funktioniert es jetzt und ich freue mich. Werd mir dann mal die 64 Bit variante zu Gemüte führen.

Thul
Thulsadum ist offline   Mit Zitat antworten
Alt 22.12.11, 00:17   #5 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 202
Standard

64-bit erlaubt eben die RIP-Adressierung, wodurch der "delta-call" zur Positionsermittlung überflüssig wird:
Codegurus.be - About RIP relative addressing (Win64 / x64 / x86-64 / AMD64 / EM64T / AA-64)
Code:
lea rsi,[rel msg]
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Alt 22.12.11, 00:45   #6 (permalink)
Themenstarter
 
Registriert seit: 29.06.10
Thulsadum Leistung: Facit NTK
Likes: 0
Standard

Also dein Code funktioniert einwandfrei, wobei das return tatsächlich wichtig ist, da es sonst zu nem segfault kommt, sollte der syscall an exit nicht schon das Programm beenden?
Thulsadum ist offline   Mit Zitat antworten
Alt 22.12.11, 02:00   #7 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 202
Standard

der erste Link sollte eigentlich zu sowas führen:
64-bit Linux system call list
und
sys_exit = 60d = 0x3c (in meinem Code steht 60h, was falsch ist)
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » [solved] C: Maschinen-Code ausführen / Speicherzugriffskontrolle
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[JAVA] Wie in Abhängigkeit vom Datentyp in einem Object-Array code Ausführen? BlackPanter Code Kitchen 3 26.05.10 17:18
EXE Code während der Laufzeit ausführen _SharK_ Code Kitchen 5 18.12.06 20:50
Code direkt ausführen Nick H. Code Kitchen 11 03.12.05 17:56
Linux 2.6.13 mit Suspend auf SMP-Maschinen non News & Ankündigungen 0 30.08.05 12:53
PHP Code aus Datenbank ausführen the-hermi (Web-) Design und webbasierte Sprachen 2 20.06.04 22:23


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61