15年后:qmail中的远程代码执行

2020-05-20 23:43:25

@@-38,6+40,7@@#include";ip.h";#include";qmail-verify.h";#include";errbits.h";+#include";scan.h";#定义ENEW(){eout(";qmail-Verify:";);}}#定义GETPW_USERLEN 32@@-71,6+74。通信问题:正在退出。\n";);eflush();_exit(1);}void die_inuse(){ENEW();eout(";端口已在使用:正在退出。\n";);eflush();_exit(1);}void die_socket(){ENEW();eout(";设置套接字时出错:正在退出。\n";);eflush();eout(";无法删除/恢复权限:正在退出。\n";);eflush();_exit(1);}char*posstr(buf,status)char*buf;int status;@@-207,10+211,47@@return 0;}+static int stat_as(uid,gid,path,sbuf)+const uid_t uid;+const gid_t gid;+const。+const gid_t save_egid=getegid();+const uid_t save_euid=geteuid();+int ret=-1;++if(save_euid==0){+ngroup=getgroup(sizeof(Group)/sizeof(groups[0]),groups);+if(ngroup<;0|+setgroups(1,&;gid)!=0||+setegid(gid。++IF(SAVED_EUID==0){+IF(seteuid(SAVED_EUID)!=0||+setgid(SAVED_EGID)!=0||+setgroup(n group,groups)!=0){+die_Privs();+}+}++return ret;+}+int verifyaddr(Addr)char*addr;{char*home dir;+uid_t uid=-1;+gid_t。请注意,它们不需要重置,因为初始使用的总是stralloc_copys(),通配符除外(使用下面的.len=0重置)。*/@@-303,6+344,7@@if(r==1){char*x;+unsign long u;if(!stralloc_Ready(&;nughde,(Unsign Int)dlen))die_noem();nughde.len=dlen;if(cdb_baad(fd,nughde.s,nughde.len)==-1)die_cdb();@@-318,10+360,14@。/*跳过uid*/+scan_ulong(x,&;u);+uid=u;x+=byte_chr(x,nughde.s+nughde.len-x,';\0';);if(x==nughde.s+nughde.len)return allowaddr(addr,ADDR_OK|QVPOS4);++x;/*跳过gid*/+scan_ulong(x,\0';);if(x==nughde.s+nughde.len)return allowaddr(addr,ADDR_OK|QVPOS5);++x;@@-360,6+406,8@@if(!stralloc_copys(&;nughde,pw->;pw_dir))die_noem();if(!stralloc_0(&;nughde))die_noem();home dir。qme,&;safeext)die_noem();if(!stralloc_0(&;qme))die_noem();/*例如home dir/.qmail-localpart*/-if(stat(qme.s,&;st)==0)return allowaddr(addr,addr_OK|QVPOS10);+if(stat_as(uid,gid,qme.s,&;st)=。if(errno!=error_noent){return stat_error(qme.s,errno,STATERR|QVPOS11);/*可能未以root身份运行,因此拒绝访问*/}@@-394,7+442,7@@if(!stralloc_cat(&;qme,&;qme;default";))die_noem();if(!stralloc_0(&;QME))die_noem();/*。st)==0){+if(stat_as(uid,gid,qme.s,&;st)==0){/*如果它&39;s~alias/.qmail-default,则可选地检查aliases.cdb*/if(!i&;&;(quser==auto_usera)){char*s;@-423,6+471,7@@char*s;if(chdir(auto_qqs;if(control_rldef(&;envnoathost,&;control/envnoathost&34;,1,";envnoathost";)!=1)die_control();