00截断 java_Java写文件时文件名00截断 BUG

漏洞概要

缺陷编号:WooYun-2012-016537

漏洞标题:Java写文件时文件名00截断 BUG

相关厂商:java

漏洞作者:smartmice

提交时间:2012-12-26 21:30

公开时间:2012-12-26 21:30

漏洞类型:文件上传导致任意代码执行

危害等级:中

自评Rank:6

漏洞状态:未联系到厂商或者厂商积极忽略

Tags标签:

漏洞详情

披露状态:

2012-12-26: 积极联系厂商并且等待厂商认领中,细节不对外公开

2012-12-26: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

Java在上面两种环境写文件时,会因为00截断而无法正确为新生成的文件命名。比如用户需要的用户名abc.jsp .jpg,但经过00截断后,生成的文件的名称变为abc.jsp , 因此我们在涉及到上传的文件名没更改名称或者可自定义目录的时候加以利用

详细说明:

测试环境:1.windows7(x64)+tomcat7+jdk1.62.Linux3.0(ubuntu11.10)(x86)+tomcat7+jdk1.7Java在上面两种环境写文件时,会因为00截断而无法正确为新生成的文件命名。比如用户需要的用户名abc.jsp .jpg,但经过00截断后,生成的文件的名称变为abc.jsp , 因此我们在涉及到上传的文件名没更改名称或者可自定义目录的时候加以利用。测试发送的头部数据如下:

POST /simpleUpload/write.jsp HTTP/1.1

Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

Accept-Language: zh-cn

Content-Type: application/x-www-form-urlencoded

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)

Host: 192.168.200.142:8084

Content-Length: 17

Connection: Keep-Alive

Cache-Control: no-cache

Cookie: JSESSIONID=D2EC5F95AD581EB5FD3A860FC4CE640

1

2

3

4

5

6

7

8

9

10

11

POST/simpleUpload/write.jspHTTP/1.1

