mirror of
https://github.com/github/codeql.git
synced 2026-02-21 01:13:43 +01:00
add ssh client libraries, add SecondaryServerCmdInjectionCustomizations
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `asyncssh` PyPI package.
|
||||
* See https://pypi.org/project/asyncssh/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
import experimental.semmle.python.security.SecondaryServerCmdInjectionCustomizations
|
||||
|
||||
/**
|
||||
* Provides models for the `asyncssh` PyPI package.
|
||||
* See https://pypi.org/project/asyncssh/.
|
||||
*/
|
||||
private module Asyncssh {
|
||||
/**
|
||||
* Gets `asyncssh` package.
|
||||
*/
|
||||
private API::Node asyncssh() { result = API::moduleImport("asyncssh") }
|
||||
|
||||
/**
|
||||
* A `run` method responsible for executing commands on remote secondary servers.
|
||||
*/
|
||||
class AsyncsshRun extends SecondaryCommandInjection::Sink {
|
||||
AsyncsshRun() {
|
||||
this =
|
||||
asyncssh()
|
||||
.getMember("connect")
|
||||
.getReturn()
|
||||
.getMember("run")
|
||||
.getACall()
|
||||
.getParameter(0, "command")
|
||||
.asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `netmiko` PyPI package.
|
||||
* See https://pypi.org/project/netmiko/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
import experimental.semmle.python.security.SecondaryServerCmdInjectionCustomizations
|
||||
|
||||
/**
|
||||
* Provides models for the `netmiko` PyPI package.
|
||||
* See https://pypi.org/project/netmiko/.
|
||||
*/
|
||||
private module Netmiko {
|
||||
/**
|
||||
* Gets `netmiko` package.
|
||||
*/
|
||||
private API::Node netmiko() { result = API::moduleImport("netmiko") }
|
||||
|
||||
/**
|
||||
* Gets `netmiko.ConnectHandler` return value.
|
||||
*/
|
||||
private API::Node netmikoConnectHandler() {
|
||||
result = netmiko().getMember("ConnectHandler").getReturn()
|
||||
}
|
||||
|
||||
/**
|
||||
* The `send_*` methods responsible for executing commands on remote secondary servers.
|
||||
*/
|
||||
class NetmikoSendCommand extends SecondaryCommandInjection::Sink {
|
||||
NetmikoSendCommand() {
|
||||
this =
|
||||
netmikoConnectHandler()
|
||||
.getMember(["send_command", "send_command_expect", "send_command_timing"])
|
||||
.getACall()
|
||||
.getParameter(0, "command_string")
|
||||
.asSink()
|
||||
or
|
||||
this =
|
||||
netmikoConnectHandler()
|
||||
.getMember(["send_multiline", "send_multiline_timing"])
|
||||
.getACall()
|
||||
.getParameter(0, "commands")
|
||||
.asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `paramiko` PyPI package.
|
||||
* See https://pypi.org/project/paramiko/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
import experimental.semmle.python.security.SecondaryServerCmdInjectionCustomizations
|
||||
|
||||
/**
|
||||
* Provides models for the `paramiko` PyPI package.
|
||||
* See https://pypi.org/project/paramiko/.
|
||||
*/
|
||||
private module Paramiko {
|
||||
/**
|
||||
* Gets `paramiko` package.
|
||||
*/
|
||||
private API::Node paramiko() { result = API::moduleImport("paramiko") }
|
||||
|
||||
/**
|
||||
* Gets `paramiko.SSHClient` return value.
|
||||
*/
|
||||
private API::Node paramikoClient() { result = paramiko().getMember("SSHClient").getReturn() }
|
||||
|
||||
/**
|
||||
* The `exec_command` of `paramiko.SSHClient` class execute command on ssh target server
|
||||
*/
|
||||
class ParamikoExecCommand extends SecondaryCommandInjection::Sink {
|
||||
ParamikoExecCommand() {
|
||||
this =
|
||||
paramikoClient().getMember("exec_command").getACall().getParameter(0, "command").asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `scrapli` PyPI package.
|
||||
* See https://pypi.org/project/scrapli/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
import experimental.semmle.python.security.SecondaryServerCmdInjectionCustomizations
|
||||
|
||||
/**
|
||||
* Provides models for the `scrapli` PyPI package.
|
||||
* See https://pypi.org/project/scrapli/.
|
||||
*/
|
||||
private module Scrapli {
|
||||
/**
|
||||
* Gets `scrapli` package.
|
||||
*/
|
||||
private API::Node scrapli() { result = API::moduleImport("scrapli") }
|
||||
|
||||
/**
|
||||
* Gets `scrapli.driver` package.
|
||||
*/
|
||||
private API::Node scrapliDriver() { result = scrapli().getMember("driver") }
|
||||
|
||||
/**
|
||||
* Gets `scrapli.driver.core` package.
|
||||
*/
|
||||
private API::Node scrapliCore() { result = scrapliDriver().getMember("core") }
|
||||
|
||||
/**
|
||||
* A `send_command` method responsible for executing commands on remote secondary servers.
|
||||
*/
|
||||
class ScrapliSendCommand extends SecondaryCommandInjection::Sink {
|
||||
ScrapliSendCommand() {
|
||||
this =
|
||||
scrapliCore()
|
||||
.getMember([
|
||||
"AsyncNXOSDriver", "AsyncJunosDriver", "AsyncEOSDriver", "AsyncIOSXEDriver",
|
||||
"AsyncIOSXRDriver", "NXOSDriver", "JunosDriver", "EOSDriver", "IOSXEDriver",
|
||||
"IOSXRDriver"
|
||||
])
|
||||
.getReturn()
|
||||
.getMember("send_command")
|
||||
.getACall()
|
||||
.getParameter(0, "command")
|
||||
.asSink()
|
||||
or
|
||||
this =
|
||||
scrapli()
|
||||
.getMember("Scrapli")
|
||||
.getReturn()
|
||||
.getMember("send_command")
|
||||
.getACall()
|
||||
.getParameter(0, "command")
|
||||
.asSink()
|
||||
or
|
||||
this =
|
||||
scrapliDriver()
|
||||
.getMember("GenericDriver")
|
||||
.getReturn()
|
||||
.getMember("send_command")
|
||||
.getACall()
|
||||
.getParameter(0, "command")
|
||||
.asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `ssh2-python` PyPI package.
|
||||
* See https://pypi.org/project/ssh2-python/.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import semmle.python.Concepts
|
||||
private import semmle.python.ApiGraphs
|
||||
import experimental.semmle.python.security.SecondaryServerCmdInjectionCustomizations
|
||||
|
||||
/**
|
||||
* Provides models for the `ssh2-python` PyPI package.
|
||||
* See https://pypi.org/project/ssh2-python/.
|
||||
*/
|
||||
private module Ssh2 {
|
||||
/**
|
||||
* Gets `ssh2` package.
|
||||
*/
|
||||
private API::Node ssh2() { result = API::moduleImport("ssh2") }
|
||||
|
||||
/**
|
||||
* Gets `ssh2.session` package.
|
||||
*/
|
||||
private API::Node ssh2Session() { result = API::moduleImport("ssh2").getMember("session") }
|
||||
|
||||
/**
|
||||
* Gets `ssh2.session.Session` return value.
|
||||
*/
|
||||
private API::Node ssh2Session() { result = ssh2Session().getMember("Session").getReturn() }
|
||||
|
||||
/**
|
||||
* A `execute` method responsible for executing commands on remote secondary servers.
|
||||
*/
|
||||
class Ssh2Execute extends SecondaryCommandInjection::Sink {
|
||||
Ssh2Execute() {
|
||||
this =
|
||||
ssh2Session()
|
||||
.getMember("open_session")
|
||||
.getReturn()
|
||||
.getMember("execute")
|
||||
.getACall()
|
||||
.getParameter(0, "command")
|
||||
.asSink()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,42 +4,10 @@ import semmle.python.dataflow.new.RemoteFlowSources
|
||||
import semmle.python.ApiGraphs
|
||||
import semmle.python.dataflow.new.internal.DataFlowPublic
|
||||
import codeql.util.Unit
|
||||
|
||||
/**
|
||||
* Provides sinks and additional taint steps for the secondary command injection configuration
|
||||
*/
|
||||
module SecondaryCommandInjection {
|
||||
/**
|
||||
* The additional taint steps that need for creating taint tracking or dataflow.
|
||||
*/
|
||||
class AdditionalTaintStep extends Unit {
|
||||
/**
|
||||
* Holds if there is a additional taint step between pred and succ.
|
||||
*/
|
||||
abstract predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ);
|
||||
}
|
||||
|
||||
/**
|
||||
* A abstract class responsible for extending new decompression sinks
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
}
|
||||
|
||||
/**
|
||||
* The exec_command of `paramiko.SSHClient` class execute command on ssh target server
|
||||
*/
|
||||
class ParamikoExecCommand extends SecondaryCommandInjection::Sink {
|
||||
ParamikoExecCommand() {
|
||||
this = paramikoClient().getMember("exec_command").getACall().getParameter(0, "command").asSink()
|
||||
}
|
||||
}
|
||||
|
||||
private API::Node paramikoClient() {
|
||||
result = API::moduleImport("paramiko").getMember("SSHClient").getReturn()
|
||||
}
|
||||
import SecondaryServerCmdInjectionCustomizations
|
||||
|
||||
module SecondaryCommandInjectionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
predicate isSource(DataFlow::Node source) { source instanceof SecondaryCommandInjection::Source }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof SecondaryCommandInjection::Sink }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import python
|
||||
import semmle.python.dataflow.new.TaintTracking
|
||||
import semmle.python.dataflow.new.RemoteFlowSources
|
||||
import semmle.python.ApiGraphs
|
||||
import semmle.python.dataflow.new.internal.DataFlowPublic
|
||||
import codeql.util.Unit
|
||||
|
||||
/**
|
||||
* Provides sinks and additional taint steps for the secondary command injection configuration
|
||||
*/
|
||||
module SecondaryCommandInjection {
|
||||
/**
|
||||
* The additional taint steps that need for creating taint tracking or dataflow.
|
||||
*/
|
||||
class AdditionalTaintStep extends Unit {
|
||||
/**
|
||||
* Holds if there is a additional taint step between pred and succ.
|
||||
*/
|
||||
abstract predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ);
|
||||
}
|
||||
|
||||
/**
|
||||
* A abstract class responsible for extending secondary command injection dataflow sinks.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
|
||||
/**
|
||||
* A data flow source for secondary command injection data flow queries.
|
||||
*/
|
||||
abstract class Source extends DataFlow::Node { }
|
||||
|
||||
class RemoteSources extends Source {
|
||||
RemoteSources() { this instanceof RemoteFlowSource }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user