Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
»ùÓÚChakra JITµÄCFGÈÆ¹ý¼¼Êõ
 
×÷Õߣºshan66 À´Ô´£ºtheori.io ·¢²¼ÓÚ£º 2017-1-23
  2251  次浏览      28

ÒýÑÔ

ÔÚ±¾ÎÄÖУ¬ÎÒÃǽ«Ïò¶ÁÕß½éÉÜÔÚ¹¥»÷Internet ExplorerºÍEdgeä¯ÀÀÆ÷ʱ¿ÉÓÃÓÚÈÆ¹ýMicrosoftµÄ¿ØÖÆÁ÷·À»¤(CFG)µÄ·½·¨¡£ÎÒÃÇÒÔǰµÄ¸ÅÄîÑéÖ¤ÐÔÖʵÄ©¶´ÀûÓôúÂëÊÇͨ¹ý¸²¸Ç¶ÔÏóµÄº¯ÊýÖ¸ÕëÀ´ÊµÏֵġ£µ«ÊÇ£¬µ±Óöµ½CFGʱ£¬ÕâÖÖ·½·¨¾Í²»Ì«ºÃʹÁË¡£ÎÒÃǼÙÉè¹¥»÷ÕßÒѾ­»ñµÃÁ˶ÁдÄÚ´æÈ¨ÏÞ¡£

±³¾°ÖªÊ¶

CFGÊÇ΢Èí½üÀ´ÎªWindowsϵͳÌí¼ÓÒ»ÖÖ°²È«·À»¤»úÖÆ¡£¸Ã»úÖÆÍ¨¹ý¼ä½Óµ÷ÓÃ/Ìø×ªÖ¸ÁîµÄÄ¿±êµØÖ·µÄ¸ßЧ¼ì²éÀ´Ìṩ±£»¤¡£Èç¹ûÄúÏ£Íû½øÒ»²½Á˽âCFGµÄ¸ü¶àÏêÇ飬¿ÉÒÔ²ÎÔIJο¼ÎÄÏ×[1][2][3]£¬ËùÒÔÎÒÃDz»×öÉîÈëϸÖµĽ²½â¡£

ËäÈ»¸Ã»º½â»úÖÆÔö¼ÓÁË¿ØÖÆÁ÷½Ù³ÖÐ͹¥»÷µÄÄѶȣ¬µ«ÊÇCFG±¾Éí²¢²»ÍêÃÀ¡£¸Ã¼¼ÊõµÄÉè¼ÆÄ¿±êÊDZ£»¤¼ä½Óµ÷ÓúÍÌø×ª£¬ËùÒÔ£¬Ã»ÓÐΪ¶ÑÕ»(¼´ROPÈÔÊÇ¿ÉÄܵÄ)Ìṩ±£»¤¡£´ËÍ⣬ֵµÃ×¢ÒâµÄÊÇ£¬ÕâÊÇÒ»¸ö±àÒëʱ²å×®¼¼Êõ£¬ÐèÒªÖØÐ±àÒëÔ´´úÂë¡£¾¡¹Ü΢ÈíÏÖÔÚµÄÐí¶à¶þ½øÖÆÎļþ¿ÉÒÔÊÜÒæÓÚCFG£¬µ«»¹ÓкܶàÆäËû³ÌÐò²»ÊÇÀûÓÃCFG±£»¤»úÖÆ±àÒëµÄ¡£

Chakra JIT

Chakra JIT¸ºÔðΪ¶à´Îµ÷Óõĺ¯ÊýºÍÑ­»·Éú³ÉÓÅ»¯µÄJIT´úÂë¡£Õâ¸ö¹ý³Ì·ÖΪ¶à¸ö½×¶ÎÍê³É£¬ÆäÖÐFull JIT CompilerºÍGarbage Collection½×¶ÎÊÇÔÚºǫ́Ïß³ÌÖнøÐеġ£Èç¹ûÄúÓÐÐËȤµÄ»°£¬¿ÉÒÔ´ÓMSDNÉÏÕÒµ½Ïà¹ØµÄ¹¤×÷Á÷³ÌºÍ¸÷ÖÖͼÊÍ¡£

