CVE-2019-5018:Sqlite3 Window function长途代码实行破绽 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

CVE-2019-5018:Sqlite3 Window function长途代码实行破绽

申博_安全防护 申博 101次浏览 未收录 0个评论

概述

研究人员发如今Sqlite3 3.26.0的Windows函数功用中存在UAF破绽。经由历程特别捏造的SQL敕令能够发生该UAF破绽,致使长途代码实行。攻击者能够发送歹意SQL敕令来触发该破绽。

破绽概况

SQLite是完成SQL数据库引擎的经常运用库函数,被普遍运用于挪动装备、浏览器、硬件装备、用户运用中。也是小型、疾速、牢靠数据库解决方案的经常运用挑选。
SQLite完成了SQL的Window Functions特性,许可对行的子集(Subset、window)举行查询。经由历程剖析含有Window函数的SELECT语句,SELECT语句就会运用sqlite3WindowRewrite函数举行转化。

src/select.c:5643
sqlite3SelectPrep(pParse, p, 0);
...
#ifndef SQLITE_OMIT_WINDOWFUNC
if( sqlite3WindowRewrite(pParse, p) ){
    goto select_end;
}

在该函数中,若是运用了聚合函数(COUNT, MAX, MIN, AVG, SUM),SELECT对象的表达式列表就会被重写。

src/window.c:747
int sqlite3WindowRewrite(Parse *pParse, Select *p){
    int rc = SQLITE_OK;
    if( p->pWin && p->pPrior==0 ){
        ...
        Window *pMWin = p->pWin;      /* Master window object */
        Window *pWin;                 /* Window object iterator */
        ...
        selectWindowRewriteEList(pParse, pMWin /* window */, pSrc, p->pEList, &pSublist); [0]
        selectWindowRewriteEList(pParse, pMWin /* window */, pSrc, p->pOrderBy, &pSublist);
        ...
        pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition);

Master Window对象 pMWin是从SELECT对象中掏出的,在重写历程当中也用到了。这一历程是为了使其处置惩罚window函数举行轻易。

Advanced CORS Exploitation Techniques

Advanced CORS Exploitation Techniques 直入主题,本文我会介绍怎么去利用错误的CORS配置去搞事情。 第一种就是常规的XSS,第二种是基于先进的CORS技术。 第一种情况 攻击点 一年前,我正在攻击HackerOne主办的一个私人项目。在HTTP请求中使用Origin标识头后,然后检查服务器响应以检查它们是否进行域名白名单检查,我注意到应用程序只是盲目地将子域列入白名单,甚至是一些不存在的子域。 出于隐私原因和其他政策,我们假设Web应用程序托管在:www.redacted.com 这个CORS配置错误看起来像这样: HTTP Request: GET /api/return HTTP/1.1
Host: www.redacted.com
Origin: evil.redacted.com
Connection: close
HTTP Response: HTTP/1.1 200 OK
Access-control-allow-credentials: true
Access-control-allow-origin: evil.redacted.com
此API端点返回用户的私人信息,如全名,电子邮件地址,…. 为了充分利用这种错误配置,以便我们可以执行攻击,例如泄露用户的私人信息,我们需要声明一个被废弃的子域(子域名接管),或者在现有子域的中找到一个XSS。 发挥想象力,不要局限性思考 找到一个人家不要的子域并不是那么简单,所以我决定选择第二个选项,在一个现有的子域

src/window.c:692
static void selectWindowRewriteEList(
    Parse *pParse, 
    Window *pWin, 
    SrcList *pSrc,
    ExprList *pEList,               
    ExprList **ppSub                
){
    Walker sWalker;
    WindowRewrite sRewrite;

    memset(&sWalker, 0, sizeof(Walker));
    memset(&sRewrite, 0, sizeof(WindowRewrite));

    sRewrite.pSub = *ppSub;
    sRewrite.pWin = pWin; // [1] 
    sRewrite.pSrc = pSrc;

    sWalker.pParse = pParse;
    sWalker.xExprCallback = selectWindowRewriteExprCb;
    sWalker.xSelectCallback = selectWindowRewriteSelectCb;
    sWalker.u.pRewrite = &sRewrite;

    (void)sqlite3WalkExprList(&sWalker, pEList);

    *ppSub = sRewrite.pSub;
}
```sql
Master window对象是在WindowRewrite对象中运用的。在处置惩罚每一个表达式历程当中,xExprCallback函数会用作处置惩罚的回调函数。在处置惩罚聚合函数(TKAGGFUNCTION)和添加到表达式列表中后,表达式就会被删除。
```sql
src/window.c:602
static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
    struct WindowRewrite *p = pWalker->u.pRewrite;
    Parse *pParse = pWalker->pParse;
    ...
    switch( pExpr->op ){
        ...
        /* Fall through.  */

        case TK_AGG_FUNCTION:
        case TK_COLUMN: {
        Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0);
        p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup);
        if( p->pSub ){
            assert( ExprHasProperty(pExpr, EP_Static)==0 );
            ExprSetProperty(pExpr, EP_Static);
            sqlite3ExprDelete(pParse->db, pExpr); [2]
            ExprClearProperty(pExpr, EP_Static);
            memset(pExpr, 0, sizeof(Expr));

            pExpr->op = TK_COLUMN;
            pExpr->iColumn = p->pSub->nExpr-1;
            pExpr->iTable = p->pWin->iEphCsr;
        }
        ...
    }

