부정행위 보고서를 쓰는 기교

만약 당신이 부정행위를 반대하는 작업 원리에 대해 호기심을 느꼈거나, 혹은 당신이 직접 그것을 쓰려고 했다면, 이 글에서, 나는 당신에게 유명한 부정행위자들의 공격을 받지 않도록 응용 프로그램을 어떻게 감지하고 보호하는지 알려줄 것이다.
주의해야 할 것은 본고에서 나는 서버가 아닌 클라이언트 부분을 강조할 것이다.미래에 문제가 발생하지 않고 완전히 안전한 응용 프로그램을 가지기 위해 당신이 할 수 있는 가장 좋은 일은 잘 작성된 프로그램을 가지는 것입니다. 이 프로그램은 제3자가 어떠한 방식으로도 고장을 이용하는 것을 허락하지 않습니다.

디버깅 거부
프로그램이 침입자의 공격을 받지 않도록 보호하는 가장 널리 알려지고 가장 자주 사용하는 방법 중 하나는 사용자의 디버깅을 방지하여 역방향 프로젝트를 하는 것이다.

Reverse engineering is the process of discovering the technological principles and functioning of a device, object or system, through the analysis of its structure, function and operation.


나의 부정행위 반대 업무에서, 나는 12가지 다른 반디버깅 방법을 수집했다.내가 발견한 모든 설비는 효율적이고 기능이 완비되어 있다.아래에서, 너는 이 방법들을 살펴보고, 그것들을 마음대로 사용할 수 있다.모든 방법의 코드는 본문을 오염시키지 않도록 단독Gist에 있다는 것을 기억하세요.



찾기 창


기존의 부정행위 반대 방법에서, 이것은 매우 흔히 볼 수 있는 방법으로, 검색이 창 이름에 따라 실행되는 프로세스를 포함한다."예를 들어,""해커""라는 단어가 있는 창이 있으면 부정행위로 인해 해당 프로세스가 맬웨어로 감지됩니다(이 방법은 매우 일반적인 가짜 양성 감지)<"p>

나는 두 가지 가능한 검색 창을 사용한다. 하나는 내가 선택한 키워드를 포함하는 창이 있는지 확인하는 것이다.또 하나는 지금까지의 모든 문장을 분석하고 악성 소프트웨어가 될 수 있는지 확인하는 것이다




창 이름으로 찾기


앞에서 말한 바와 같이 이 방법은 Windows APIFindWindow 함수를 사용하고 선택한 단어를 포함하는 창이 있는지 확인하는 데 불과하다.유효 핸들을 반환하면 창이 검색됨



if( FindWindow( "hacker", NULL ) != NULL )
     HackerDetected();



창문을 찾다


이 방법은 모든 열린 프로세스를 더욱 깊이 있게 검색하여 이 프로그램을 악성 소프트웨어로 식별하는 어떤 모드를 검색하려고 시도합니다


우리는 EnumWindowsEnumChildWindows 함수를 사용하여 기존 문장을 반복합니다



EnumWindows( (WNDENUMPROC)EnumWindowsProc, ( LPARAM )nullptr );
void EnumWindowsProc( HWND hWnd, LPARAM lParam ) {
    EnumChildWindows(...);
}