Accept:application/x-shockwave-flash,image/gif,image/x-xbitmap,image/jpeg,image/pjpeg,*/*

Accept-Language:zh-cn

Content-Type:application/x-www-form-urlencoded

Accept-Encoding:gzip,deflate

User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)

Host:192.168.200.142:8084

Content-Length:17

Connection:Keep-Alive

Cache-Control:no-cache

Cookie:JSESSIONID=D2EC5F95AD581EB5FD3A860FC4CE640

name=abc.jsp .jpg(注意在上传前,这里的空格需要我们用十六进制编辑器将其变为00)测试的服务端代码如下:

out.clear();

String filename = request.getParameter("name");

if (filename != null) {

String path = application.getRealPath("/");

String p=path + "/" + filename;

File uploadfile = new File(p);

if (!uploadfile.exists()) {

uploadfile.createNewFile();

}

out.println("System Name:"+System.getProperty("os.name"));

out.println("1.The information of UploadFile:");

if(uploadfile!=null){

out.println(" a.the UploadFile exists!");

out.println(" b.The path of UploadFile: "+uploadfile.getAbsolutePath());

out.println(" c.The name of UploadFile: "+uploadfile.getName());

p=uploadfile.getAbsolutePath().substring(0,uploadfile.getAbsolutePath().length()-5);

File bugFile=new File(p);

out.println("2.The information of BugFile:");

if(bugFile.exists()){

out.println(" a.The BugFile exists!");

out.println(" b.The path of BugFile: "+bugFile.getAbsolutePath());

out.println(" c.The name of BugFile: "+bugFile.getName());

}else{

out.println("The BugFile: "+bugFile+" does't exist!");

}

File uploadfile2 = new File(p+uploadfile.getAbsolutePath().substring(uploadfile.getAbsolutePath().length()-5));

out.println("3.Assure whether the nonexistent UploadFile exists because of the java API or not:");

if(uploadfile2.exists()){

out.println(" a.The nonexistent UploadFile exists!");

out.println(" b.The path of nonexistent UploadFile: "+uploadfile2.getAbsolutePath());

out.println(" c.The name of nonexistent UploadFile: "+uploadfile2.getName());

}else{

out.println("The nonexistent UploadFile: "+uploadfile2+" does't exist!");

}

}else

out.println("The UploadFile: "+uploadfile+" isn't uploaded successfully!");

} else {

out.println("Null name!");

}

out.flush();

%>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

out.clear();

Stringfilename=request.getParameter("name");

if(filename!=null){

Stringpath=application.getRealPath("/");

Stringp=path+"/"+filename;

Fileuploadfile=newFile(p);

if(!uploadfile.exists()){

uploadfile.createNewFile();

}

out.println("System Name:"+System.getProperty("os.name"));

out.println("1.The information of UploadFile:");

if(uploadfile!=null){

out.println("   a.the UploadFile  exists!");

out.println("   b.The path of UploadFile:    "+uploadfile.getAbsolutePath());

out.println("   c.The name of UploadFile:    "+uploadfile.getName());

p=uploadfile.getAbsolutePath().substring(0,uploadfile.getAbsolutePath().length()-5);

FilebugFile=newFile(p);

out.println("2.The information of BugFile:");

if(bugFile.exists()){

out.println("   a.The BugFile  exists!");

out.println("   b.The path of BugFile:    "+bugFile.getAbsolutePath());

out.println("   c.The name of BugFile:   "+bugFile.getName());

}else{

out.println("The BugFile: "+bugFile+"  does't exist!");

}

Fileuploadfile2=newFile(p+uploadfile.getAbsolutePath().substring(uploadfile.getAbsolutePath().length()-5));

out.println("3.Assure whether the nonexistent  UploadFile exists because of the java API or not:");

if(uploadfile2.exists()){

out.println("   a.The nonexistent  UploadFile  exists!");

out.println("   b.The path of nonexistent  UploadFile:    "+uploadfile2.getAbsolutePath());

out.println("   c.The name of nonexistent  UploadFile:   "+uploadfile2.getName());

}else{

out.println("The nonexistent  UploadFile: "+uploadfile2+" does't exist!");

}

}else

out.println("The UploadFile: "+uploadfile+"  isn't uploaded successfully!");

}else{

out.println("Null name!");

}

out.flush();

%>

漏洞证明:

1.在windows7(x64)+tomcat7+jdk1.6环境下提交的数据返回结果的截图:

7219d542de61b4d036bab7c49bb33244.png

2.在Linux3.0(ubuntu11.10)(x86)+tomcat7+jdk1.7环境下提交的数据返回结果的截图:

a754d40de334c6d5b0dfb910cb1d0266.png

从上图我们可以看到:1点成功了,表示文件已经上传成功了,并且文件名abc.jsp00.jpg没变,且java认为这个文件存在的。2点也成功了,表明 abc.jps存在.3我们用abc.jsp组全00.jpg去确认这个文件是否存在,结果java认为存在。注:(这里的00表示16进制字符)当我们打开对应的目录时,发现只有abc.jsp存在。这说明文件名00截断是JAVA的原因。而不是系统的原因。为了不让web shell由于这个漏洞而得以上传,推荐你使用fckeditor的方法,用一个正则表达式替换用户可以定义的路径名或者文件名,代码如下filename = filename.replaceAll("\\/|\\/|\\||:|\\?|\\*|\"||\\p{Cntrl}", "_");(正则表达中\\p{Cntrl}这个是处理00字符的。)

修复方案:

漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝

评价

2010-01-01 00:00 Xhm1n9 白帽子 | Rank:57 漏洞数:13)

这个问题好像kj牛有提到过

2010-01-01 00:00 cnrstar 白帽子 | Rank:136 漏洞数:18)

岂不是很多jsp上传都会躺枪,不过不随机重命名的还是不多

所有媒体,可在保留署名、原文连接的情况下转载,若非则不得使用我方内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值