Wednesday, January 9, 2019

[12] 脚本编译语言带有unicode字符

https://bugs.chromium.org/p/chromium/issues/detail?id=70718
https://bugs.webkit.org/show_bug.cgi?id=52390
https://bugs.webkit.org/show_bug.cgi?id=52396
https://bugs.webkit.org/show_bug.cgi?id=50929

和yy规则配合后,导致错误的规则解析

<script id="per-fragment-lighting-fs" type="x-shader/x-fragment">
  float specularLightWeighténg = 0.0;
</script>

Monday, January 7, 2019

[11] 错误调用名称近似但返回类型相同的方法

https://www.exploit-db.com/exploits/46071

void AbstractValue::set(Graph& graph, RegisteredStructure structure)
{
    RELEASE_ASSERT(structure);
    
    m_structure = structure;

    m_arrayModes = asArrayModes(structure->indexingType());  <<<<<<<<
    m_type = speculationFromStructure(structure.get());
    m_value = JSValue();
    
    checkConsistency();
    assertIsRegistered(graph);
}

显然,此处代码应该调用IndexingMode而不是indexingType。

[10] 关键判断有效性语句的条件绕过

https://www.exploit-db.com/exploits/46072

对于代码:

    if ((storage->hasHoles() && this->structure(vm)->holesMustForwardToPrototype(vm, this)) 
        || hasSparseMap() 
        || shouldUseSlowPut(indexingType())) {
        return false;
    }

该函数应该防止带hole的数组进入后续代码。但是这种类型的数组实际上可以通过让holesMustForwardToPrototype方法返回false来实现。
除非数组上有任何索引访问器或原型链中的Proxy,否则该方法将只返回false。导致此处关键判断有效性语句失效。

PoC:

function main() {
    let arr = [1];

    arr.length = 0x100000;
    arr.splice(0, 0x11);

    arr.length = 0xfffffff0;
    arr.splice(0xfffffff0, 0, 1);
}

main();

[09] 缓冲区截断后长度信息未能正确同步

https://curl.haxx.se/docs/CVE-2017-1000100.html

在curl / libcurl进行TFTP传输时,会给出一个包含很长文件名(长度大约为515字节)的URL,文件名会被截断以适应缓冲区边界,但缓冲区大小仍然会被错误地更新以便使用未截断的长度。
然后在sendto()调用中使用这个过大的值,使curl尝试发送的数据多于实际放入缓冲区的数据。

@@ -489,10 +489,15 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
     result = Curl_urldecode(data, &state->conn->data->state.path[1], 0,
                             &filename, NULL, FALSE);
     if(result)
       return result;
 
+    if(strlen(filename) > (state->blksize - strlen(mode) - 4)) {
+      failf(data, "TFTP file name too longn");
+      return CURLE_TFTP_ILLEGAL; /* too long file name field */
+    }
+

[08] 针对用户名/密码的比较使用了非大小写敏感函数

https://curl.haxx.se/docs/CVE-2016-8616.html

重新使用连接时,curl对用户名和密码与现有连接进行不区分大小写的比较。这会导致猜测密码的复杂性下降许多。

在对代码进行重新抽象化时,我发现类似的问题通常出现在开发者封装了一个不区分大小写的比较函数,而名称却没有表示清楚。除非特别归纳测试用例,这类问题很难通过普通自动化测试发现。

-        if(!strequal(needle->user, check->user) ||
-           !strequal(needle->passwd, check->passwd)) {
+        if(strcmp(needle->user, check->user) ||
+           strcmp(needle->passwd, check->passwd)) {

[07] 部分编译器下realloc可能导致double free问题

注意到libcurl有如下漏洞:
53 double-free in curl_maprintf November 02, 2016 7.1 7.50.3 CVE-2016-8618 CWE-415: Double Free
52 double-free in krb5 code November 02, 2016 7.3 7.50.3 CVE-2016-8619 CWE-415: Double Free

在某些编译器下(如gcc),当调用realloc(ptr, 0)即size=0时,realloc将试图释放原内存。当开发人员通过realloc的返回值决定是否做失败后释放时,将可能在第二次释放处产生double free。

leonwxqian@leonwxqian-VirtualBox:~$ cat realloc.c 
#include <stdlib.h>

void main(){
  void* a = malloc(16);
  if(!realloc(a, 0))  //free 1
      free(a);           //free 2 !!!
}
leonwxqian@leonwxqian-VirtualBox:~$ ./realloctest
*** Error in `./realloctest': double free or corruption (fasttop): 0x000000000081b010 ***