Practical Cpp Reversing

download Practical Cpp Reversing

of 36

Transcript of Practical Cpp Reversing

  • 8/3/2019 Practical Cpp Reversing

    1/36

    Practical C++ reversing

    Benjamin Vanheuverzwijn

    ESET

  • 8/3/2019 Practical Cpp Reversing

    2/36

    About me

    Employee @ ESET botnet analysis

    Student in electrical engineering @ E.T.S. Member @ CISSP groupies

    [email protected]

  • 8/3/2019 Practical Cpp Reversing

    3/36

    Win32/Kelihos

    scan your harddrive network dump send spam DDoS

    2 mb binary packed

    custom UPX

    multiple libraries Boost winpcap protocol library

    (http,...) heavy thread usage P2P protocol

  • 8/3/2019 Practical Cpp Reversing

    4/36

    Objectives

    Reverse Kelihos network stack1. raw data handler2. packet handler3. message handler

    Learn how C++ works in assembly1. object construction2. call convention3. object layout in memory

    Exploit weakness in the Kelihos protocol

  • 8/3/2019 Practical Cpp Reversing

    5/36

    The plan

    Infect a machine Kelihos listens on port 80 Hook a debugger Reverse the packet handling stack:

    raw data handler packet handler header handler message handler

  • 8/3/2019 Practical Cpp Reversing

    6/36

    First step (1/2)

    Static analysis is hard (without context) Finding an entry point (network) Put a breakpoint on WSARecv Send some data

  • 8/3/2019 Practical Cpp Reversing

    7/36

    First step (2/2)

    The stack.

  • 8/3/2019 Practical Cpp Reversing

    8/36

    Followed by static analysis

    References toWSARecv():deep inboost.asio!

  • 8/3/2019 Practical Cpp Reversing

    9/36

    Object construction

    "new(size_t s)" wraps "malloc(size_t s)" Call the constructor function (using "edi" as "memory ptr")

  • 8/3/2019 Practical Cpp Reversing

    10/36

    Compiler paradigm: constructor

    call to new(size_t) malloc() memory

    call to "base_class->construct()" function that initialize the structure

    call to "member->construct()" when object has object members

    call to "object->construct()" written by the programmer

    returns "this" in eax

  • 8/3/2019 Practical Cpp Reversing

    11/36

    Raw data handler

    recv_handler function:

  • 8/3/2019 Practical Cpp Reversing

    12/36

    Raw data handler

    From dynamic (debugger) analysis:

  • 8/3/2019 Practical Cpp Reversing

    13/36

    Raw data handler

    From WSARecv documentation:"If no error occurs and the receive operation has completedimmediately, WSARecv returns zero."

  • 8/3/2019 Practical Cpp Reversing

    14/36

    Raw data handler

    There is still some question: Using ecxwithout initialization? Calling a register initialized with ecx?

  • 8/3/2019 Practical Cpp Reversing

    15/36

    Compiler paradigm: call convention

    Register used for "this" ptr (usually ecx) Parameters on the stack Static method: A::static_fct(int x)

    push 42 - push parameter

    call static_fct - call the static function Classic method: a->fct(int y)

    push 42 - push parameter (int z) mov ecx, esi - put "this" in ecx call fct - call the function

    Virtual method: a->v_fct(int z) push 42 - push parameter (int z) mov eax, [esi] - dereference vftable mov ecx, esi - put "this" in ecx call [eax] - call the function (vftable)

  • 8/3/2019 Practical Cpp Reversing

    16/36

    Raw data handler

    We come from classic method: this->fct(int z) ecxis used without initialization ebxis used to reference "this"

  • 8/3/2019 Practical Cpp Reversing

    17/36

    Raw data handler

    But... we still have a question: calling "[this+20C8]+0x4"?

  • 8/3/2019 Practical Cpp Reversing

    18/36

    Compiler paradigm: instance layout

    Virtual function table (vft) Members

  • 8/3/2019 Practical Cpp Reversing

    19/36

    Raw data handler

    What we know from the instance layout of the object: 1 vftable = 1 parent class vftable are hard to follow in static analysis

  • 8/3/2019 Practical Cpp Reversing

    20/36

    Packet handler

  • 8/3/2019 Practical Cpp Reversing

    21/36

    Packet handler

  • 8/3/2019 Practical Cpp Reversing

    22/36

    Packet handler

  • 8/3/2019 Practical Cpp Reversing

    23/36

    Packet handler

    Call to string::append(char *buffer, size_t length) Now we know "member_2" is a String

  • 8/3/2019 Practical Cpp Reversing

    24/36

    Packet handler

  • 8/3/2019 Practical Cpp Reversing

    25/36

    Packet handler

  • 8/3/2019 Practical Cpp Reversing

    26/36

    Packet handler

    Call to string::append()1. push parameters2. put the string pointer in "ecx"3. call the function

    Call to string::operator[]()1. push parameter2. put the string pointer in "ecx"3. call the function4. eax will now point on the position

    We learn that for a valid packet: must not begin with 0x0500 must have a minimum length of 0x08

  • 8/3/2019 Practical Cpp Reversing

    27/36

    Static analysis: header_handler

    We then pass trough a lot of not efficient code:1. validate packet headers2. unpack packet headers3. strip headers

    4. call the message_handler

  • 8/3/2019 Practical Cpp Reversing

    28/36

    Header validation

  • 8/3/2019 Practical Cpp Reversing

    29/36

    Header unpacking

  • 8/3/2019 Practical Cpp Reversing

    30/36

    Static analysis: header_unpack

    1. head1, head2, a and b = random integers2. crypted_size = c - head1 - a3. msg_type = d - crypted_size - 2* (head1 - a)

  • 8/3/2019 Practical Cpp Reversing

    31/36

    Message handler

  • 8/3/2019 Practical Cpp Reversing

    32/36

    Message handler

    msg of type "Bootstrap"

  • 8/3/2019 Practical Cpp Reversing

    33/36

    More about kelihos P2P protocol

    Payload is: Encrypted Compressed Serialized

    Bootstrap message contains: Peerlist Peer information (ip, port, etc)

    The bug: port is serialized with 4 bytes cast in 2 bytes needed

  • 8/3/2019 Practical Cpp Reversing

    34/36

    Bootstrap message

    Label: m_live_time Type: ValueScalar value:73 size:8

    ...Label: m_listenning_port Type: Value

    Scalar value:80 size:4

    Label: m_real_target_ip Type: ValueScalarvalue:62.4.47.49 size:4

    Label: m_bootstrap_list Type: Section...

  • 8/3/2019 Practical Cpp Reversing

    35/36

    Inject peers

    Peer with high live_time is kept first in the list Peers are identified with ip AND port Inject same ip but with different port (80 dec. = 0x50)

    0xAAAA0050 & 0x0000FFFF = 0x50

    0xBBBB0050 & 0x0000FFFF = 0x50 Injected peer list:

    m_ip = 64.12.41.51m_live_time = 9999999m_listening_port = 0xAAAA0050

    ...m_ip = 64.12.41.51m_live_time = 9999999m_listening_port = 0xBBBB0050

  • 8/3/2019 Practical Cpp Reversing

    36/36

    Question? / Answer!