在表达式删除时期,若是表达式被标记为window function,相干的window对象也会被删除。

src/window.c:1051
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
    ...
    if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
        ...
        if( ExprHasProperty(p, EP_WinFunc) ){
        assert( p->op==TK_FUNCTION );
        sqlite3WindowDelete(db, p->y.pWin);
        }
    }
 Window删除时期,与Window相干的局部都被删除
src/window.c:851
void sqlite3WindowDelete(sqlite3 *db, Window *p){
    if( p ){
        sqlite3ExprDelete(db, p->pFilter);
        sqlite3ExprListDelete(db, p->pPartition);
        sqlite3ExprListDelete(db, p->pOrderBy);
        sqlite3ExprDelete(db, p->pEnd);
        sqlite3ExprDelete(db, p->pStart);
        sqlite3DbFree(db, p->zName);
        sqlite3DbFree(db, p);
    }
}

能够看一下原始的sqlite3WindowRewrite函数,删除的局部在表达式列表被重写后重用了。

src/window.c:785
selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist); [4]
selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
...
pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition); [5]

src/window.c:723
static ExprList *exprListAppendList( 
    Parse *pParse,          
    ExprList *pList,        
    ExprList *pAppend [5]
){
    if( pAppend ){
        int i;
        int nInit = pList ? pList->nExpr : 0;
        for(i=0; i<pAppend->nExpr; i++){
            Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
            pList = sqlite3ExprListAppend(pParse, pList, pDup);
            if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
        }
    }
    return pList;
}

这局部被删除后,会在exprListAppendList中被重用,致使UAF破绽,终究激发DOS。若是攻击者能够掌握开释后的内存,那末就能够损坏更多的数据,有能够致使代码实行。

奔溃信息

运用sqlite3 debug版正本损坏开释的缓存的内容能够证实该破绽的存在。监控0xfafafafafafafafa左近的奔溃能够申明开释的缓存正在被再次接见。