JIT¹¤×÷Á÷³Ì

ÎÒÃǹØ×¢µÄÖØµãÊÇFull JIT Compiler½×¶Î£¬Ëü¸ºÔð»ñÈ¡×Ö½ÚÂëºÍÊä³ö±¾µØ´úÂë¡£Õë¶Ôµ¥¸öº¯Êý»òÑ­»·µÄ¸ß¼¶´¦ÀíÊÇÔÚFunc::Codegen()ÖнøÐеġ£Ê×ÏÈ£¬Ëü»áÉú³É×Ö½ÚÂëµÄÖмä±íʾ(IR)¡£È»ºó£¬ÕâЩIR½«±»×ª»»Èô¸É´Î£ºÓÅ»¯¡¢¼Ä´æÆ÷·ÖÅä¡¢prologºÍepilogµÈ¡£Ò»µ©IR×¼±¸¾ÍÐ÷£¬¾Í»á±»Encoder::Encode()±àÂëΪ±¾µØ´úÂë¡£

// https://github.com/Microsoft/
ChakraCore/blob/master/lib/Backend/Encoder.cpp#L15
void
Encoder::Encode()
{
NoRecoverMemoryArenaAllocator localAlloc(_u
("BE-Encoder"), m_func->m_alloc->
GetPageAllocator(), Js::Throw::OutOfMemory);
m_tempAlloc = &localAlloc;
...
m_encodeBuffer = AnewArray(m_tempAlloc,
BYTE, m_encodeBufferSize);
...
}

ʵ¼ÊÉÏ£¬ÕæÕýÉú³Éʵ¼Ê±¾µØ´úÂëµÄÈÎÎñÊÇÓÉEncoderÍê³ÉµÄ¡£Ê×ÏÈ£¬Ëü»á·ÖÅäm_encodeBufferÀ´ÁÙʱ´æ·Å±¾µØ´úÂë¡£µ±ËùÓб¾µØÖ¸Áî±»·¢Ë͵½m_encodeBufferÖ®ºó£¬Encoder½«¶Ô¸Ã»º³åÇø½øÐÐÖØÐ¶¨Î»£¬½«Æä¸´ÖƵ½read-only-executeÄڴ棬²¢°´ÕÕCFGµÄÒªÇó´¦Àíµ÷ÓÃÄ¿±ê¡£´Ëʱ£¬¸ÃÁÙʱ»º³åÇø¾Í²»ÔÙʹÓã¬ËùÒÔ¿ÉÒÔÊÍ·ÅÁË¡£

// https://github.com/Microsoft/
ChakraCore/blob/master/lib/Backend/Encoder.cpp#L294
...
m_encoderMD.ApplyRelocs((size_t) workItem->GetCodeAddress());
workItem->RecordNativeCode(m_func, m_encodeBuffer);
m_func->GetScriptContext()->GetThreadContext()->
SetValidCallTargetForCFG((PVOID) workItem->GetCodeAddress());
...

×¢Ò⣬һµ©´úÂë±»¸´ÖƵ½¿ÉÖ´ÐÐÄÚ´æºó£¬¾ÍºÜÄÑÐÞ¸ÄÁË¡£µ«ÊÇ£¬µ±EncoderÔÚÕâ¸öÁÙʱ»º³åÆ÷ÖÐÉú³É±¾µØ´úÂëʱ£¬ÊÇÎÞ·¨·ÀÖ¹¹¥»÷ÕßÀûÓÃдÈëÄÚ´æÈ¨ÏÞÀ´¸ü¸ÄÁÙʱ»º³åÆ÷ÖеĴúÂëµÄ¡£ÓÉÓÚJIT½ø³ÌλÓÚºǫ́Ïß³ÌÖУ¬ËùÒÔJavaScriptÏß³ÌÈÔÈ»¿ÉÒÔÕý³£ÔËÐС£¹¥»÷ÕßµÄÄѵãÊÇÕÒµ½¸ÃÁÙʱ»º³åÇø£¬²¢ÔÚEncoderÔËÐеļ«¶Ìʱ¼äÄÚÍê³ÉÏàÓ¦µÄÐÞ¸ÄÈÎÎñ¡£

