Стек 1: https://exploit-exercises.com/protostar/stack1/

Exploit-Exercises Machines: https://exploit-exercises.com/download/

И снова здравствуйте. На этот раз мы рассмотрим вторую задачу стека Protostar, Stack 1. И снова эта задача будет сосредоточена на некоторых простых переполнениях буфера.

Итак, давайте проверим исходный код.

Итак, это выглядит точно так же, как стек 0, за исключением того, что вместо проверки того, был ли изменен modified, программа проверяет, установили ли мы его как шестнадцатеричное значение 0x61626364.

Итак, давайте снова поиграем с буфером, обратите внимание, что он использует функцию strcpy вместо функции gets, однако уязвимость такая же, поскольку ни одна из них не использует проверку границ.

user@protostar:/opt/protostar/bin$ ./stack1 $(python -c "print 'a'*64")
Try again, you got 0x00000000
user@protostar:/opt/protostar/bin$ ./stack1 $(python -c "print 'a'*65")
Try again, you got 0x00000061
user@protostar:/opt/protostar/bin$

Обратите внимание, что в $(‹some command›) это похоже на порядок операций для командной строки, который говорит сначала сделать это, а затем подставить значение на месте, это позволяет нам передать наш вывод Python в качестве аргумента.

Так что, как и в прошлый раз, 65-й байт первым передается в modified. Целые числа здесь занимают 4 байта, поэтому нам потребуется четыре символа (по 1 байту каждый), чтобы полностью изменить его.

Вы также можете видеть выше, что 65-й 'a' (первый в modified) появляется в конце гекса, это потому, что память находится в Little Endian и как бы читается в обратном порядке (ваш данные заполняются вниз по стеку, но вы читаете каждый байт вверх по стеку).

Таким образом, мы можем решить эту проблему, поставив 64 'a', а затем четыре байта, соответствующие 0x61626364, в обратном порядке. Но что это за ценности?

Возможно, вы заметили выше, что 0x61 — это «a». Вы можете посмотреть эти значения в диаграмме ASCII, однако неудивительно, что 62, 63 и 64 — это b, c, d соответственно. Таким образом, modified должен содержать «abcd», но в обратном порядке, потому что это Little Endian.

user@protostar:/opt/protostar/bin$ ./stack1 $(python -c "print 'a'*64 + 'dcba'")
you have correctly got the variable to the right value
user@protostar:/opt/protostar/bin$

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