CodeQL 文档

PAM 授权绕过,原因是使用不当

ID: py/pam-auth-bypass
Kind: path-problem
Security severity: 8.1
Severity: warning
Precision: high
Tags:
   - security
   - external/cwe/cwe-285
Query suites:
   - python-code-scanning.qls
   - python-security-extended.qls
   - python-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

仅使用对 pam_authenticate 的调用来检查登录的有效性会导致授权绕过漏洞。

pam_authenticate 只验证用户的凭据。它不会检查用户是否具有适当的授权来实际登录。这意味着具有过期登录或密码的用户仍然可以访问系统。

建议

pam_authenticate 的调用之后应紧接着对 pam_acct_mgmt 的调用,以检查用户是否允许登录。

示例

在以下示例中,代码只检查用户的凭据。因此,在这种情况下,具有过期凭据的用户仍然可以登录。这可以通过创建新的用户帐户,使用 chage -E0 `username` 使其过期,然后尝试登录来验证。

libpam                    = CDLL(find_library("pam"))

pam_authenticate          = libpam.pam_authenticate
pam_authenticate.restype  = c_int
pam_authenticate.argtypes = [PamHandle, c_int]

def authenticate(username, password, service='login'):
    def my_conv(n_messages, messages, p_response, app_data):
        """
        Simple conversation function that responds to any prompt where the echo is off with the supplied password
        """
        ...

    handle = PamHandle()
    conv   = PamConv(my_conv, 0)
    retval = pam_start(service, username, byref(conv), byref(handle))

    retval = pam_authenticate(handle, 0)
    return retval == 0

这可以通过调用 pam_acct_mgmt 来避免,以验证访问权限,如下面代码段所示。

libpam                    = CDLL(find_library("pam"))

pam_authenticate          = libpam.pam_authenticate
pam_authenticate.restype  = c_int
pam_authenticate.argtypes = [PamHandle, c_int]

pam_acct_mgmt          = libpam.pam_acct_mgmt
pam_acct_mgmt.restype  = c_int
pam_acct_mgmt.argtypes = [PamHandle, c_int]

def authenticate(username, password, service='login'):
    def my_conv(n_messages, messages, p_response, app_data):
        """
        Simple conversation function that responds to any prompt where the echo is off with the supplied password
        """
        ...

    handle = PamHandle()
    conv   = PamConv(my_conv, 0)
    retval = pam_start(service, username, byref(conv), byref(handle))

    retval = pam_authenticate(handle, 0)
    if retval == 0:
        retval = pam_acct_mgmt(handle, 0)
    return retval == 0

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私