> For the complete documentation index, see [llms.txt](https://yutewiyof.gitbook.io/intro-rev-ida-pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yutewiyof.gitbook.io/intro-rev-ida-pro/chast-58.md).

# Часть 58

[\[Используемые материалы\]](https://github.com/yutewiyof/intro-rev-ida-pro/tree/e1367e11cc661f3d69c02ae5f733b7dd168bc5ab/.gitbook/assets/files/58.zip)

Хорошо. Нам осталось добавить сам шеллкод. Это типичный шеллкод, который крадет токен процесса **SYSTEM** и копирует его в наш процесс. Он очень короткий. Но стоит его хорошо проанализировать.

```python
shellcode="\x53\x56\x57\x60\x33\xC0\x64\x8B\x80\x24\x01\x00\x00\x8B\x40\x50\x8B\xC8\xBA\x04\x00\x00\x00\x8B\x80\xB8\x00\x00\x00\x2D\xB8\x00\x00\x00\x39\x90\xB4\x00\x00\x00\x75\xED\x8B\x90\xF8\x00\x00\x00\x89\x91\xF8\x00\x00\x00\x61\x33\xC0\x83\xC4\x0C\x5D\xC2\x08\x00"
```

Шеллкод - довольно общий. То, что нужно знать про шеллкод, состоит в том, что когда он завершается, он возвращается к процедуре откуда он был вызван. Для этого нужно внимательно посмотреть. Последняя инструкция **RETN** должна быть **RETN 4** или больше, чтобы вернуться туда куда нужно. Если бы мы не перезаписали **RET** случилось бы переполнение и программа продолжила работу. Иначе будет **BSOD** и чао-какао.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8mX5zOi49ITHSKV%2F58-01.png?generation=1563225021854731\&alt=media)

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

Если бы я запустил скрипт, прежде чем объяснять вам всё это, мы бы увидели, что я поместил вызов **RAW\_INPUT** в конец скрипта, чтобы остановить его до того, как он закроется, и посмотрим, смогу ли я повысить системные привилегии. Вы также можете запустить другой процесс и увидеть, есть ли у этого процесса системные привилегии, что может произойти только в том случае, если один системный процесс запускается другим.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8mkh_uk4YKWwPp4%2F58-02.png?generation=1563225023854357\&alt=media)

Здесь я запустил скрипт. Я вижу, что скрипт остановился на вызове **RAW\_INPUT**. Давайте посмотрим в **PROCESS EXPLORER**. Добавим столбец, который показывает текущего пользователя, который говорит нам следующее

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8n3yVIEgSsM64Ow%2F58-03.png?generation=1563225029265649\&alt=media)

Мы работали над преобразованием процесса с привилегиями обычного пользователя в **SYSTEM**. Давайте посмотрим, как мы это сделали. Присоединим **IDA** и остановимся на инструкции **RET** перед выполнением шеллкода.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3sibmGAzgN0rN_u%2F04.png?generation=1563265884743487\&alt=media)

Здесь код остановился у инструкции **RET**. Мы трассируем один раз с помощью **F7**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8nLZYZhSXkg0vhT%2F58-05.png?generation=1563225028478014\&alt=media)

Здесь находится шеллкод. Он очень маленький и мы видим, что он заканчивается на инструкции **RETN 8**. Это значение должно быть хорошо отрегулировано, потому что под адресом возврата, который мы перезаписываем в стеке, чтобы выполнять наш шеллкод, находится адрес возврата в родительскую функцию, и это то, что мы действительно должны достичь с помощью этого **RET**, чтобы вернуться в программу так как родительская функция сделала бы это.

С помощью **P** мы можем создать функцию **CREATE FUNCTION** и преобразить её в графическую форму с помощью пробела.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3t9gzWBA3-Vt1nU%2F06.png?generation=1563265884595173\&alt=media)

После инструкции **PUSHA**, которая сохраняет регистры в стеке, мы видим, что, поскольку **EAX** равно **0** из-за инструкции **XOR** и программа заканчивает чтение значения регистра **FS:\[124]**

Хорошо. Каждый процесс имеет **TEB** или **TIB**.

<https://es.wikipedia.org/wiki/Win32_Thread_Information_Block>

В вычислительной технике, **WIN32 THREAD INFORMATION BLOCK (TIB)** эта структура данных в системах **WIN32**, особенно в архитектуре **X86**, которая хранит информацию о потоке, который выполняется. Также она известна как **THREAD ENVIRONMENT BLOCK (TEB)**.