만약 우리가 모든 창의 핸들과 창의 모든 요소의 핸들 (Win32의 모든 UI 대상은 핸들) 을 가지고 있다면, 우리는 악성 프로그램인지 확인하기 위해 함께 관찰하고 분석할 수 있습니다.결과를 관찰합니다(예:


  • 창 내의 모든 곳에 특정 텍스트
  • 특정 윈도우 스타일(크기, 색상)이 있는 UI 요소
  • 키워드는 Win32 UI 요소
  • 에서 확인할 수 있습니다.

당신은 커닝 도구를 사용하여 사용자 인터페이스의 모델, 예를 들어 단추의 크기, 스타일, 텍스트 등을 식별할 수 있습니다. 따라서 우리의 커닝 도구는 이러한 모델을 만났을 때 악성 프로그램으로 식별했습니다




주입 모듈 피하기


분명히 DLL이 프로세스에 주입되기를 원하지 않기 때문에 실행할 때 코드, 메모리 등에 접근할 수 있습니다


이러한 문제를 피하기 위해 해결 방안은 매우 간단합니다. 우리는 응용 프로그램에 존재하는 모든 모듈을 검사합니다. 중간에 알 수 없는 모듈이 있으면 침입자로 검출하고 실행에서 쫓아냅니다







복제된 프로세스 인스턴스


사람들이 프로세스 메모리를 처리하는 데 사용하는 매우 흔한 방법은 ReadProcessMemory와 WriteProcessMemory를 사용하는 것이다.이 두 함수를 사용할 때 부정확한 메모리 작업에 필요한 모든 권한이 있는지 확인하기 위해서 OpenProcess를 먼저 실행해야 합니다


The OpenProcess function works by creating a new instance of our process, making it as if two distinct HANDLEs point to the same running process.


실행 중인 프로세스와 관련된 모든 실례를 검사하여 이러한 상황을 피합니다. 만약 이 실례가 알 수 없는 프로세스에서 온다면, 메모리 작업 (쓰기, 읽기) 을 허용하지 않습니다.




연결 기능


이런 보호는 매우 간단하지만, 역방향 공사에 대해 그렇게 많은 지식이 없는 사기꾼을 효과적으로 대처할 수 있다.이러한 보호는 본고에서 언급한 다른 보호에도 추가할 수 있기 때문에 효과가 더욱 좋다


보호는 함수 하나가 걸렸는지 간단하게 검사하고 우리가 보호하고자 하는 함수의 메모리가 JMP 형식의 어셈블리 문장을 사용했는지 확인하는 것을 포함합니다



bool __forceinline IsHookAPI( BYTE* pbFunction )
{
  //JMP
  if( pbFunction[0] == 0xE9 )
     return true;
  //JMP DWORD PTR DS:[...]
  if( pbFunction[0] == 0xFF && pbFunction[1] == 0x25 )
     return true;
   return false;
}

IsHookAPI 함수를 사용하려면 검사할 함수의 메모리 주소를 제시하여 호출해야 합니다.예:



if( IsHookAPI( (BYTE*)&GetTickCount ) )
  //Do something...

위의 예에서 GetTickCount 함수가 다른 곳에 연결되었는지 확인하고 있습니다. 만약 그렇다면, 부정행위자를 검출할 수 있도록 값을 되돌려줍니다.p>



체크섬


보호에 있어서 가장 자주 사용하는 방법 중 하나로 여러 곳에서 사용할 수 있습니다.우리는 기본적으로 파일이나 메모리의 완전성을 검사하고 원본 파일과 일치하기를 바란다.만약 완전성 검사가 예상과 일치하지 않는다면, 우리는 파일/메모리가 변경되었다고 단정하고 사용자를 부정행위자로 표시할 수 있습니다


A checksum is a small-sized datum derived from a block of digital data for the purpose of detecting errors that may have been introduced during its transmission or storage. By themselves, checksums are often used to verify data integrity but are not relied upon to verify data authenticity. Source: Wikipedia


프로그램의 중요한 파일, 실행 가능한 파일 자체, 심지어 부분에서 이 방법을 사용할 수 있습니다.실행 가능한 파일의 텍스트


The .text section of the executable is where the program code is located. In it we have the permission to read and execute. Therefore, if any user makes any changes in this section, we know that the code has been tampered with.




계산 체크섬


내가 선택한 것은CRC32이지만, 몇 가지 방법으로 어떤 물건의 검사와 검사를 계산할 수 있다.이러한 인증은 네트워크 프로토콜 및 스토리지 디바이스의 버그 감지에 널리 사용됩니다


우리의 경우 이런 알고리즘은 가장 좋은 선택이 아닐 수도 있지만, 내가 선택한 것은 상대적으로 간단하고 실현하기 쉽기 때문이다



int VerifyChecksum::GetChecksum( void* pBuffer, DWORD dwSize )
{
   //Calculate the checksum of .text section
   boost::crc_32_type result;
   result.process_bytes( pBuffer, dwSize );
   return result.checksum();
}

당신이 그것을 실현하고 싶지 않으면boost 라이브러리를 사용할 수 있습니다. 우리는 이미 함수를 설계했습니다




보호 함수 호출


본고에서 언급한 바와 같이 프로그램 클라이언트를 보호하지 않는 가장 좋은 방법은 서버에서 가능한 한 많은 프로그램을 보호하는 것이다.그러나 클라이언트에 남겨야 하는 것들이 있습니다. 사용자가 어떤 방식으로든 사용하기를 원하지 않습니다.





이 함수에서 우리가 보호한 함수의 되돌아오는 주소가 프로그램의 범위 내에 있는지, 알고 있는 라인에서 실행되는지 확인하는 것입니다.만약 이 검사 중의 어떤 반환 음수가 있다면, 우리는 이 함수가 외부 프로그램에 의해 호출되고 있다는 것을 알 수 있다. 예를 들어.dll 주입으로 부정확한 호출로 검출됨




이런 간단한 기교를 통해 당신은 미래의 번거로움을 피할 수 있고 당신의 프로젝트가 부정행위자의 영향을 받지 않도록 보호할 수 있습니다.비록 일부 방법은 매우 간단하지만 부정행위자는 반드시 상당한 정도의 역방향 공정 능력을 갖추고 모든 기존의 보호 조치를 통과할 수 있어야 한다(이 조치들은 전체 절차에 분산될 것이다)


다시 한 번 강조하지만, 프로그램을 보호하는 가장 좋은 방법은 미묘한 작업을 서버에 남겨서 사용자가 가지고 있지 말아야 할 자원에 접근하지 못하게 하는 것입니다


그래서 서버를 정확하게 구축합니다!🤗

좋은 웹페이지 즐겨찾기