virtualprotect 예제

virtualprotect 예제

2 agosto, 2019

첫 번째 인수는 실행할 명령에 대한 포인터이고 두 번째 매개 변수는 창 동작을 나타냅니다. 몇 가지 예 : DEP가 보호하는 것을 정확하게 보여 줄 수있는 몇 가지 코드 예제를 살펴보겠습니다. 이것은 Java가 DEP를 사용할 수 없다고 생각하는 사람들에게 는 놀라운 일이 될 수 있습니다. 다음은 샘플 코드입니다: 당신이 볼 수 있듯이, 우리는 기본적으로 체인의 시작 부분에 있는 명령(rop 가젯)의 수를 제한합니다. 스택 포인터를 저장한 다음 Virtualprotect 함수/매개 변수를 뛰어넘으면 나중에 매개 변수 자리 표시자를 더 쉽게 덮어쓸 수 있습니다. (걱정하지 마세요 – 당신은 내가 몇 분 안에 무슨 뜻인지 이해할 수 있습니다) 실제 세계에서이 같은 코드를하지 마십시오. 최소한의 코드를 사용하여 예제를 보여주고 있습니다. 이제 JIT 코드는 mem PAGE_EXECUTE_READWRITE의 모든 것을 할당하지 않습니다. 쓰기 및 실행 가능한 메모리가 없어야 합니다. 그것은 문제를 요구하는 것입니다. 대신 읽기 / 쓰기 파마로 mem을 할당하고, 데이터를 복사하고, 실행 권한을 변경한 다음 (읽기가 실제로 필요하지 않음) 실행해야합니다: F7을 눌러 단계별로 실행하십시오. NTDLL에 호출 후. ZwWriteVirtualMemory는 (7C8022C9에서) 만들어집니다, RETN 14 명령이 그 호출의 끝에서 실행되기 전에, 우리는 우리의 쉘 코드가 7C8022CF로 복사 된 것을 볼 수 있습니다 : .

이제 가장 좋은 부분이 온다:- API 후킹 (APIHook.cpp). EIP가 Mysend 함수로 라우팅되면 (연결된 코드에서 수행됨)- 세 번째 매개 변수를 만들기 위해 크기를 0x300 바이트로 설정하기로 결정했습니다. 우리가이 작업을 수행 할 필요가 가제트는 XOR EAX, EAX 및 추가 EAX,100 “jmp edi”명령 (점프를 만들 것입니다)을 제거해야합니다. 우리는 정보를 보내고받는 데 사용되는 소켓 API의 도입으로 시작됩니다, 이들은 보내고 recv입니다. 연결된 코드는 이러한 API를 후크/하이재킹하고 이를 통해 전달된 모든 정보를 기록하려고 시도합니다. 컴퓨터를 다시 부팅하고 포인터가 여전히 동일한 위치에서 찾을 수 있는지, 스택에서 선택한 포인터에서 VirtualProtect()까지의 오프셋이 여전히 동일한지 확인합니다. 어쨌든, 다시 우리의 “사용자 정의 코드”문제로. 따라서 스택에서 코드를 실행하지 않으면 ROP를 사용해야 합니다.

rop.txt에서 빠른 검색을 수행 한 후, 나는 이것을 발견 : (참고 : 첫 번째 덮어 쓰기 작업의 경우 ESI는 자동으로 올바른 위치를 가리키므로 값을 늘리거나 줄일 필요가 없습니다. ESI+10은 첫 번째 매개 변수 자리 표시자의 위치를 가리킵니다) 두 경우 모두 디버거를 사용하여 지침을 검색하고 RET를 검색할 수 있습니다.