Хорошо. Эта структура имеет поля, к которым обращается через регистр **FS:\[x]**. Здесь в таблице мы видим, например, **FS:\[124]**

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8nZiPeWCYQ4WwI0%2F58-07.png?generation=1563225025210033\&alt=media)

Также, широко используется указатель на **PEB**, что расшифровывается как **PROCESS ENVIRONMENT BLOCK**, который находится в **FS:\[30]**

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8ndnAE_mqJDtmX3%2F58-08.png?generation=1563225032329539\&alt=media)

В **WINDBG** вы можете увидеть эту структуру.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8nlGUTVMDKpO_uS%2F58-09.png?generation=1563225021767036\&alt=media)

Хотя смещение **0x124** не показывается нам даже если мы придадим структуре большую глубину. Как мы видели, это структура **ETHREAD**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8nw33Azeumi6VSz%2F58-10.png?generation=1563225031762421\&alt=media)

Как и в позиции **0,** это структура **KTHREAD** или **KERNEL THREAD**. Это означает, что поле **50**, которое программа ищет дальше внутри структуры **ETHREAD**, будет находиться внутри **KTHREAD**, потому что последняя имеет размер **0x200**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3u0LtMrrnad0EmP%2F11.png?generation=1563265884767748\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3uFcXDQ1iyFPSL9%2F12.png?generation=1563265884740963\&alt=media)

Мы видим, что поле **0x50** не показывается нам. Оно находится внутри структуры **\_KAPC\_STATE** которая находится по смещению **0x40**.

Посмотрим её. По смещению **0x10** это **\_KPROCESS**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3u_LMQPXxxba5qE%2F13.png?generation=1563265884699887\&alt=media)

Если мы читаем это значение, и передаем его в регистр **EAX**, мы видим, что это знаменитый **EPROCESS** или **KPROCESS** - то же самое? Нет, но почти.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3uiqCRFJSb9WTQu%2F14.png?generation=1563265884526621\&alt=media)

Мы видим, что **KPROCESS** находится в поле **0 EPROCESS**, так что всё нормально, адрес совпадает. Если начиная с этого значения, сумма смещения меньше чем **0x98**, это будет **KPROCESS** и находится внутри этого. Если сумма больше **0x98**, это будет в оставшейся части структуры **EPROCESS**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3upe7n2hsNum2VM%2F15.png?generation=1563265884306298\&alt=media)

Мы видим, что программа читает поле **0xB8**, поэтому мы уже вышли из структуры **KPROCESS** и находимся внутри **EPROCESS**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3uzqTFeQdEhUHXe%2F16.png?generation=1563265884944561\&alt=media)

Программа читает знаменитую **ACTIVEPROCESSLINKS**.

Как и в предыдущем упражнении, я собрал структуру **EPROCESS**, которая была неполной, но она работает.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8onGVVRvA-UQVFj%2F58-17.png?generation=1563225028010318\&alt=media)

Через меню **FILE → LOAD FILE → PARSE C HEADER FILE** я ищу структуру и добавляю её.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3vGlI9qAub0OvWD%2F18.png?generation=1563265884840205\&alt=media)

Я помечаю её через **LOCAL TYPES** и экспортирую её в файл **C HEADER**

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3vQkX25Coyy1z2T%2F19.png?generation=1563265884392374\&alt=media)

Теперь происходит синхронизация.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8p31qpXezZ9G-68%2F58-20.png?generation=1563225032517979\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3voHsq8LkuTZk_c%2F21.png?generation=1563265885946288\&alt=media)

Я нажимаю **T** и ищу структуру. И это наш **FLINK**. Другими словами, он указывает на **ACTIVEPROCESSLINK** следующего процесса, так как он находится по смещению **0xB8**. Программа вычитает эту константу, чтобы найти **EPROCESS** следующего процесса.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3w0QBqQGcGScSv9%2F22.png?generation=1563265884776302\&alt=media)

В регистре **EAX** должен быть указатель на **EPROCESS** следующего процесса.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8pK4j728PlUXzxO%2F58-23.png?generation=1563225030996695\&alt=media)

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

Мы видим, что программа сравнивает значение поля **0xB4** этого **EPROCESS** со значением **4**. Давайте посмотрим, что это смещение **0xB4**. Поэтому мы добавляем его в нашу структуру.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3wJw9l4yWsv5of9%2F24.png?generation=1563265884678785\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8pYsCyqGsKZ4xRX%2F58-25.png?generation=1563225027665214\&alt=media)

