переполнение memcpy - PullRequest
       26

переполнение memcpy

0 голосов
/ 06 января 2011

Можно ли переписать eip в следующих условиях, если у меня есть контроль над параметрами src и length?

memcpy (float * dest, float * src, int length)

Полагаю, можно было бы перезаписать eip (?), Но можно ли перезаписать его чем-то значимым?

** Извините за непонятность. Под перезаписью EIP я подразумеваю перезапись указателя возврата, который будет использоваться регистром EIP после возврата функции, передавая выполнение программы.

Ответы [ 3 ]

4 голосов
/ 06 января 2011

Поскольку eip является регистром, вы не можете перезаписать его. Вы можете только перезаписать значения в стеке. Атака переполнения буфера включает перезапись возвращаемого значения функции, тем самым передавая выполнение данным, которые можно интерпретировать как код, который вы поместили где-то в памяти.

В ответ на ваше уточнение:

Да. Поскольку при вызове функции указатель возврата помещается в стек, вы можете записать в эту область памяти. Он будет найден чуть выше любых распределений для переменных (при условии архитектуры x86 и соглашения о вызовах по умолчанию). Здесь вы можете записать значение, указывающее на следующую область памяти, куда вы должны загрузить двоичные данные, соответствующие обработанным инструкциям на языке ассемблера. Обратите внимание, что, выполняя действия, описанные мной, вы уничтожили стек и все шансы продолжения выполнения программы после введенного кода. Для этого вы должны сохранить адрес возврата где-нибудь еще в стеке и написать шелл-код, который копирует его в правильное место и затем выполняет возврат.

Я также предполагаю, что параметр dest является контролируемым. Если вы не можете разместить данные там, где хотите, они бесполезны для вас

0 голосов
/ 06 января 2011

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

Если перезаписать его чем-то значимым, это зависит от того, что вы подразумеваете под «значимым».Если вы имеете в виду «что-то, что не приведет к аварийному завершению программы (с точки зрения ОС) сразу», тогда да.Если вы предполагаете, что полностью перезаписываете его случайными данными, то статистически у вас есть столько страниц, отображенных в вашей программе таким образом, что они исполняемые, и так много возможных страниц памяти, и вы можете рассчитать вероятность того, что вы перейдете к исполняемому файлу.стр.Тогда вам будет сложнее вычислить вероятность того, что то, что там может быть выполнено очень долго без сбоев (на самом деле это форма классической остановка проблема ).

0 голосов
/ 06 января 2011

Что вы называете "перезаписать eip"?

EIP - это регистр, а не память.Он не будет перезаписан.

Возможно, что memcpy сможет перезаписать поток команд в памяти, на который указывает EIP.Но кодовые страницы, как правило, не слишком близки к страницам данных / стека / кучи, и часто также доступны только для чтения.

Что более распространено, так это то, что данные в куче или стеке перезаписываются, что в последующих инструкцияхадрес для загрузки в EIP - например, если указатель функции перезаписывается и используется в качестве обратного вызова, или если адрес возврата перезаписывается и переходит на.

(В вашем примере вы сказали, что src и length контролируются, но как насчет dest?)

...