src/malloc.c:341
void sqlite3DbFreeNN(sqlite3 *db, void *p){
    assert( db==0 || sqlite3_mutex_held(db->mutex) );
    assert( p!=0 );
    if( db ){
        ...
        if( isLookaside(db, p) ){
            LookasideSlot *pBuf = (LookasideSlot*)p;

            /* Trash all content in the buffer being freed */
            memset(p, 0xfa, db->lookaside.sz); [5]

            pBuf->pNext = db->lookaside.pFree;
            db->lookaside.pFree = pBuf;
            return;
        }
```sql
经由历程gdb sqlite3运转POC:
```sql
[─────────────────────REGISTERS──────────────────────]
*RAX  0xfafafafafafafafa
RBX  0x0
*RCX  0x7fffffd0
RDX  0x0
*RDI  0x7fffffffc3a0 —▸ 0x7ffff79c7340 (funlockfile) ◂— mov    rdx, qword ptr [rdi + 0x88]
RSI  0x0
R8   0x0
*R9   0x30
R10  0x0
*R11  0x246
*R12  0x401a20 (_start) ◂— xor    ebp, ebp
*R13  0x7fffffffe000 ◂— 0x2
R14  0x0
R15  0x0
*RBP  0x7fffffffc900 —▸ 0x7fffffffc990 —▸ 0x7fffffffcc10 —▸ 0x7fffffffce90 ◂— ...
*RSP  0x7fffffffc8d0 —▸ 0x4db4f5 (selectWindowRewriteSelectCb) ◂— push   rbp
*RIP  0x4db723 (exprListAppendList+240) ◂— mov    eax, dword ptr [rax]
[───────────────────────DISASM───────────────────────]
 0x4db723 <exprListAppendList+240>    mov    eax, dword ptr [rax]
0x4db725 <exprListAppendList+242>    cmp    eax, dword ptr [rbp - 0x10]
0x4db728 <exprListAppendList+245>    jg     exprListAppendList+94         <0x4db691>
    
0x4db691 <exprListAppendList+94>     mov    rax, qword ptr [rbp - 0x28]
0x4db695 <exprListAppendList+98>     mov    edx, dword ptr [rbp - 0x10]
0x4db698 <exprListAppendList+101>    movsxd rdx, edx
0x4db69b <exprListAppendList+104>    shl    rdx, 5
0x4db69f <exprListAppendList+108>    add    rax, rdx
0x4db6a2 <exprListAppendList+111>    add    rax, 8
0x4db6a6 <exprListAppendList+115>    mov    rcx, qword ptr [rax]
0x4db6a9 <exprListAppendList+118>    mov    rax, qword ptr [rbp - 0x18]
[───────────────────────SOURCE───────────────────────]
145380  ){
145381    if( pAppend ){
145382      int i;
145383      int nInit = pList ? pList->nExpr : 0;
145384      printf("pAppend: [%p] -> %p\n", &pAppend, pAppend);
145385      for(i=0; i<pAppend->nExpr; i++){ // BUG-USE 0
145386        Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0);
145387        pList = sqlite3ExprListAppend(pParse, pList, pDup);
145388        if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder;
145389      }
[───────────────────────STACK────────────────────────]
00:0000 rsp  0x7fffffffc8d0 —▸ 0x4db4f5 (selectWindowRewriteSelectCb) ◂— push   rbp
01:0008      0x7fffffffc8d8 ◂— 0xfafafafafafafafa
02:0010      0x7fffffffc8e0 —▸ 0x746d58 ◂— 0x1
03:0018      0x7fffffffc8e8 —▸ 0x7fffffffdb30 —▸ 0x73b348 —▸ 0x736c60 (aVfs.13750) ◂— ...
04:0020      0x7fffffffc8f0 ◂— 0x100000000
05:0028      0x7fffffffc8f8 ◂— 0xce1ae95b8dd44700
06:0030 rbp  0x7fffffffc900 —▸ 0x7fffffffc990 —▸ 0x7fffffffcc10 —▸ 0x7fffffffce90 ◂— ...
07:0038      0x7fffffffc908 —▸ 0x4db994 (sqlite3WindowRewrite+608) ◂— mov    qword ptr [rbp - 0x68], rax
[─────────────────────BACKTRACE──────────────────────]
 f 0           4db723 exprListAppendList+240
f 1           4db994 sqlite3WindowRewrite+608


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明CVE-2019-5018:Sqlite3 Window function长途代码实行破绽
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址