То есть, программа замечает, что если **PID** равен **4**, это соответствует процессу **SYSTEM**.

Я добавлю поле в мою структуру. Программа не позволяет редактировать структуру, потому что я импортирую её, поэтому я добавил поле в **.H** файл, который я экспортировал.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3w_t_WA5XM1VjKn%2F26.png?generation=1563265884585241\&alt=media)

Я повторно импортирую файл, не удаляя предыдущий, и добавляется недостающее поле.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3wgQgbWMZUF2Z_7%2F27.png?generation=1563265884509395\&alt=media)

Я нахожусь здесь.

Мы видим, что значение не равно **4**, поэтому мы продолжаем трассировать. Конечно, всё начнется снова с первого процесса. Давайте посмотрим.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8pq2q-HW3esWeA-%2F58-28.png?generation=1563225022100815\&alt=media)

Здесь программа начинается с начала. В этом случае **PID** или **CID** равен **4** и соответствует процессу **SYSTEM**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8pxUzyrpmm06M80%2F58-29.png?generation=1563225022742472\&alt=media)

Теперь если программа найдет **EPROCESS** процесса **SYSTEM**, она выйдет из цикла.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3x3Dgc2hjUQZZ_c%2F30.png?generation=1563265885149845\&alt=media)

Мы видим, что программа читает поле **0xF8 EPROCESS** процесса **SYSTEM**. Давайте посмотрим, что там есть.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8qHkKPkLexGIoZP%2F58-31.png?generation=1563225027733440\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8qO9myckAt7JStO%2F58-32.png?generation=1563225030126793\&alt=media)

Хорошо. Программа копирует токен системы в наш **EPROCESS**. Он будет иметь привилегии **SYSTEM**, и вот что программа там делает. Читает токен **SYSTEM**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3xd7HBjdTYcCZ4D%2F33.png?generation=1563265884688055\&alt=media)

И поскольку регистр **ECX** имел наш **EPROCESS**, к нему добавляется значение **0xF8**, чтобы сохранить токен **SYSTEM** в нашем процессе.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3xoD27lQ7aIpn7J%2F34.png?generation=1563265884665784\&alt=media)

Я могу добавить недостающее поле в **.H** файл и импортировать его снова. Нет необходимости удалять предыдущий.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3y0_7UsDsVujm7V%2F35.png?generation=1563265884970022\&alt=media)

Помните, что значения являются токенами разных процессов. Регистр **EAX** указывает на **EPROCESS SYSTEM,** а **ECX** на наш **EPROCESS** из **PYTHON.EXE**.

С этим уже все работает как нужно. Давайте посмотрим, сможем ли мы с этим **RET** нормально вернутся обратно в программу и продолжить работу с драйвером.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT8qsMvM1AJNbNgWo%2F58-36.png?generation=1563225032596248\&alt=media)

Программа вернулась в ту же самую точку, куда она должна была вернуться, если бы вместо того, чтобы выполнить наш шеллкод, она возвратилась к уязвимой функции. Со стеком в той же самой позиции. Нужно убедиться в этом, иначе снова будет **BSOD**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3yHjxkrcT-Y06C5%2F37.png?generation=1563265884392221\&alt=media)

Я нажимаю **RUN** и остаюсь в ожидании функции **RAW\_INPUT**.

У меня сейчас нет **PROCESS EXPLORER**. Я закрыл его, чтобы он обновился.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3yT0ermF6pQBKYr%2F38.png?generation=1563265884680847\&alt=media)

И у нас есть готовые права **SYSTEM**.

Я могу запустить калькулятор с правами **SYSTEM**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3yZg_R29_K_G0JH%2F39.png?generation=1563265884657439\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu3yj2tHFeK0RSylJ%2F40.png?generation=1563265884634008\&alt=media)

Готово. Мы достигли цели.

Автор оригинального текста — Рикардо Нарваха.

Перевод и адаптация на русский язык — Яша Яшечкин.

Перевод специально для форума системного и низкоуровневого программирования - WASM.IN

01.12.2018

[**Источник: ricardonarvaja.info**](http://ricardonarvaja.info/WEB/IDA%20DESDE%20CERO/CURSO%20DE%20IDA%20TUTES/58-INTRODUCCION%20AL%20REVERSING%20CON%20IDA%20PRO%20DESDE%20CERO.docx)
