시작
환경:<span>Windows</span> <span>XP</span><br><span>VC</span>++ 6<span>.0</span><br>
이 방법은 다음에만 적합합니다. 테스트 또는 쉘코드가 동적으로 실행될 수 없다는 것을 배우십시오. 즉, 쉘코드는 XP에서만 사용할 수 있습니다. 왜냐하면 aslr
ASLR 명령은 win7부터 사용할 수 있기 때문입니다: https://blog.morphisec.com/aslr-what-it-is-and-what-it-isnt/pop- 업
테스트 :
<span>#<span>include</span><span><windows.h></span></span><br><span><span>int</span> <span>main</span><span>(<span>int</span> argc,<span>char</span>** argv)</span></span>{<br> MessageBox(<span >NULL</span>,<span>"편두통으로 인해 해킹당했습니다!"</span>,<span>"Pwned"</span>,MB_OK);<br>}<br>
Alt+8은 win API 호출 방법을 관찰하기 위해 디스어셈블리 모드를 불러옵니다.
기사를 참고해 보니 기계어 코드는 직접 추출할 수 없고 어셈블리어로 작성해야 한다는 사실을 알게 되었습니다. 그런 다음 바이트 코드를 추출하십시오. <span>//보안 게스트 기사에서 다시 게시됨</span><br><span>#<span>include</span><span><windows
기사를 참조하여 쉘코드의 어셈블리 및 실행이 수행되는 방법을 이해하십시오.
.h></span></span><br><span><span>void</span> <span>메인</span><span>()</span><br></span>{ <br> LoadLibrary(<span>"user32.dll"</span>);<span>//DLL 로드</span><br> __asm<br> { <br> push <span>0x00656e</span>;ne< br> 푸시 <span>0x69617267</span>;grai<br> 푸시 <span>0x694d2079</span>;y Mi<br> push <span>0x62206565</span>;ed b<br> push <span>0x6b636168</span>;hack<br> push <span>0x20657261</ 스팬>;<br> 푸시 <span>0x20756F59</span>;당신은<br> mov ebx,esp<br> push <span>0x0</span><br> push <span>0x656e6961</span>;aine<br> push <span> 0x7267694d</span>;Migr<br> mov ecx,esp<br><br><br> <span>//int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType );</span><br> xor eax,eax<br> push eax<span>//uTyoe->0</span ><br> 푸시 ecx<span>//lpCaption->편두통</span><br> 푸시 ebx<span>//lpText->편두통으로 해킹당했습니다</span><br> push eax<span>//hWnd->0</span><br> mov esi,<span>0x77D3ADD7</ span><span>//User32.dll->MessageBoxA</span><br> 호출 esi<br><br><br> }<br>}<br>
- 사용할 문자열을 16진수로 변환합니다. X86이므로 한번에 최대 8바이트까지 저장할 수 있습니다.
- 문자열의 변환된 16진수 값을 스택에 푸시합니다.
- 0x0을 푸시한 후 필요한 항목을 스택에 반복적으로 푸시한 다음 다른 레지스터에 저장합니다.
- 그런 다음 win API 값을 오른쪽에서 왼쪽으로 설정합니다(참고: 오른쪽에서 왼쪽으로).
- 마지막으로 esi에 Windows API 주소를 제공합니다.
- call은 현재 실행 중인 명령어의 주소를 스택에 푸시한 다음 무조건 레이블이 가리키는 명령어로 분기합니다.
OD를 통해 해당 API에 중단점을 설정하여 주소를 얻습니다.
(참고: 각 시스템의 주소는 다릅니다)
예:
그런 다음 C 임베디드 asm을 사용하여 기계어 코드를 디버그하고 추출합니다.
전체 asm 범위의 기계 코드가 추출됩니다.
<스팬>"\x68\x6E\x65\x00\x00\x68\x67\x72\x61\x69\x68\x79\x20\x4D\x69\x68\x65\x65\x20\x62"</span>< br> <스팬>"\x68\x68\x61\x63\x6B\x68\x61\x72\x65\x20\x68\x61\x62\x63\x00\x8B\xDC\x6A\x00\x68"</span>< br> <스팬>"\x61\x69\x6E\x65\x68\x4D\x69\x67\x72\x8B\xCC\x33\xC0\x50\x68\x61\x69\x6E\x65\x68"</span>< br> <span>"\x4D\x69\x67\x72\x8B\xCC\x33\xC0\x50\x51\x53\x50\xBE\xEA\x07\xD5\x77\xFF\xD6"</span><br>
그냥 실행하세요:
WinExec를 사용하여 <span>//WinExec address-7C86250D</span><br><span>//ExitProcess address-7C81CB12</span><br><span>#<span>include</span>< 계산을 재생합니다 . 스팬><windows.h></span></span><br><span><span>int</span> <span>main</span><span>()</span><br></span>{<br> LoadLibrary(<span>"kernel32.dll"</span>);<br> __asm<br > {<br> 푸시 <span>0x636C6163</span>;calc<br> mov eax,esp<br> 푸시 <span>0x0</span><br> 푸시 <span>0x5</span><br> mov ebx,esp<br><br><br> push ebx<br> push eax<br> mov esi,<span>0x7C86250D</span><br> call esi <br> xor ecx,ecx<br> mov esi,<span>0x7C81CB12</span><br> 호출 esi<br> }<br> <span>반환</span> <span>0</span>;<br>}<br>
쉘코드는
<span>"\x68\x63\x61\x6C\x63\x8B\xC4\x6A\x05\x8B\xDC\x53\x50\xBE\x0D\x25\ 입니다. x86\x7C"</span><br><span>"\xFF\xD6\x33\xC9\xBE\x12\xCB\x81\x7C\xFF\xD6"</span><br>
참고: calc를 16진수로 변환하는 방법을 모른다면 그냥 조합하세요.