# Часть 58

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

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://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM33xHiOqt1-fHkzO%2F01.png?generation=1564666005625181\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM34EmMm6v06yQpig%2F02.png?generation=1564666016356247\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM34JSQx9xCYRzMOw%2F03.png?generation=1564666000781161\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM34PkRK9OeT4zFUM%2F04.png?generation=1564666004815422\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM34XWwSscHSU4vFI%2F05.png?generation=1564665998978208\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM34fYE4hIT_kzBo_%2F06.png?generation=1564665996664492\&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://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM34luo4IwzI01g_d%2F07.png?generation=1564665998332334\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM34raAPhfjZVru8F%2F08.png?generation=1564665998511466\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35-c6b68MWIv0tq%2F09.png?generation=1564665994820032\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM357ovz-1bU7jeFe%2F10.png?generation=1564665995203650\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35EOsjYoo3xATbL%2F11.png?generation=1564665994864633\&alt=media)

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35LjTFr1EVO-oIC%2F12.png?generation=1564665994749380\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35WyNnehfwOtYCg%2F13.png?generation=1564665994834836\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35ZfCSyubq6HxlR%2F14.png?generation=1564665998168441\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35bkN1xRbRBSBGY%2F15.png?generation=1564666006558422\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35gRGJnbmVlXgTm%2F16.png?generation=1564665995193318\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35ochpQ3Mo_16Cd%2F17.png?generation=1564665996540370\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM35xULeSkR3VUjI9%2F18.png?generation=1564666007639046\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM362bhKlmauyCrdv%2F19.png?generation=1564665995746774\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM36BJqSF9hIeSRFe%2F20.png?generation=1564665998971513\&alt=media)

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM36LsJVdHGJBT8GH%2F21.png?generation=1564665999010127\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM36T5BTXqhWqKyc2%2F22.png?generation=1564665995277840\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM36duU8ygVDKBaxg%2F23.png?generation=1564665995282631\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM36la1hqYxas9Ut0%2F24.png?generation=1564665995159170\&alt=media)

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM36qJgTWzgRVoAgz%2F25.png?generation=1564665995105807\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM36w3Got69Bco4oQ%2F26.png?generation=1564666006916388\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM36z92AV5sHHcrDu%2F27.png?generation=1564665995984814\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM374DHOtZpRXxih7%2F28.png?generation=1564665994815962\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37B-Lnn2m7p70xC%2F29.png?generation=1564665996831214\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37HMqXjSyuspi1A%2F30.png?generation=1564665999281969\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37P_uP9RASSnytX%2F31.png?generation=1564665998677047\&alt=media)

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37VFQWLzPxfGufH%2F32.png?generation=1564665997055700\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37b0yVPKL3wlFOj%2F33.png?generation=1564666004625941\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37hFzsmgw18Gq1A%2F34.png?generation=1564665996837074\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37opUkZ_DzvwjDe%2F35.png?generation=1564666013706754\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37s8DRgAPoYa8Ah%2F36.png?generation=1564666005682330\&alt=media)

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM37v2DRM8t5Mt8-3%2F37.png?generation=1564665998921505\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM380Jd12E2hB35p-%2F38.png?generation=1564665998088584\&alt=media)

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

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

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM383PK0NhK9uL7Xi%2F39.png?generation=1564665996905473\&alt=media)

![](https://2625274913-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LlCLaBFYUXycrwo1F8f%2F-LlCLnPRTA5yNwbyF2aC%2F-LlCM38CWaFKuOAE-qtC%2F40.png?generation=1564665995880459\&alt=media)

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

**======================================================= Автор текста: Рикардо Нарваха** - **Ricardo** **Narvaja** (**@ricnar456**) Перевод на русский с испанского: **Яша\_Добрый\_Хакер(Ростовский фанат Нарвахи).** Перевод специально для форума системного и низкоуровневого программирования — **WASM.IN 01.12.2018 Версия 1.0**
