2011-01-09 3 views
0

Windows XP 32 비트를 사용하여 "Hello World"를 콘솔에 작성하여 버퍼 오버 플로우를 테스트하고 싶습니다. 쉘 코드는 오버플로하려는 프로그램에 "scanf"를 전달하기 위해 널 (null)이 없어야합니다. Windows 용 어셈블리 튜토리얼을 많이 찾았습니다. 누군가 NASM을 사용하여 이걸 저를 따라 주시기 바랍니다. Thxxx!간단한 "Hello-World", Windows 용 null없는 쉘 코드가 필요합니다.

+0

음, 조립 옵 코드는 리눅스와 윈도우 모두 동일하며, 그 튜토리얼에 일이 너무 창에 적용해야합니다. – BlackBear

+0

어셈블리 opcode는 같지만 syscall은 다릅니다. 자세한 내용은 내 대답을 참조하십시오. :) – MarioVilas

답변

0

어셈블리 언어는 프로세서에 의해 정의되며 어셈블리 구문은 어셈블러에서 정의합니다 (따라서 &t 및 인텔 구문). 주된 차이점은 (적어도 필자는 ...) 실제 모드 (실제 인터럽트를 호출하여 프로그램을 수행하는 대신 컴퓨터에 액세스 할 수있는 모든 메모리를 사용할 수 있음) 및 Linux가 보호 모드입니다 (프로그램의 작은 큐브 메모리에서만 액세스 할 수 있습니다 , int 0x80을 호출하고 하드웨어와 바이오스를 호출하는 대신 커널을 호출해야한다) 어쨌든 hello world 타입의 것들은 리눅스와 윈도우간에 동일하거나 같을 것이다. 호환 프로세서.

작성한 프로그램에서 쉘 코드를 가져 오려면 대상 시스템의 디버거 (Linux의 경우 gdb, Windows의 경우 디버그)에로드 한 다음 디버그에 d를 입력하십시오. 또는 어쨌든 h (도움말)을 입력하면 명령어와 메모리 사이에 opcode가 표시됩니다. 텍스트 편집기에서 텍스트 문자열을 하나의 문자열로 복사하여 ASCII 값으로 변환하는 프로그램을 만들 수 있습니다. GDB Tho에서이 작업을 수행하는 방법을 잘 모르는 경우 ...

어쨌든 ba 익스플로잇으로 만들려면 aaaaa ...를 입력하고 버퍼 오버 플로우 오류가 발생하면 에서 충돌이 발생할 때까지 계속 추가하십시오. 그러나 충돌을 일으키는 데 얼마나 많은 시간이 걸리는지 정확히 찾아야합니다. 그렇다면 그것은 어떤 기억의 주소 였는지 말해 주어야합니다. 일반적으로 오류 메시지에서 알려야합니다. 그것이 '9797 [원래 돌아 오는 주소의 나머지]'라고 말하면, 당신은 그것을 얻습니다. 이제 UR 디버거를 사용하여 이것이 어디에서 있었는지 확인해야합니다. 디버거로 프로그램을 분해하고 scanf가 호출 된 곳을 찾으십시오. 거기에 중단 점을 설정하고 실행하여 스택을 검사하십시오. 그 97 개를 모두 찾으십시오. (나는 'a'에 대한 ascii 번호를 언급하는 것을 잊었습니다.) 그들이 끝나는 곳을 확인하십시오. 그런 다음 중단 점을 제거하고 필요한 양을 입력합니다 (정확하게 금액입니다.) 오류 메시지가 '97 [원래 반환 주소의 나머지 부분]에서 버퍼 오버플로가 발생했습니다. '그런 다음 마지막 a를 제거하고 검사 한 주소를 입력하십시오. 스택, 그리고

+0

이 회신에 몇 가지 문제가 있습니다. 1) Windows는 ** 실제 모드가 아닙니다. 2) Windows와 Linux hello world code는 Windows가 POSIX가 아니기 때문에 전혀 다릅니다. 3) 귀하의 기억을 신뢰하는 대신 Google에 답하는 것이 가장 좋습니다. 4) bof를 악용하는 방법에 대한 설명은 오히려 혼란스럽고, 불완전하며, 실제로 질문과 관련이 없습니다. – MarioVilas

1

조립 옵 코드가 같은 ...

해피 해킹. 모두가 잘된다면, 당신은 당신의 쉘 코드가 실행 볼 수 있습니다. 당신의 쉘 코드를 삽입하기 때문에 일반 트릭은 여전히 ​​널 (null)이없는 쉘 코드를 생성하는 적용되지만 시스템 콜을하는 방법은 다릅니다.

리눅스에서는 "int 0x80"명령으로 시스템 호출을하고, Windows에서는 DLL 라이브러리를 사용하고 t에 대한 일반적인 유머 모드 호출을해야합니다 후계자 수출 기능. 이러한 이유로

는 윈도우에 쉘 코드는 다음 중 하나를 수행해야합니다 : 하드 코딩이는 Win32 API 함수 주소 (대부분 전용 컴퓨터에서 작동합니다)
  • 사용는 Win32 API 확인자 쉘 코드를 (모든 작동

    • Windows 버전)

    지금 배우는 분이라면 디버거에 표시되는 주소를 하드 코딩하는 것이 더 쉽습니다. 호출 위치를 독립적으로 만들려면 레지스터에 주소를로드 할 수 있습니다.예를 들어, 4 개의 인수가있는 함수에 대한 호출은 다음과 같습니다.

    PUSH 4     ; argument #4 to the function 
    PUSH 3     ; argument #3 to the function 
    PUSH 2     ; argument #2 to the function 
    PUSH 1     ; argument #1 to the function 
    MOV EAX, 0xDEADBEEF  ; put the address of the function to call 
    CALL EAX 
    

    인수는 역순으로 푸시됩니다. CALL 명령 뒤에 EAX는 반환 값을 포함하고 스택은 이전과 같을 것이다 (즉, 함수가 자신의 인수를 팝한다). ECX 및 EDX 레지스터에는 가비지가 포함될 수 있으므로 호출 후에 값을 유지하지 마십시오.

    위치에 따라 직접 호출 명령이 작동하지 않습니다. 자체가 86 쉘 코드에 대한 널 (null)이없는 트릭 중 하나를 시도 주소에 0을 방지하기 위해

    , 거기에서 많은이 있지만 (긴이기는하지만) 내가 제일 좋아하는 XOR 지침을 사용하여 값을 인코딩입니다 :

    MOV EAX, 0xDEADBEEF^0xFFFFFFFF ; your value xor'ed against an arbitrary mask 
    XOR EAX, 0xFFFFFFFF    ; the arbitrary mask 
    

    을 NEG EAX 또는 NOT EAX (부호 반전 및 비트 반전)를 사용하여 작동 여부를 확인할 수도 있습니다 (각각 2 바이트).

    당신은 여기에서 호출 할 수있는 다양한 API 기능에 도움을받을 수 있습니다 : 당신이해야합니다 http://msdn.microsoft.com

    가장 중요한 사람은 아마도 다음

    첫 번째는 명령을 실행하고 다음 두 개는 DLL 파일을로드하고 해당 기능의 주소를 가져 오는 명령입니다.

    여기에 완전한 튜토리얼이 윈도우 쉘 코드 작성에있어 : ​​http://www.codeproject.com/Articles/325776/The-Art-of-Win32-Shellcoding

  • 관련 문제