2017年6月

NScript:有符号的64位和无符号的32位(?)

最近有一个比较扯淡的学业水平试题,学业水平考试一向是走形式,没想大厂微软也做了类似的事情。微软的公共符号不仅方便微软找问题,也方便了安全人员找问题,不过最近在看MSE的NScript时,发现了微软一个好玩的东西。

Ps0c-fyhfxph1878995.jpg

不知道微软是32位被报的多了还是怎么的,在它的公共符号服务器上还就是没有32位DLL的符号(无论是直接下载,还是使用虚拟机看x86自带的Windows Defender,最后结果都是——没有)。但是64位的符号却有,这就让人十分不解了。

(32bit)1.1.13804.0 From Windows Defender
E:\Program Files (x86)\Debugging Tools for Windows>symchk E:\Users\BlastTS\Desktop\wLoadMpEngine\Debug\mpengine.dll
SYMCHK: mpengine.dll         FAILED  - mpengine.pdb mismatched or not found

SYMCHK: FAILED files = 1
SYMCHK: PASSED + IGNORED files = 0

(64,win7)1.1.13701.0 From Windows Defender
E:\Program Files (x86)\Debugging Tools for Windows>symchk E:\msmpeng\x64-w7\mpengine.dll

SYMCHK: FAILED files = 0
SYMCHK: PASSED + IGNORED files = 1

如果你觉得是版本的问题,那也有例外,win10 64bit:1.1.13103.0 也就没有符号。所以,不知道微软葫芦里卖的什么药,难不成是正式版和非正式版的区别?不过这可都是你官网下发的啊。

这里主要最近看了taviso的linux加载MSE引擎并evaluate的例子,我想着在Windows下直接用系统的方式加载DLL并传入数据进行Fuzz。但是可怕的是没有符号,也就是说我需要手动定位我要hook的函数在哪里,而且修改它,让它跳转到我的函数中。

taviso的方式类似grinder的处理方式,即hook strtod来做logging。传入的字符是__log:开头的时候,就会认为是我们的log,否则调用正常的strtod逻辑。这个strtod被parseFloat调用:(后续的代码截图全是基于x64的)

out.jpg

不过为啥要放出上面的图呢,因为……即使32位无符号,像strtod这样不会有代码变动的函数(微软的编译选项中,strtod的代码是被直接静态写入DLL中的,不是对MSVC库的调用),只要和x64的代码一对比就可以找到位置。通过对比x64的JsDelegateObject_Global::parseFloat,就可以轻易地找到strtod,并在我们的代码中对其进行Hook。一下午的操作之后,我们就能直接调用NScript的接口,并且正确的得到输出了:

out.jpg

相关的代码之后我会整理放出。

精简了一下mozilla的funfuzzer,有兴趣的可以直接拿去玩

mozilla的那套框架真是令人excited,代码耦合的程度那是相当的高,各种依赖,如果你只是想测试一下你的js引擎,而且还是第一次接触funfuzzer,我估计你看完那一堆需求和写的不明不白的官方文档之后会疯掉。

老实说,你开源了就做个一键能用的嘛,这么麻烦作甚。好在fuzz代码和框架其实是某种意义上的非耦合的。很简单的就可以提取出funfuzzer的fuzz代码,脚本也是十分简单,提供如下。

extract-funfuzzer.bat

echo "//by blast @nul.pw">>output.js
copy /b output.js+.\jsfunfuzz\preamble.js output.js

copy /b output.js+.\jsfunfuzz\detect-engine.js output.js
copy /b output.js+.\jsfunfuzz\avoid-known-bugs.js output.js
copy /b output.js+.\jsfunfuzz\error-reporting.js output.js

copy /b output.js+.\shared\random.js output.js
copy /b output.js+.\shared\mersenne-twister.js output.js
copy /b output.js+.\shared\testing-functions.js output.js

copy /b output.js+.\jsfunfuzz\built-in-constructors.js output.js

copy /b output.js+.\jsfunfuzz\mess-tokens.js output.js
copy /b output.js+.\jsfunfuzz\mess-grammar.js output.js

copy /b output.js+.\jsfunfuzz\gen-asm.js output.js
copy /b output.js+.\jsfunfuzz\gen-math.js output.js
copy /b output.js+.\jsfunfuzz\gen-grammar.js output.js
copy /b output.js+.\jsfunfuzz\gen-proxy.js output.js
copy /b output.js+.\jsfunfuzz\gen-recursion.js output.js
copy /b output.js+.\jsfunfuzz\gen-regex.js output.js
copy /b output.js+.\jsfunfuzz\gen-stomp-on-registers.js output.js
copy /b output.js+.\jsfunfuzz\gen-type-aware-code.js output.js

copy /b output.js+.\jsfunfuzz\test-asm.js output.js
copy /b output.js+.\jsfunfuzz\test-math.js output.js
copy /b output.js+.\jsfunfuzz\test-regex.js output.js
copy /b output.js+.\jsfunfuzz\test-consistency.js output.js
copy /b output.js+.\jsfunfuzz\test-misc.js output.js

copy /b output.js+.\jsfunfuzz\driver.js output.js

copy /b output.js+.\jsfunfuzz\run-reduction-marker.js output.js

copy /b output.js+.\jsfunfuzz\run-in-sandbox.js output.js
copy /b output.js+.\jsfunfuzz\run.js output.js
copy /b output.js+.\jsfunfuzz\tail.js output.js

找到对应文件,把它们全部拷出来吧。然后,在v8或者chakracore中直接跑就可以了。什么,spidermonkey shell?no no,用户量太小了,并不想跑。

chakracore跑起来的壮观景象如下:

ch.jpg

当然,这个复现加跟踪啥的还是很麻烦的,我现在也打算做一个在线fuzz的接口,之后会开源一些工具和简单框架,这样,你就可以手动的fuzz+跟踪了,不用在VS中一遍遍的点着重启调试进程了:)。

注:grinder一样可以。只不过ie和edge在某种意义上,对ES6的支持并不好,你会看到各种奇妙的报错,如果你有兴趣,也可以做一些向下兼容的操作。