Ipmi d'après Wikipedia est: "L'Interface de gestion intelligente de matériel, (ou IPMI, Intelligent Platform Management Interface) est un ensemble de spécifications d'interfaces communes avec du matériel informatique (principalement des serveurs) permettant de surveiller certains composants (ventilateur, sonde de température, ...), mais également de contrôler l'ordinateur à distance, reboot, interrupteur, console à distance."
En gros ça se présente sous la forme d'un chip intégré à la carte réseau d'un serveur et ça écoute pour recevoir des commande bas niveau de type combien de courant consomme tu ? coupe l'alimentation, effectue un redémarrage par acpi et ainsi de suite ... Les firmwares embarqués sont toujours de bon candidat au fuzzing car pas souvent mis à jour et mis à jour pénible et c'est pas comme si ça n'avait pas posé des problèmes dans le passé ...
#! /usr/bin/env python #vim: set fileencoding=latin-1 # Author: Jérémie Banier # Date: Oct. 29 2013 # Purpose: implement / test ipmi protocol with scapy # Based on test add-ons sample # usage: import logging # Set log level to benefit from Scapy warnings logging.getLogger("scapy").setLevel(1) from scapy.all import * class Rmcp(Packet): name = "Remote Management Control Protocol" fields_desc=[ LEShortField("Version",0x06), ByteField("Sequence", 0xFF) , XByteField("Type and Class", 0x07) , ByteEnumField("Authentication type", 0, {0:'None', 6:'RMCP+'}), ] bind_layers( UDP, Rmcp, sport=623 ) bind_layers( UDP, Rmcp, dport=623 ) class IPMISessionLayer(Packet): name = "IPMI Session Wrapper" fields_desc=[ IntField("Session sequence number", 0), XIntField("Session ID", 0), ByteField("Message length", 0), ] class IPMISessionLayer2(Packet): name = "IPMI Session Wrapper v2.0+" fields_desc=[ ByteEnumField("Payload type", 0x10, {0x10:"Open session request", 0x11:"Open session response", 0x12:"RAKP Message 1", 0x13:"RAKP Message 2" }), IntField("Session sequence number", 0), XIntField("Session ID", 0), ByteField("Message length", 0), ] bind_layers( Rmcp, IPMISessionLayer, {'Authentication type':0} ) bind_layers( Rmcp, IPMISessionLayer2, {'Authentication type':6} ) class IPMILayer(Packet): name = "Intelligent Platform Management Interface" fields_desc = [ ByteField("Target address", 0x20), ByteEnumField("Target LUN", 0x18, {0x18:"NetFN Application Request"}), ByteField("Header checksum", 0xc8), ByteField("Source address", 0x81), ByteField("Source LUN", 0x00), ByteEnumField("Command", 0x38, {0x38:"Get Channel Auth. cap."}), ByteEnumField("Version compat.", 0x0e, {0x0e:"IPMI v2.0+"}), ByteEnumField("Requested privilege level", 0x04, {0x04:"Administrator"}), ByteField("Data checksum", 0xb5) ] bind_layers( IPMISessionLayer, IPMILayer ) if __name__ == "__main__": interact(mydict=globals(), mybanner="IPMI fuzzer")
Le script en est encore à l'état d'ébauche mais on peut déjà l'utiliser pour tester l'API de Scapy:
└───> ./Rmcp.py WARNING: No route found for IPv6 destination :: (no default route?) Welcome to Scapy (2.2.0) IPMI fuzzer >>> t= rdpcap('ipmi2.pcap') >>> t[16].show() ###[ cooked linux ]### pkttype= sent-by-us lladdrtype= 0x1 lladdrlen= 6 src= '\x00\x1d\tlg,' proto= IPv4 ###[ IP ]### version= 4L ihl= 5L tos= 0x0 len= 76 id= 9063 flags= DF frag= 0L ttl= 64 proto= udp chksum= 0x5c0a src= 10.200.82.208 dst= 10.201.82.207 \options\ ###[ UDP ]### sport= 41227 dport= asf_rmcp len= 56 chksum= 0xbb79 ###[ Remote Management Control Protocol ]### Version= 6 Sequence= 255 Type and Class= 0x7 Authentication type= RMCP+ ###[ IPMI Session Wrapper v2.0+ ]### Payload type= Open session request Session sequence number= 0 Session ID= 0x0 Message length= 32
Il me reste encore à implémenter l'ouverture de session, ce qui permettrais de faire du brute force sur le mot de passe admin par exemple (encore qu'il faudrait pour cela que le chip ipmi soit accessible depuis internet ce qui serait pas un très bonne idée pour dire ça poliment)
Une affaire à suivre avec heureusement des détails croustillants :P et une fin heureuse ...