ÈÆ¹ýCFG·À»¤

¼ÈÈ»ÒѾ­ÖªµÀÁËÐÞ¸ÄJIT´úÂëµÄ»ù±¾·½·¨£¬ÏÂÃæ¾ÍÈÃÎÒÃǸ¶ÖîÐж¯£¬ÒÔ±ãÉè·¨ÈÆ¹ýCFG¡£

ÎÒÃǵĹý³Ì·ÖΪÈý²½£º

´¥·¢JIT¡£

²éÕÒÁÙʱµÄ±¾µØ´úÂ뻺³åÇø¡£

Ð޸Ļº³åÇøµÄÄÚÈÝ¡£

µ±È»£¬ÕâÀïÒþº¬µÄ×îºóÒ»²½ÊÇÖ´ÐÐJIT´¦Àí¹ýµÄ´úÂë¡£

´¥·¢JIT

µÚÒ»²½£¬Ò²ÊÇ×î¼òµ¥µÄÒ»²½£¬¾ÍÊÇ´¥·¢JIT£¬ÈÃËü¿ªÊ¼¶ÔÒ»¸öº¯Êý½øÐбàÂ롣ΪÁËʹµÚ¶þ²½±äµÃ¸üÈÝÒ×һЩ£¬ÎÒÃÇÏ£Íûº¯ÊýµÄ´úÂë¶àһЩ£¬ÒÔ±ãÎÒÃÇÓÐ×ã¹»µÄʱ¼äÔÚÄÚ´æÖÐѰÕÒ¸ÃÁÙʱ»º³åÇø¡£µ±È»£¬º¯ÊýÖеľßÌåÖ¸ÁîÊÇÎ޹ؽôÒªµÄ¡£

var code = "var i = 10; var j = 1; "; 
for (var i = 0; i < 6000; i++)
{
code += "i *= i + j.toString();";
}
code += "return i.toString();"
f = Function(code);
for (var i = 0; i < 1000; i++)
{
// trigger jit
f.call();
}

²éÕÒ±¾»ú´úÂ뻺³åÇø

Ò»µ©ºǫ́Ï߳̽øÈëEncoder::Encode()£¬ÎÒÃÇÐèÒª¿ìËÙÕÒµ½ÁÙʱ±¾µØ´úÂ뻺³åÇø¡£·¢ÏÖ»º³åÇøµÄÒ»ÖÖ·½·¨ÊÇ£¬ÕÒµ½¸ø¸Ã»º³åÇø·ÖÅäÄÚ´æµÄÒ³·ÖÅäÆ÷£¬È»ºóÖð¸ö²é¿´Ëü·ÖÅäµÄÄÚ´æ¶Î¡£ÎÒÃÇ×¢Òâµ½£¬¿ÉÒÔÏÈÕÒµ½ThreadContext£¬È»ºóÕÒµ½¸Ãºǫ́Ï̵߳ÄBackgroundJobProcessor£¬ÕâÑù¾Í¿ÉÒÔÕÒµ½¸ÃÒ³Ãæ·ÖÅäÆ÷µÄÒýÓÃÁË¡£

// find the ThreadContext using ThreadContext::globalListLast 
var tctx = readN(jscript9Base + 0x00349034, 4);
// BackgroundJobProcessor
var bgjob = readN(tctx + 0x3b0, 4);
// PageAllocator
var pgalloc = bgjob + 0x1c;

