============================================ Linux Kernel Memory Disclosure Ãë¾à¼ºÀÇ ±âÃÊ by hkpco(¹ÚÂù¾Ï) ------------------------------- mail - chanam.park@hkpco.kr homepage - http://hkpco.kr/ date - 2009. 1. 5 ------------------------------- ============================================ 1. ¼­·Ð º» ¹®¼­¿¡¼­´Â Linux Kernel Memory Disclosure Ãë¾à¼º(ÀÌÇÏ Ä¿³Î ¸Þ¸ð¸® ´©Ãâ Ãë¾à¼º)ÀÇ ±âÃÊ¿¡ ´ëÇØ ¼³¸íÇÏ°íÀÚ ÇÑ´Ù. ÀÌ´Â ºñ·Ï Ä¿³Î ·¹º§¿¡¼­ÀÇ Ãë¾à¼ºÀÌÁö¸¸ Àü¹ÝÀûÀ¸·Î »ó´çÈ÷ ½¬¿î °³³ä¿¡ ¼ÓÇϸç Ä¿³ÎÀ̶ó´Â »ý¼ÒÇÔ ¶ÇÇÑ Å©°Ô ´À³¥ ¼ö ¾øÀ» °ÍÀÌ´Ù. ÇØ´ç Ãë¾à¼ºÀº ·çÆ® ±ÇÇÑÀ» ȹµæÇÒ ¸¸Å­ÀÇ Á÷Á¢ÀûÀÎ À§Ç輺Àº Áö´Ï°í ÀÖÁö ¾ÊÁö¸¸ ¸Þ¸ð¸® »ó¿¡ Á¸ÀçÇÏ´Â Æнº¿öµå¿Í °°Àº Áß¿äÇÑ µ¥ÀÌÅ͸¦ ȹµæÇÒ ¼ö ÀÖ´Â °£Á¢ÀûÀÎ À§Ç輺Àº ÃæºÐÇÏ´Ù. ±â¹ý¿¡ ´ëÇÑ ¼³¸íÀº ½ÇÁ¦ ¹ßÇ¥µÈ Ãë¾à¼ºÀ» ÅëÇØ ÁøÇàÇÒ °ÍÀ̸ç, ¸¶Ä§ ÃÖ±Ù¿¡ °ø°³µÈ ½¬¿î ´ë»óÀ» ãÀ» ¼ö ÀÖ¾ú´Ù. 2. Ãë¾à¼º ¼³¸í º» ¹®¼­ÀÇ ¸Þ¸ð¸® ´©Ãâ Ãë¾à¼º ºÐ¼®À» À§ÇÏ¿© Âü°íÇÏ´Â Ä¿³Î ¼Ò½º ÄÚµåÀÇ ¹öÀüÀº 2.6.26 ÀÌ¸ç ¼³¸íÀ» À§ÇÑ ´ë»óÀº Linux Kernel SCTP-AUTH API ¿¡¼­ ¹ß»ýÇÏ´Â Ä¿³Î ¸Þ¸ð¸® ´©Ãâ Ãë¾à¼ºÀ¸·Î ÀÌ¿¡ ´ëÇÑ ¸µÅ©´Â ´ÙÀ½¿¡¼­ È®ÀÎÇÒ ¼ö ÀÖ´Ù. ( Link: http://www.securityfocus.com/archive/1/archive/1/496256/100/0/threaded ) ÀϹÝÀûÀ¸·Î Ä¿³Î ¸Þ¸ð¸® ´©Ãâ Ãë¾à¼ºÀº Ä¿³Î¿¡¼­ À¯Àú ·¹º§À¸·Î µ¥ÀÌÅ͸¦ º¹»çÇÏ´Â °úÁ¤¿¡¼­ ±æÀÌ Ã¼Å©ÀÇ °á¿©, Á¤¼öÇü ¿À¹öÇ÷οì, Æ÷ÀÎÅÍ Á¦¾î»óÀÇ ¹®Á¦Á¡ µî¿¡ ÀÇÇÏ¿© ¹ß»ýÇÑ´Ù. ´ÙÀ½Àº Ãë¾àÇÑ ÇÔ¼öÀÎ sctp_getsockopt_hmac_ident()ÀÇ ÄÚµåÀÌ´Ù. ~ 5053 static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, 5054 char __user *optval, int __user *optlen) 5055 { 5056 struct sctp_hmac_algo_param *hmacs; 5057 __u16 param_len; 5058 5059 hmacs = sctp_sk(sk)->ep->auth_hmacs_list; 5060 param_len = ntohs(hmacs->param_hdr.length); 5061 5062 if (len < param_len) 5063 return -EINVAL; 5064 if (put_user(len, optlen)) 5065 return -EFAULT; 5066 if (copy_to_user(optval, hmacs->hmac_ids, len)) 5067 return -EFAULT; 5068 5069 return 0; 5070 } ~ 5062 ¶óÀÎÀ» º¸°ÔµÇ¸é, 16bit º¯¼öÀÎ param_len°ú 32bit º¯¼öÀÎ lenÀ» ºñ±³ÇÏ°í ÀÖ´Ù. ±×·± ´ÙÀ½ 5064 ¶óÀο¡¼­ put_user() ¸ÅÅ©·Î¸¦ ÅëÇØ lenÀÇ °ªÀ» »ç¿ëÀÚ ¿µ¿ª º¯¼öÀÎ optlen¿¡ ÀúÀåÇϴµ¥ ÀÌ´Â ÀÌÈÄ¿¡ º¹»çÇÒ µ¥ÀÌÅÍÀÇ Å©±â¿Í µ¿ÀÏÇÏ´Ù. ¸¶Áö¸·À¸·Î 5066 ¶óÀο¡¼­ copy_to_user() ÇÔ¼ö¸¦ ÅëÇÏ¿© Ä¿³Î ¿µ¿ªÀÇ µ¥ÀÌÅÍÀÎ hmacs->hmac_ids¸¦ lenÀÇ Å©±â¸¸Å­ »ç¿ëÀÚ ¿µ¿ª °ø°£ÀÎ optval¿¡ ÀúÀåÇÑ´Ù. ¿©±â¼­ ¸¸¾à º¯¼ö lenÀÇ °ªÀ» ÀÓÀÇ·Î Á¶ÀÛ °¡´ÉÇÏ´Ù¸é hmacs->hmac_idsº¸´Ù ÈξÀ Å« ±æÀ̸¦ Àü´ÞÇÏ¿© ÀǵµÇÏÁö ¾ÊÀº Ä¿³Î ¸Þ¸ð¸® ´©Ãâ Ãë¾à¼ºÀ» ¹ß»ý½Ãų ¼ö ÀÖ´Ù. ¸¶Ä§ 32bit º¯¼ö lenÀ» 16bit º¯¼ö¿Í ºñ±³ÇÏ°í Àֱ⠶§¹®¿¡ lenÀÇ °ªÀÌ 16bit º¸´Ù Å©´Ù¸é 5062 ¶óÀÎÀÇ Ã¼Å©´Â ¹«Á¶°Ç Åë°ú°¡ °¡´ÉÇÒ °ÍÀÌ´Ù. ±×·¸´Ù¸é ÀÌÁ¦ sctp_getsockopt_hmac_ident() ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ·çƾÀ» »ìÆ캸µµ·Ï ÇÏÀÚ. ´ÙÀ½Àº sctp_getsockopt() ÇÔ¼ö ÄÚµåÀÇ ÀϺκÐÀ¸·Î½á Ãë¾àÇÑ ÇÔ¼öÀÎ sctp_getsockopt_hmac_ident()¸¦ È£ÃâÇÏ´Â ·çƾÀ» Æ÷ÇÔÇÏ°í ÀÖ´Ù. ~ 5175 SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, 5176 char __user *optval, int __user *optlen) 5177 { 5178 int retval = 0; 5179 int len; 5180 5181 SCTP_DEBUG_PRINTK("sctp_getsockopt(sk: %p... optname: %d)\n", 5182 sk, optname); 5183 5184 /* I can hardly begin to describe how wrong this is. This is 5185 * so broken as to be worse than useless. The API draft 5186 * REALLY is NOT helpful here... I am not convinced that the 5187 * semantics of getsockopt() with a level OTHER THAN SOL_SCTP 5188 * are at all well-founded. 5189 */ 5190 if (level != SOL_SCTP) { 5191 struct sctp_af *af = sctp_sk(sk)->pf->af; 5192 5193 retval = af->getsockopt(sk, level, optname, optval, optlen); 5194 return retval; 5195 } 5196 5197 if (get_user(len, optlen)) 5198 return -EFAULT; 5199 5200 sctp_lock_sock(sk); 5201 5202 switch (optname) { 5203 case SCTP_STATUS: 5204 retval = sctp_getsockopt_sctp_status(sk, len, optval, optlen); 5205 break; 5206 case SCTP_DISABLE_FRAGMENTS: 5207 retval = sctp_getsockopt_disable_fragments(sk, len, optval, 5208 optlen); 5209 break; . . . 5303 case SCTP_HMAC_IDENT: 5304 retval = sctp_getsockopt_hmac_ident(sk, len, optval, optlen); 5305 break; 5306 case SCTP_AUTH_ACTIVE_KEY: 5307 retval = sctp_getsockopt_active_key(sk, len, optval, optlen); 5308 break; 5309 case SCTP_PEER_AUTH_CHUNKS: 5310 retval = sctp_getsockopt_peer_auth_chunks(sk, len, optval, 5311 optlen); 5312 break; 5313 case SCTP_LOCAL_AUTH_CHUNKS: 5314 retval = sctp_getsockopt_local_auth_chunks(sk, len, optval, 5315 optlen); 5316 break; 5317 default: 5318 retval = -ENOPROTOOPT; 5319 break; 5320 } 5321 5322 sctp_release_sock(sk); 5323 return retval; 5324 } ~ Âü°í·Î »ç¿ëÀÚ ·¹º§¿¡¼­ ¼ÒÄÏ »ý¼º ½Ã socket() ÇÔ¼öÀÇ ¼¼ ¹ø° ÀÎÀÚÀÎ ÇÁ·ÎÅäÄÝÀ» IPPROTO_SCTP·Î ¼³Á¤ÇÑ ´ÙÀ½ getsockopt() ½Ã½ºÅÛ ÄÝÀ» »ç¿ëÇϸé Ä¿³Î ·¹º§ÀÇ sctp_getsockopt() ÇÔ¼ö°¡ È£ÃâµÈ´Ù. ¶ÇÇÑ »ç¿ëÀÚ ¿µ¿ª¿¡¼­ »ç¿ëÇÏ´Â getsockopt() ½Ã½ºÅÛ ÄÝÀÇ ÀÎÀÚ¿Í Ä¿³Î ·¹º§ÀÇ sctp_getsockopt() ÇÔ¼öÀÇ ÀÎÀÚ°¡ °ÅÀÇ µ¿ÀÏÇϱ⠶§¹®¿¡ ÇØ´ç ÇÔ¼öÀÇ ÀÎÀÚ´Â ´ëºÎºÐ »ç¿ëÀÚ ¿µ¿ª¿¡¼­ ÀÓÀÇ·Î Á¶ÀÛÀÌ °¡´ÉÇÏ´Ù°í º¸¸éµÈ´Ù. 5304 ¶óÀÎÀ» º¸°ÔµÇ¸é Ãë¾àÇÑ ÇÔ¼öÀÎ sctp_getsockopt_hmac_ident()¸¦ È£ÃâÇÏ°í ÀÖ´Ù. ÇØ´ç ÄÚµå±îÁö µµ´ÞÇϱâ À§Çؼ­´Â ¿ì¼± sctp_getsockopt() ÇÔ¼öÀÇ µÎ ¹ø° ÀÎÀÚÀÎ levelÀÇ °ªÀ» SOL_SCTP·Î ¼³Á¤ÇÏ¿© 5190 ¶óÀÎÀÇ Ã¼Å© ±¸¹®À» Åë°úÇØ¾ß ÇÑ´Ù. ±×·± ´ÙÀ½ 5197 ¶óÀο¡¼­ »ç¿ëÀÚ ¿µ¿ªÀÇ °ªÀÎ optlenÀ» Ä¿³Î º¯¼ö len¿¡ ÀúÀåÇϴµ¥, ÀÌ´Â ÀÌÈÄ¿¡ Ãë¾àÇÑ ÇÔ¼öÀÇ len º¯¼ö·Î Àü´ÞµÇ±â ¶§¹®¿¡ ÀÌÀü¿¡ ¼³¸íÇßµíÀÌ 16bitº¸´Ù Å« °ªÀ» ¼³Á¤ÇÏ¸é µÈ´Ù. ÀÌÁ¦ ÃÖÁ¾ÀûÀ¸·Î Ãë¾àÇÑ ÇÔ¼ö¸¦ È£ÃâÇϱâ À§ÇÏ¿© ¼¼ ¹ø° ÀÎÀÚÀÎ optnameÀÇ °ªÀ» SCTP_HMAC_IDENTÀ¸·Î ¼³Á¤ÇØ ÁÖ¸é ¿ì¸®°¡ ÇÊ¿äÇÑ ¸ðµç ÀÛ¾÷ÀÌ ³¡³ª°Ô µÈ´Ù. 3. ÀͽºÇ÷ÎÀÕ ÀÌÁ¦ ÇØ´ç Ãë¾à¼ºÀ» Àû¿ëÇÒ ÀͽºÇ÷ÎÀÕ¿¡ ´ëÇØ °£´ÜÈ÷ »ìÆ캸°Ú´Ù. milw0rm¿¡ °ø°³µÈ ÀͽºÇ÷ÎÀÕÀº ´ÙÀ½ ¸µÅ©¿¡¼­ È®ÀÎÇÒ ¼ö ÀÖ´Ù. ( Link - http://milw0rm.com/exploits/7618 ) ÀͽºÇ÷ÎÀÕÀÇ ¼öÇà °úÁ¤Àº Å©°Ô µÎ ºÎºÐÀ¸·Î ³ª´¶´Ù. ------------------------------------------------------ a. ¼ÒÄÏ »ý¼º(IPPROTO_SCTP) b. getsockopt() ½Ã½ºÅÛ ÄÝ È£ÃâÀ» ÅëÇÑ Ä¿³Î ¸Þ¸ð¸® ¿­¶÷ ------------------------------------------------------ º» ¹®¼­¿¡¼­ ºÐ¼®Çß´ø Ãë¾àÇÑ Ä¿³Î ÇÔ¼ö¸¦ ¾Ç¿ëÇϱâ À§ÇÑ getsockopt() ½Ã½ºÅÛ ÄÝÀÇ ÀÎÀÚ ±¸¼ºÀº ´ÙÀ½°ú °°´Ù. --------------------------------------------------------------------- s(arg1) : IPPROTO_SCTP ÇÁ·ÎÅäÄÝÀ» ±â¹ÝÀ¸·Î »ý¼ºÇÑ ¼ÒÄÏ ±â¼úÀÚ level(arg2) : SOL_SCTP optname(arg3) : SCTP_HMAC_IDENT optval(arg4) : Ä¿³Î ¸Þ¸ð¸®ÀÇ µ¥ÀÌÅ͸¦ ÀúÀåÇÒ ¹öÆÛ optlen(arg5) : 16bit º¸´Ù Å©°í 32bitº¸´Ù ÀÛÀº °ª --------------------------------------------------------------------- À§¿Í °°Àº Çü½ÄÀ¸·Î ÀͽºÇ÷ÎÀÕÀ» ±¸¼ºÇÏ°Ô µÇ¸é ³× ¹ø° ÀÎÀÚÀÎ optval¿¡ ´Ù¼¸¹ø° ÀÎÀÚÀÎ optlenÀÇ Å©±â ¸¸Å­ Ä¿³Î ¿µ¿ª ¸Þ¸ð¸®ÀÇ µ¥ÀÌÅÍ°¡ ÀúÀåµÉ °ÍÀÌ´Ù. ´ÙÀ½Àº ½ÇÁ¦ ÀͽºÇ÷ÎÀÕÀÇ ÇÙ½É ÄÚµåÀÌ´Ù. ~ . . #define DUMP_SIZE 256*1024 . . socklen_t memlen = DUMP_SIZE; . . sock = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); getsockopt(sock, SOL_SCTP, SCTP_HMAC_IDENT, memdump, &memlen); . . ~ 4. ¼Ö·ç¼Ç ¼Ö·ç¼Ç¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ¼³¸íÀº ·¹ÆÛ·±½º¸¦ Âü°íÇϱ⠹ٶõ´Ù. ¿©·¯°¡Áö ÄÚµå ¼öÁ¤ÀÌ ÀÌ·ç¾îÁ® ÀÖÁö¸¸ ÇÙ½ÉÀûÀÎ ³»¿ëÀº Ä¿³Î»óÀÇ µ¥ÀÌÅ͸¦ À¯Àú ¿µ¿ªÀ¸·Î º¹»çÇÒ ¶§ÀÇ ±æÀ̸¦ ÀÏ¹Ý »ç¿ëÀÚ°¡ ÀÓÀÇ·Î Á¶ÀÛÇÒ ¼ö ¾ø°Ô ÇÑ´Ù´Â °ÍÀÌ´Ù. ¸¸¾à Á¶ÀÛÀÌ °¡´ÉÇÏ´õ¶óµµ ƯÁ¤ Å©±â(¿¹¸¦µé¸é ±¸Á¶Ã¼ÀÇ Å©±â) ÀÌ»óÀÇ °ªÀÌ ÁÖ¾îÁ³´ÂÁö¸¦ üũÇØ¾ß ÇÑ´Ù. 5. ·¹ÆÛ·±½º http://milw0rm.com/exploits/7618 http://www.securityfocus.com/archive/1/archive/1/496256/100/0/threaded http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.26.y.git;a=commit;h=be9467bd75b522a3db0369c12db739f797cfec6a