Возвратно-ориентированное программирование: почему литеральный номер используется в цепочке ROP?
После статьи о введении ROP в Windows я обнаружил, что автор поместил несколько буквенных чисел в цепочку ROP.
Фрагмент кода, генерирующий шелл-код:
rop += struct.pack('<L',0x10013b1c) # POP EBX # RETN
rop += struct.pack('<L',0xffffffff) # will be 0x1
rop += struct.pack('<L',0x100319d3) # INC EBX # FPATAN # RETN
rop += struct.pack('<L',0x100319d3) # INC EBX # FPATAN # RETN
#------------------------------------[dwSize (0x1) -> EBX]-#
rop += struct.pack('<L',0x10030361) # POP EAX # RETN
rop += struct.pack('<L',0x90909090) # NOP
#---------------------------------------------[NOP -> EAX]-#
Насколько я понимаю, цепочка ROP должна состоять из адресов памяти, указывающих на гаджет, поэтому CPU будет последовательно выполнять инструкции по соответствующему адресу памяти. Тем не менее, автор положил 0xffffffff
а также 0x90909090
в цепочке гаджетов.
Может кто-нибудь объяснить использование этих буквенных чисел в цепочке ROP? Спасибо.
1 ответ
- В этой цепочке ROP автору нужно
ebx
быть0x1
, Однако запись в стеке в этом двоичном файле составляет 4 байта, поскольку это 32-разрядный двоичный файл. Для выполнения этой записи число должно быть0x00000001
, но запись нулевых байтов, как известно, плохо в эксплуатации, так как функции, такие какstrcpy
остановит обработку ввода, когда он достигнет нулевых байтов. Таким образом, автор поп значение0xffffffff
для ebx (используя первые 2 строки), а затем увеличьте значение наebx
от1
, Это оборачивает максимальное значение в 32-битной системе, и значение становится0x00000001
, - Для второго буквального числа
0x90909090
это NOP-сани.0x90
этоNO-oPeration
и это ничего не делает. Это, возможно, пустая сана для выполнения буфера, который автор пытается переполнить. - Вы также можете видеть другие литеральные числа в обход ASLR, который включает перезапись таблицы глобальных смещений динамически связанного двоичного файла. В этом методе эксплуатации определенные функции в libc будут находиться в определенном смещении от базового адреса libc. Вам нужно будет найти этот базовый адрес libc и по смещению, полученному из libc, вы можете вычислить адрес этих функций и использовать их в своем эксплойте. Узнайте больше здесь.