PageAllocator¾ßÓÐÈô¸ÉÒÑ·ÖÅä¶ÎµÄÁÐ±í¡£ÓÉÓÚ¾­JIT´¦Àí¹ýµÄº¯Êý»á±ä´ó£¬ËùÒÔ¸ÃÁÙʱ±¾µØ´úÂ뻺³åÆ÷Ò²½«ºÜ´ó¡£ËùÒÔ£¬Í¨¹ý¼ì²élargeSegmentsÁÐ±í£¬ÎÒÃǾͿÉÒÔÇáËÉÕÒµ½¸ÃÄÚ´æ¶ÎÁË¡£ÎÒÃÇ¿ÉÒÔʹÓÃÒ»¸öwhileÑ­»·£¬ÕâÑùÒ»Ö±µÈµ½Õâ¸ölargeSegmentsÁбí±äΪ·Ç¿Õ£¬È»ºó½øÈë×îºóÒ»²½¡£

while (true) { 
// read largeSegments list
var largeseg = readN(pgalloc + 0x24, 4);
// check if the list was empty
if (largeseg == pgalloc + 0x24) continue;
// get the address of the actual data
var page = readN(largeseg + 8 + 8, 4);
if (page == 0) continue;
break;
}

Ð޸IJ¢ÔËÐÐ

ÏÖÔÚ£¬¼ÈÈ»ÒѾ­ÖªµÀÁËÁÙʱ±¾µØ´úÂ뻺³åÇøµÄλÖã¬ÄÇô½ÓÏÂÀ´¾Í¿ÉÒÔÐÞ¸ÄÆäÄÚÈÝÀ´×¢ÈëshellcodeÁË¡£µ±È»£¬°´Àí˵ֻҪʹÓÃÎÒÃǵÄshellcode¸²¸Ç»º³åÇøµÄÄÚÈݾÍÐÐÁË£¬µ«ÊÇʵ¼ÊÉÏÒª±ÈÕâ¸ö¹ý³ÌÒª¸´ÔӵĶ࣬ÒòΪÎÒÃDZØÐë±ÜÃ⸲¸ÇδÀ´ÔÚÖØ¶¨Î»²½ÖèÖн«ÒªÐ޸ĵÄÈκÎÄÚÈÝ¡£ÒòΪÓÃÓÚ´¥·¢JITµÄº¯ÊýÐèÒª¶à´Îµ÷ÓÃtoString()£¬Í¬Ê±»¹Òª±ÜÃâÖØ¶¨Î»µÄÓ°Ï죬ËùÒÔ£¬Êµ¼ÊÉÏ¿ÉÓÃÓÚshellcodeµÄ¿Õ¼ä²¢²»³äÔ£¡£

ËäÈ»×î¼Ñ֮ѡÊÇÐÞ¸ÄÒª½øÐÐJIT´¦ÀíµÄº¯Êý£¬µ«ÕâÀïÑ¡ÔñʹÓÃfirst-stage shellcode£¬ËüÖ»ÊǼòµ¥µ÷ÓÃVirtualProtect£¬È»ºóÌø×ªµ½ÎÒÃǵÄsecond-stage shellcode¡£Õâ¸öfirst-stage shellcodeͨ³£ÊǷdz£Ð¡(Ö»ÓÐ20¸ö×Ö½Ú)µÄ¡£ËùÒÔ £¬ÎÒÃÇ¿ÉÒÔ°Ñfirst-stage shellcode·Åµ½¾àÕâ¸ö»º³åÇø±È½Ï½üµÄµØ·½£¬È»ºóÔÚÕâ¸ö»º³åÇøµÄÆðʼλÖ÷ÅÉÏÒ»¸ö½ü×ªÒÆÖ¸Á´Ó¶øÌø×ªÖÁ¸Ã´úÂë¡£

ÕâÑùµÄ»°£¬ÎÒÃǵÄsecond-stage shellcode¿ÉÒÔÊÇÈκγ¤¶È£¬ËùÒÔÔÚÎÒÃǵÄ©¶´ÀûÓôúÂëÖУ¬Ê¹ÓÃÁËÒ»¸ömetasploitÉú³ÉshellcodeÀ´Ö´ÐÐnotepad.exe¡£Êµ¼ÊÉÏ£¬Õâ¸ösecond-stage shellcode»¹¿ÉÒÔÈÆ¹ý±£»¤Ä£Ê½(ɳÏä)¡£

ÔÚÐ޸ĺÃÁÙʱ»º³åÇøÖ®ºó£¬ÎÒÃǽ«½øÈë×îºóÒ»²½£¬¾ÍÊǽøÐеȴý£¬Ö±µ½JIT´¦ÀíÍê³É²¢Ö´ÐÐÐ޸ĺóµÄJIT´úÂ롣Ϊ´Ë£¬Äã¿ÉÒÔ²»¶Ïµ÷ÓÃÄ¿±êº¯Êý£¬Ö±µ½ÄãµÄshellcodeµÃµ½Ö´ÐÐΪֹ¡£

for (var i = 0; i < 1000; i++) 
{
// call overwritten jit block
f.call();
}

©¶´ÀûÓÃ

ΪÁËÑÝʾÕâÖÖÈÆ¹ý¼¼Êõ£¬ÎÒÃÇ½è¼øÁË´ËǰÓÃÓÚWindows 10ÉϵÄInternet Explorer 11µÄÀûÓôúÂ룬²¢½øÐÐÁËÏàÓ¦µÄÐ޸ġ£ÆäÖУ¬»ñÈ¡¶ÁдÄÚ´æÈ¨Ï޵ĴúÂëûÓиı䣬µ«ÊÇÔÚÖ´ÐÐÎÒÃǵÄshellcodeµÄʱºò£¬Ê¹ÓõÄÊÇJIT´úÂ븲¸Ç¼¼Êõ£¬¶ø²»ÊÇÈ¥¸²¸Ç´¥·¢CFGµÄº¯ÊýÖ¸Õë¡£

Äã¿ÉÒÔÔÚhttps://github.com/theori-io/jscript9-typedarray-cfgÒ³ÃæÖÐÕÒµ½×îÖյĸÅÄîÑé֤©¶´ÀûÓôúÂë¡£

°²È«Ó°Ïì

ÓÉÓÚ¸ÃCFGÈÆ¹ý©¶´µÄÓ°Ïì½öÏÞÓÚ¹¥»÷ÕßÒѾ­»ñµÃÁ˶ÁдÄÚ´æÈ¨ÏÞµÄÇé¿ö£¬Òò´ËÆäʵÓÃÐÔÔÚÏÖʵÖпÉÄÜ»áÊܵ½Ò»Ð©ÏÞÖÆ¡£ÐèÒªÒýÆð¾¯¾õµÄÊÇ£¬Õâ¸öÈÆ¹ý·½·¨¾ßÓÐÄÚÖõ½Chakra JIT¼Ü¹¹ÄÚ²¿µÄÓÅÊÆ£¬ÕâÒâζ×ÅËü¿ÉÄܺÜÄÑÐÞ²¹£¬²¢ÇÒ²»»áÊܵ½ÏñÓ¢ÌØ¶ûµÄCETÕâÑùµÄδÀ´»º½â´ëÊ©µÄÓ°Ïì¡£

²¹¾È´ëÊ©

΢ÈíÒѾ­³Ðŵ¶ÔChakraCore½øÐÐÏàÓ¦µÄÐ޸ģ¬ÒÔ»º½âÎÒÃÇ·¢ÏÖµÄCFGÈÆ¹ý(ÒÔ¼°ÆäËûCVE²¹¶¡)©¶´ËùÔì³ÉµÄÍþв¡£ËûÃǵĻù±¾Ë¼ÏëÊÇ£¬ÔÚ±àÂëÆ÷±àÂëÖ¸Áîʱ¼ÆËãУÑéºÍ£¬È»ºóÔÚ½«Õû¸ö»º³åÇø¸´ÖƵ½×îÖÕµÄRX(read/execute-only)»º³åÇøÖ®ºó¶ÔУÑéºÍ½øÐÐÑéÖ¤¡£²¢ÇÒ£¬Ö»ÓÐͨ¹ýÑéÖ¤ºó£¬JIT´¦ÀíºóµÄ´úÂëµÄÈë¿Úµã²ÅÄÜ×÷ΪÓÐЧµÄCFGÄ¿±ê¡£ÕâÀïµÄÑ¡ÔñµÄУÑéºÍËã·¨ÊÇCRC32¡£

   
2251 ´Îä¯ÀÀ       28
 
Ïà¹ØÎÄÕÂ

iOSÓ¦Óð²È«¿ª·¢£¬Äã²»ÖªµÀµÄÄÇЩÊÂÊõ
Web°²È«Ö®SQL×¢Èë¹¥»÷
ÒÆ¶¯APP°²È«ÔÚÉøÍ¸²âÊÔÖеÄÓ¦ÓÃ
´ÓGoogle±¸·Ý»¥ÁªÍø¿´¡°Êý¾Ý°²È«¡±
 
Ïà¹ØÎĵµ

web°²È«Éè¼ÆÓë·À»¤
»¥ÁªÍøº£Á¿ÄÚÈݰ²È«´¦Àí¼¼Êõ
ºÚ¿Í¹¥»÷Óë·À·¶¼¼Êõ
WEBºÚºÐ°²È«¼ì²â
 
Ïà¹Ø¿Î³Ì

WEBÍøÕ¾ÓëÓ¦Óð²È«Ô­ÀíÓëʵ¼ù
webÓ¦Óð²È«¼Ü¹¹Éè¼Æ
´´½¨°²È«µÄJ2EE WebÓ¦ÓôúÂë
ÐÅÏ¢°²È«ÎÊÌâÓë·À·¶
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

iOSÓ¦Óð²È«¿ª·¢
Web°²È«Ö®SQL×¢Èë¹¥»÷
APP°²È«ÔÚÉøÍ¸²âÊÔÖеÄÓ¦ÓÃ
³õ̽PHPµÄSQL×¢Èë¹¥»÷µÄ¼¼Êõ
´ÓGoogle±¸·Ý¿´¡°Êý¾Ý°²È«¡±

WEBÍøÕ¾ÓëÓ¦Óð²È«Ô­ÀíÓëʵ¼ù
webÓ¦Óð²È«¼Ü¹¹Éè¼Æ
´´½¨°²È«µÄJ2EE WebÓ¦ÓôúÂë
×¢²áÐÅÏ¢°²È«×¨ÒµÈËÔ±(CISP)
ÐÅÏ¢°²È«¹ÜÀí
ÐÅÏ¢°²È«ÎÊÌâÓë·À·¶

ÖйúÒøÐÐ ÐÅÏ¢°²È«¼¼Êõ¼°Éî¶È·ÀÓù
WebÓ¦Óð²È«¼Ü¹¹¡¢ÈëÇÖ¼ì²âÓë·À»¤
ij²ÆË°ÁìÓòÖªÃûIT·þÎñÉÌ Web°²È«²âÊÔ
ÆÕÈð¿Ë˹ web°²È«Éè¼Æ¡¢²âÊÔÓëÓÅ»¯
±±¾©ºÍÀûʱ ÐÔÄܺͰ²È«ÐÔ²âÊÔ
SUNÖйú¹¤³ÌÑо¿Ôº JSF¿ò¼Ü¡¢°²È«