<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Emmanuel Chibuzor Kingsley on Medium]]></title>
        <description><![CDATA[Stories by Emmanuel Chibuzor Kingsley on Medium]]></description>
        <link>https://medium.com/@rootchisco?source=rss-c107d4c93d10------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*7dXVyWctdcA9VxaFGEQ13Q.jpeg</url>
            <title>Stories by Emmanuel Chibuzor Kingsley on Medium</title>
            <link>https://medium.com/@rootchisco?source=rss-c107d4c93d10------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 25 May 2026 11:16:42 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@rootchisco/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Practical Project: Scanning and Enumeration on a Vulnerable Linux Target (Kioptrix)]]></title>
            <link>https://medium.com/@rootchisco/practical-project-scanning-and-enumeration-on-a-vulnerable-linux-target-kioptrix-bef5b59c8962?source=rss-c107d4c93d10------2</link>
            <guid isPermaLink="false">https://medium.com/p/bef5b59c8962</guid>
            <category><![CDATA[enumeration]]></category>
            <category><![CDATA[scanning]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[kioptrix]]></category>
            <dc:creator><![CDATA[Emmanuel Chibuzor Kingsley]]></dc:creator>
            <pubDate>Fri, 30 May 2025 03:26:04 GMT</pubDate>
            <atom:updated>2025-05-30T03:28:47.928Z</atom:updated>
            <content:encoded><![CDATA[<p>As part of my hands-on learning with <strong>TCM Security’s Practical Ethical Hacking course</strong>, I worked on scanning and enumeration against the vulnerable Kioptrix VM. This blog documents my process from discovering the target to identifying its exposed services and potential weak spots</p><h4>Step 1: Verifying Connectivity</h4><p>On the Kioptrix box, I pinged Google’s DNS (8.8.8.8) to confirm internet reachability.</p><p>Then, on my Kali machine, I ran:</p><p><strong>arp-scan -l</strong></p><p>This listed all live devices in my local subnet. I identified <strong>Kioptrix’s IP as </strong><strong>10.0.2.4</strong>.</p><h4>Step 2: Full Nmap Scan</h4><p>To discover open ports and services running on the target, I launched a full TCP scan with the following command:</p><p><strong>nmap -T4 -p- -A 10.0.2.4</strong></p><h4>Command Breakdown:</h4><ul><li>nmap: The network scanner tool.</li><li>-T4: Sets the <strong>timing template</strong> to 4 (Aggressive), which speeds up the scan without overwhelming the network.</li><li>-p-: Tells Nmap to scan <strong>all 65,535 TCP ports</strong> instead of just the default top 1000.</li><li>-A: Enables <strong>aggressive detection</strong>, which includes:</li><li>OS detection</li><li>Version detection</li><li>Script scanning</li><li>Traceroute</li></ul><h3>Results:</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/779/1*bdWVNeRrKZ__SU5zSaPYvA.png" /></figure><h4>Step 3: Service Enumeration</h4><p>Now that I knew what was running, I began <strong>manual service enumeration</strong>.</p><h4>Web Enumeration (HTTP/HTTPS — Ports 80 &amp; 443)</h4><p>I browsed to http://10.0.2.4 and saw the classic <strong>Apache Test Page</strong> — a sign that the default Apache web server was up but not customized.</p><p>Then, I used <strong>DirBuster</strong> to find hidden files/directories:</p><ul><li><strong>Target URL</strong>: <a href="http://10.0.2.4">http://10.0.2.4</a></li><li><strong>Extensions</strong>: .php, .csv, .docx</li><li><strong>Wordlist</strong>: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/760/1*4McyQunHTDvx050uVY66Ig.png" /></figure><h4>SMB Enumeration (Port 139)</h4><p>From the Nmap scan, I saw the server was running <strong>Samba</strong> (SMB). I fired up Metasploit for further fingerprinting:</p><p><strong>msfconsole </strong>then</p><p><strong>use auxiliary/scanner/smb/smb_version<br>set RHOSTS 10.0.2.4<br>run</strong></p><p><strong>Result:</strong> Samba version <strong>2.2.1a</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*09RfBVcWZYCLECKoyvSDaA.png" /></figure><h4>SSH Enumeration (Port 22)</h4><p>Attempted to connect to the SSH service using:</p><p><strong>ssh 10.0.2.4</strong></p><p>The banner didn’t reveal much — no additional info beyond what Nmap already told me: <strong>OpenSSH 2.9p2 (protocol 1.99)</strong></p><h4>Nikto Web Vulnerability Scan</h4><p>To round off web enum, I ran:</p><p><strong>nikto -h </strong><a href="http://10.0.2.4"><strong>http://10.0.2.4</strong></a></p><h3>Key Findings:</h3><ul><li><strong>Apache/1.3.20</strong> is vulnerable to:</li><li>Remote DoS and code execution <a href="https://github.com/heltonWernik/OpenLuck">OpenLuck exploit</a></li><li>Buffer overflow issues in versions below 1.3.27</li></ul><p>At this stage, I’ve successfully:</p><ul><li>Identified the target’s IP</li><li>Scanned for open ports and services</li><li>Enumerated Apache, Samba, and SSH services</li><li>Collected known version-specific vulnerabilities (for mapping later)</li></ul><p><strong>This project helped me practicalize my scanning and enumeration skills using real-world tools like Nmap, DirBuster, Nikto, and Metasploit’s SMB scanner. It reinforced the importance of thorough recon before any exploitation phase.</strong></p><p><strong>I’ll continue with this lab series and dive deeper into vulnerabilities and privilege escalation techniques in the next blog.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bef5b59c8962" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My PortSwigger Journey: Exploring SQL Vulnerabilities Using Burp Suite (Pt 6)]]></title>
            <link>https://medium.com/@rootchisco/my-portswigger-journey-exploring-sql-vulnerabilities-using-burp-suite-pt-6-530fa102f14a?source=rss-c107d4c93d10------2</link>
            <guid isPermaLink="false">https://medium.com/p/530fa102f14a</guid>
            <category><![CDATA[sql-injection]]></category>
            <category><![CDATA[web-app-security]]></category>
            <category><![CDATA[pentesting]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[portswigger]]></category>
            <dc:creator><![CDATA[Emmanuel Chibuzor Kingsley]]></dc:creator>
            <pubDate>Mon, 05 May 2025 00:39:17 GMT</pubDate>
            <atom:updated>2025-05-05T00:39:17.401Z</atom:updated>
            <content:encoded><![CDATA[<h3>Exploiting blind SQL injection by triggering time delays</h3><p>Time-based SQL injection is a technique used when the web app doesn’t return visible output or error messages. Instead of looking for data in the response, the attacker injects a SQL payload that deliberately delays the web app’s response. If the delay occurs, it confirms that the payload was executed. This method is useful for extracting data one character at a time by observing the web app’s response time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/791/1*d86zeLewAD-WQsL-qiq_LQ.png" /></figure><p>In this lab, I was tasked with exploiting a SQL injection vulnerability to cause a 10-second delay on the web app. I referred to a cheatsheet and tried different payloads for various database types — the one for PostgreSQL worked successfully.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CcXupB2LAzQbLlKPM7utTQ.png" /></figure><p><strong>The PostgresqlSQL payload i used is: ’ || pg_sleep(10)--</strong></p><h3><strong>Blind SQLi with Time Delay and Information Retrieval</strong></h3><p>Moving on, I was tasked with exploiting a blind SQL injection vulnerability that involved both triggering time delays and retrieving information. This technique is useful when a web application doesn’t show visible errors or output changes. Instead, it relies on forcing the server to delay its response using SQL functions like <strong>pg_sleep() </strong>or <strong>SLEEP()</strong>. By combining this with conditions, it&#39;s possible to confirm whether specific queries are true — for example, if a certain character in a password matches. If the condition is true, the server delays the response, allowing me to extract data like passwords or usernames based on response timing alone.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/751/1*PmDxiBrl1_swk8gtbJq21Q.png" /></figure><p>In this lab, I had to exploit a time delay SQL injection vulnerability to find out the password of the <strong>administrator</strong> user</p><ol><li>I first verified that the SQL injection for time delay was working by using the payload <strong>’ || pg_sleep(10)-- </strong>and it successfully caused a delay. But since retrieving information through time-based SQLi requires a conditional check to determine true or false responses, I moved on to a new payload:</li></ol><p><strong>’%3BSELECT+CASE+WHEN(1=1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END--</strong><br><strong> </strong><br> This allowed me to confirm logical conditions by observing the server&#39;s response time.</p><p>2.<strong>To verify if the <em>administrator</em> user exists, I used the following payload:</strong><br> &#39;%3BSELECT+CASE+WHEN(username=&#39;administrator&#39;)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zxk6r8zx5QpHAsPNRKk_3w.png" /></figure><p>3.<strong> I determined how many characters are in the administrator’s password using this payload:</strong><br> &#39;%3BSELECT+CASE+WHEN+(username=&#39;administrator&#39;+AND+LENGTH(password)&gt;1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TQ1tsBkIxVFH4UGAVB56ig.png" /></figure><p>I kept increasing the number after &gt; until the server no longer delayed, which helped me conclude that the password is 20 characters long.</p><p>4. <strong>Testing the Position of the Characters</strong></p><ul><li>First, I forwarded the request to Intruder.<br> Then, I injected the payload:<br> &#39;%3BSELECT+CASE+WHEN+(username=&#39;administrator&#39;+AND+SUBSTRING(password,1,1)=&#39;a&#39;)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--<br> into the request, placed the payload position marker on ‘a’.</li><li>set up my payload configuration (simple list, a-z and 0–9 wordlist)</li><li>I set up my payload configuration using a <em>Simple List</em> with a custom wordlist containing a–z and 0–9</li><li>In order to validate the position of each character, I needed to monitor the delay time. To make this process easier and more efficient, I used the resource pool to track the delay times for each request. By observing the response time for each injected payload, I could determine whether the condition for a specific character position was met (i.e., if the character was correct).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/487/1*lU5xgWpQFg9oxAE8aVuoDw.png" /><figcaption>resource pool</figcaption></figure><ul><li>After configuring the Intruder tool, I launched the attack while constantly increasing the value of the substring (e.g., from 1,1 to 20,1) to test each position of the administrator&#39;s password. This allowed me to systematically test each character in the password, using the delay times to confirm which character was correct at each position. Once I reached 20,1, I had successfully mapped out all 20 characters of the administrator&#39;s password.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/851/1*YFpJ6biy4sJUipibPdDM6g.png" /></figure><p>The above image shows the results of testing the password characters using the Intruder tool. You should notice the “Response Received” column, which is a result of the resource pool setup. The highest number in this column typically indicates the correct character for that position in the password. In most cases, the number will be over 1000, which reflects the time delay and confirms the correct character at that specific position.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zRzB_8hV9Y5HVr4C6bk-Wg.png" /></figure><p>After identifying the entire password by testing each character position, I then used the extracted password to log into the administrator account successfully.</p><h3><strong>What I Learned</strong></h3><ul><li>How to trigger a time delay to confirm if a web app is susceptible to blind SQL Injection.</li><li>How to use the time delay to retrieve sensitive information from the web app.</li><li>How to utilize the resource pool in Burp Suite’s Intruder tool for efficient attack management.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=530fa102f14a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My PortSwigger Journey: Exploring SQL Vulnerabilities Using Burp Suite (Pt 5)]]></title>
            <link>https://medium.com/@rootchisco/my-portswigger-journey-exploring-sql-vulnerabilities-using-burp-suite-pt-5-3329319c5518?source=rss-c107d4c93d10------2</link>
            <guid isPermaLink="false">https://medium.com/p/3329319c5518</guid>
            <category><![CDATA[sql-injection]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[portswigger]]></category>
            <category><![CDATA[web-app-security]]></category>
            <category><![CDATA[error-based-sql-injection]]></category>
            <dc:creator><![CDATA[Emmanuel Chibuzor Kingsley]]></dc:creator>
            <pubDate>Fri, 02 May 2025 01:26:43 GMT</pubDate>
            <atom:updated>2025-05-02T01:26:43.603Z</atom:updated>
            <content:encoded><![CDATA[<p>After working through Blind SQL Injection with conditional errors, I explored another technique</p><h3><strong>Error-Based SQL Injection</strong></h3><p>Misconfiguration of a database can sometimes lead to verbose error messages being exposed to users. While these errors might seem harmless or just technical details, they can actually leak critical information such as database structure, table names, and even user data especially when SQL injection vulnerabilities are present.</p><h4><strong>Extracting Sensitive Data Via Verbose SQL Error Messages</strong></h4><p>In this part, I learned how to trigger errors from a misconfigured web application’s database. If the app returns an error, I can then use those error messages as a medium to extract sensitive data.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*imBEpz9RPtTEwFEvuThMng.png" /><figcaption>Visible Error-Based SQL injection Lab</figcaption></figure><h4><strong>My Approach to Solving the Lab</strong></h4><ol><li>I started by testing if the application would respond to malformed SQL input in the cookie header. I injected a single quote (’) into the cookie header and sent the request. The application responded with an error message, which confirmed the app’s vulnerability to error-based SQL injection.</li><li><strong>Retrieving the Administrator Username:</strong></li></ol><p>Next, I attempted to retrieve the administrator username from the database using the following query:</p><p><strong>‘ AND 1=CAST((SELECT username FROM users) AS int)--</strong></p><p><strong>TrackingId=’ AND 1=CAST((SELECT username FROM users) AS int) —</strong></p><p>This also triggered an error, specifically indicating that more than one row was returned. To fix this, I modified my query to ensure it only returned one row by adding <strong>LIMIT</strong>:</p><p><strong>TrackingId=’ AND 1=CAST((SELECT username FROM users LIMIT 1) AS int)--</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2NK7azXNpJrZncLJRLo4xg.png" /><figcaption>error leaks administrator user</figcaption></figure><p>The image above shows me inputting my query with the <strong>LIMIT </strong>clause, which restricts the results to just one row. The response from the web app contains an error message confirming that the administrator user exists in the database.</p><p>3.<strong> Modifying the Query to Leak the Password</strong></p><p>By modifying my previous query to:</p><p><strong>TrackingId=’ AND 1=CAST((SELECT password FROM users LIMIT 1) AS int) --</strong></p><p>I was able to make the web app leak the administrator password in the error message. The error message confirmed that the administrator’s password was exposed through the SQL injection.</p><p><strong>Note:</strong> The administrator user is the first entry in the users and password table, which is why using <strong>LIMIT 1 </strong>effectively targets the administrator&#39;s data for extraction.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0dYExTsMYwh82xXiTprR_A.png" /><figcaption>password leak</figcaption></figure><h3>What I Learned</h3><ul><li>Trigger error messages by injecting malformed SQL queries into the cookie header.</li><li>Use the information from error messages to infer the existence of database tables, such as the <strong>users </strong>table.</li><li>Retrieve sensitive data like usernames and passwords by modifying my SQL queries and using techniques such as <strong>LIMIT </strong>to control query output and avoid errors caused by multiple rows being returned.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3329319c5518" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My PortSwigger Journey: Exploring SQL Vulnerabilities Using Burp Suite (Pt 4)]]></title>
            <link>https://medium.com/@rootchisco/my-portswigger-journey-exploring-sql-vulnerabilities-using-burp-suite-pt-4-5a8b1d33e208?source=rss-c107d4c93d10------2</link>
            <guid isPermaLink="false">https://medium.com/p/5a8b1d33e208</guid>
            <category><![CDATA[error-based-sql-injection]]></category>
            <category><![CDATA[portswigger]]></category>
            <category><![CDATA[web-app-pentesting]]></category>
            <category><![CDATA[web-app-security]]></category>
            <category><![CDATA[sql-injection]]></category>
            <dc:creator><![CDATA[Emmanuel Chibuzor Kingsley]]></dc:creator>
            <pubDate>Thu, 01 May 2025 03:22:51 GMT</pubDate>
            <atom:updated>2025-05-01T03:22:51.377Z</atom:updated>
            <content:encoded><![CDATA[<p>After exploring Blind SQL Injection, I moved on to another interesting technique: <strong>Error-Based SQL Injection.</strong></p><p><strong>Error-Based SQL Injection:</strong> In some cases, the web application doesn’t return any useful response that confirms a successful query, but it does leak database error messages when a query fails. These errors can be used to gain information about the database structure or even extract data directly, just by triggering and reading the error output.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/773/1*_QQGBQi2avJO_OdNxpaUOQ.png" /><figcaption>Error Based SQLi</figcaption></figure><p>In this lab, I was tasked with exploiting the web application using a type of Blind SQL Injection that triggers conditional errors to infer information from the database. My goal was to retrieve the administrator user’s password and log in to the account.</p><h3><strong>MY APPROACH TO SOLVING THIS LAB</strong></h3><p>This technique relies on triggering deliberate errors in the web app to confirm SQL injection. So, the first thing I tried was adding a single ’ into the <strong>TrackingId </strong>cookie value to see if it would cause a visible database error in the response. As expected, it returned an error because the ’ broke the SQL syntax being processed by the backend. That error confirmed the input was being passed directly into a SQL query, meaning the application was indeed vulnerable.</p><ol><li><strong>Verify if users table exists</strong></li></ol><p>From the hint given in the lab, I learned that the web app uses an Oracle database. So, to verify if the <strong>users </strong>table exists, I used the following SQL payload in the <strong>TrackingId</strong> cookie:<strong> ’ ||(SELECT ‘’ FROM users WHERE ROWNUM = 1)||’</strong></p><p>Since the table exists, the query runs without throwing an error. Also <strong>ROWNUM=1</strong> is used to prevent the query from returning more than one row.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LQcccz6tQOagrrFKHPD2OQ.png" /><figcaption>payload to verify user in Burp Suite</figcaption></figure><p>2. <strong>Verify if administrator user exists</strong></p><p><strong>’||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE ‘’ END FROM users WHERE username=’administrator’)||’</strong></p><p>This Payload would help verify if there is a user named administrator and the web app would throw an error which helps infer the user exists.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*t0V7W8suxZrwAi7t2OELSg.png" /><figcaption>Payload in Burp Suite to verify if administrator user exist</figcaption></figure><p>3. <strong>Determine Length of Password using:</strong></p><p><strong>’||(SELECT CASE WHEN LENGTH(password)&gt;1 THEN to_char(1/0) ELSE ‘’ END FROM users WHERE username=’administrator’)||’</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/783/1*Xiom7WztirwUrkWLTtykEA.png" /><figcaption>password character length payload in burp Suite</figcaption></figure><p>As shown in the above image, I incremented the value of <strong>&gt;1</strong> step-by-step until the web app stopped showing an error response. This helped me determine that the length of the password is 20 characters.</p><p>4.<strong> Test Password Characters Position using Burp Suite Intruder Tool</strong></p><p>If you recall from the last part of this series, I used Burp Suite’s Intruder tool to automate the process of testing password characters. In this lab, my payload for this would be different since I’m working with an Oracle database type.</p><p>The payload:</p><p><strong>’||(SELECT CASE WHEN SUBSTR(password,1,1)=’a’ THEN TO_CHAR(1/0) ELSE ‘’ END FROM users WHERE username=’administrator’)||’</strong></p><p>By setting the payload marker on the <strong>‘a’ </strong>character and uploading my wordlist (a–z and 0–9) in the payload configuration, I was able to use Intruder to automate the task of testing character positions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u_hwmnvHel1mjAWZIbG0CA.png" /><figcaption>Intruder character postion result</figcaption></figure><p>I then went ahead to login to the <strong>administrator </strong>account.</p><h3>What I Learned</h3><p>Through this lab, I gained a deeper understanding of Blind SQL Injection and how to leverage it for exploiting web application vulnerabilities, even in the absence of direct error messages or query results.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5a8b1d33e208" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My PortSwigger Journey: Exploring SQL Vulnerabilities Using Burp Suite (Pt 3)]]></title>
            <link>https://medium.com/@rootchisco/my-portswigger-journey-exploring-sql-vulnerabilities-using-burp-suite-pt-3-377a6748f026?source=rss-c107d4c93d10------2</link>
            <guid isPermaLink="false">https://medium.com/p/377a6748f026</guid>
            <category><![CDATA[portswigger]]></category>
            <category><![CDATA[sql-injection]]></category>
            <category><![CDATA[sql]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[appsec]]></category>
            <dc:creator><![CDATA[Emmanuel Chibuzor Kingsley]]></dc:creator>
            <pubDate>Wed, 30 Apr 2025 01:31:16 GMT</pubDate>
            <atom:updated>2025-04-30T01:31:16.262Z</atom:updated>
            <content:encoded><![CDATA[<p>In the past parts of this series, I explored SQL vulnerabilities in scenarios where the web application provides visible feedback, making it easier to confirm if an injection was successful. But what happens when the web app doesn’t give any direct responses? How can you tell if your SQL injection is working or even possible? In these cases, queries like a <strong>UNION attack</strong> won’t be effective, as they rely on the application to display feedback.</p><p>That’s where <strong>Blind SQL Injection</strong> comes in.</p><h3>BLIND SQL INJECTION</h3><p><strong>Blind SQL Injection </strong>is a method used when an application is vulnerable to SQL injection, but it doesn’t show the results of the query in the web page. Instead of visible errors or data, the attacker must rely on observing subtle behavioral differences such as changes in the page’s content, redirects, or even how long the server takes to respond to be sure whether the injected query returned true or false.</p><p>In this blog, I’ll be sharing what I learned about <strong>Blind SQL Injection</strong>, starting with how to exploit it by <strong>triggering conditional responses </strong>a method that helps uncover vulnerabilities even when the application doesn’t visibly display query results.</p><p><strong>Blind SQL Injection With Conditional Responses</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/735/1*s43TG-CTEJF3m40TVk3moA.png" /></figure><p>Unlike other labs I’ve worked on, this lab, as shown in the image above, doesn’t return query results or display error messages. Instead, a simple “welcome back” message is shown to confirm if the query worked. In this lab, my task was to use Blind SQL Injection to retrieve the administrator’s account password.</p><h4><strong>My Approach to Solving This Lab</strong></h4><ol><li>Since the web app in the lab uses a tracking cookie for analytics and performs an SQL query on the value of the submitted cookie, I modified the tracking cookie ID by adding <strong>AND ‘1’=’1 </strong>to check if the “welcome back” message was triggered, confirming that the response was working.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/765/1*aHdAsf74dG1VNpEODc1xeg.png" /></figure><p>One of the first issues I encountered was not getting the “welcome back” message, meaning my query wasn’t working. After researching the issue, I discovered that I didn’t need to URL-encode the <strong>AND ‘1’=’1 </strong>since I was injecting it directly into the cookie header, which doesn’t require encoding like query parameters do.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/333/1*m1mxyIwfoZFaBXLsb-n7aA.png" /><figcaption>welcome back</figcaption></figure><p>After getting a “welcome back” message on the web app navigation bar i then went on to;</p><p>2. <strong>Verify if the users table exists</strong> by injecting <strong>AND (SELECT ‘a’ FROM users LIMIT 1)=’a</strong> into the cookie header and I confirmed the success by seeing the welcome back message on the web app</p><p><strong>NOTE:</strong>In this lab, the “Welcome back!” message is the application’s only behavioral cue confirming successful SQL queries<strong> </strong>because this is a Blind SQL Injection.</p><p>3.<strong> I verified if the user “administrator”</strong> exists by injecting <strong>AND (SELECT ‘a’ FROM users WHERE username=‘administrator’)=’a</strong></p><p>4.<strong> Determine how many characters make up the password</strong> of the <strong>Administrator </strong>user. this was done by injecting <strong>AND LENGTH (password)&gt;1)= a</strong></p><p>I continually repeated this and increasing the value of <strong>&gt;1</strong> till I don&#39;t get a “welcome back” message anymore.</p><p><strong>How it works:</strong> If the condition is true (i.e., the password length is indeed greater than the number I injected), the “Welcome back!” message appears. Once the “Welcome back!” message no longer appears, I know the actual password length is <strong>equal to the last number that still triggered the message</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/1*STWdmuzagfbA0xhWGhIhGA.png" /></figure><p>Now I know that the password character is 20 and with the hint given i know that they are lowercase, alphanumeric characters meaning they contain values within a-z and 0–9</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/709/1*cIqj3A5mSJQ6Y9Z91fx0hg.png" /></figure><p>5. <strong>Test for the Position of Each Password Character</strong></p><p>Instead of testing each character manually, I learned about the <strong>Intruder</strong> tool in Burp Suite and used it to automate this process. I injected the payload:</p><ul><li><strong>AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username=‘administrator’)=’a</strong> in the cookie header and placed the payload marker § on the <strong>‘a</strong></li><li>In Burp Suite’s Intruder configuration, I set the <strong>payload type</strong> to <em>Simple list</em>. Then, I created two custom wordlists:</li><li>One containing lowercase letters (a-z)</li><li>Another containing numbers (0–9)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-i5tKlzsmvk5ZcZhPe6Fig.png" /><figcaption>Payload in the cookie header</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/457/1*4KNWLK3XfaNd9RKCPRBr_Q.png" /><figcaption>payload configuration</figcaption></figure><p>To detect when the correct character was guessed, I used the <strong>Grep Match</strong> feature in Burp Suite. I added <strong>“Welcome back”</strong> as the string to match in the server’s response. This way, Burp would highlight any response that contained that message meaning the injected condition was true.</p><p>This helped me quickly spot which payload (character) returned a successful match, making it easier to build the password one character at a time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/437/1*SciOK3o1v18TEDWQRUDCug.png" /><figcaption>Grep Match</figcaption></figure><p>After setting up the Grep Match, I launched the attack. Once I successfully identified the first character of the password, I updated the payload in the cookie header to test the next character:</p><p><strong>AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username=’administrator’)=’a</strong></p><p>I continued modifying the number in the <strong>SUBSTRING </strong>function by changing it to 3, 4, 5, and so on until I reached 20,1, since I had earlier confirmed that the administrator&#39;s password is 20 characters long.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TKfkZt3wgGGkypEWpexoSA.png" /><figcaption>character position with grep match</figcaption></figure><p>The image above shows the response for my 6th attack, where the payload in the cookie header was set to: <strong>AND (SELECT SUBSTRING(password,6,1) FROM users WHERE username=’administrator’)=’a</strong></p><p>You’ll notice a 1 under the <em>Grep Match</em> column, which confirms that the 6th character of the administrator&#39;s password is <strong>t</strong>.</p><p>After running the attack until I successfully identified all 20 characters of the administrator’s password, I used the password to attempt a login.</p><p>With the password I had uncovered, including each character’s position, I logged into the administrator account successfully, confirming the effectiveness of the blind SQL injection method.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HgxRi9HGI9yQ9-Sdc-sXfg.png" /><figcaption>access to administrator account</figcaption></figure><h3>What I Learned</h3><p>From this lab, I gained a deeper understanding of Blind SQL Injection, particularly how to exploit it by triggering conditional responses. Here are the key takeaways:</p><ol><li><strong>Blind SQL Injection Mechanics</strong>: I learned that even when an application doesn’t show direct results or error messages, I can still extract sensitive data like passwords by carefully analyzing subtle behavior changes, such as changes in the page content.</li><li><strong>Using Conditional Responses</strong>: By injecting conditional SQL queries, I was able to infer true or false responses based on the “welcome back” message displayed on the web app, allowing me to deduce information step-by-step without direct feedback.</li><li><strong>Using Burp Suite’s Intruder Tool</strong>: I discovered how to leverage Burp Suite’s Intruder tool to automate payload insertion and quickly test multiple values for each character of the password. This significantly streamlined the process of finding the correct password characters.</li><li><strong>Grep Match for Response Confirmation</strong>: The use of Grep Match in Burp Suite helped me easily identify when the correct password characters were returned, saving time by pinpointing successful attempts.</li><li><strong>Efficiency in Testing Password Length and Characters</strong>: I learned how to test the length of the password and systematically extract each character’s position using SQL queries and Burp Suite’s configuration. This approach turned what could have been a long, manual process into a more efficient and methodical attack.</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=377a6748f026" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My PortSwigger Journey: Exploring SQL Vulnerabilities Using Burp Suite (Pt 2)]]></title>
            <link>https://medium.com/@rootchisco/my-portswigger-journey-exploring-sql-vulnerabilities-using-burp-suite-pt-2-775614bd6388?source=rss-c107d4c93d10------2</link>
            <guid isPermaLink="false">https://medium.com/p/775614bd6388</guid>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[portswigger-lab]]></category>
            <category><![CDATA[burpsuite]]></category>
            <category><![CDATA[appsec]]></category>
            <category><![CDATA[portswigger]]></category>
            <dc:creator><![CDATA[Emmanuel Chibuzor Kingsley]]></dc:creator>
            <pubDate>Sat, 26 Apr 2025 02:26:15 GMT</pubDate>
            <atom:updated>2025-04-26T22:16:20.443Z</atom:updated>
            <content:encoded><![CDATA[<p>Following up from my previous exploration of basic SQL injection techniques, I proceeded to explore more under SQL vulnerabilities, starting with:</p><ol><li><strong>How To Find a Column With a Useful Data Type: </strong>After determining the number of columns (as done in Part 1 of this series), it’s important to find a column that accepts a useful data type because <strong>only columns with the correct data type (like text or strings) will display information when injected</strong>. This allows attackers to extract valuable data.</li></ol><p>To do this you’ll need to query the application with</p><p><strong>‘ UNION SELECT ‘a’, NULL, NULL--</strong></p><p><strong>Note:</strong></p><ul><li>The <strong>‘a’</strong> can be any random string or text.</li><li>The number of <strong>NULL </strong>values must match the number of columns you found earlier.</li><li>You then move the <strong>‘a’ </strong>across different column positions in the query until you get a valid response.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/1*5mobWMq74b8hcCtvlXC4Zg.png" /></figure><p>The image above shows the lab where I found a column that contains text.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/655/1*FIs3eAD9ROFkGjlcHc3Xag.png" /></figure><p>The lab provided a hint with a specific text string, <strong>‘oXsaSw’</strong>, which I used to replace <strong>‘a’</strong> in the query.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0qLEYguHPlqX3OCWc76ZTw.png" /></figure><p>By adjusting the query to:</p><p><strong>‘ UNION SELECT NULL, ’oXsaSw’ , NULL--</strong></p><p>I was able to locate the column containing the useful text.</p><p>If you check the image above, you’ll notice the query I inputted into Burp Suite was URL-encoded as: <strong>‘+UNION+SELECT+NULL,‘oXsaSw’,NULL--+ </strong>(as explained in Part 1).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TJzl7Vn-SjNjqbP9CAP1iw.png" /></figure><p>The application responded, showing that my query was correctly structured and confirming the useful data column.</p><p>2. <strong>Using SQL Injection UNION Attack to Retrieve Interesting Data</strong></p><p>After determining the number of columns and identifying the column with data, the next step is to retrieve <strong>interesting or sensitive information</strong> that can be exploited.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/749/1*AHiStChFqhaK5KTQp5ef9Q.png" /></figure><p>In this lab, I was tasked with retrieving data from another table and using it to log into the <strong>administrator </strong>account.</p><p>As shown in the image above I have been provided hint that the database contains table called <strong>users</strong>, with columns named <strong>username</strong> and <strong>password</strong></p><p><strong>Note:</strong><br> <strong>To retrieve data from other tables, you either need to know or guess the table name. In this case, the hint made it easy.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BBOJS1-dESc7tOkJrK3AVg.png" /></figure><p>Using Burp Suite to intercept the application traffic, I clicked on the “Gifts” category and modified the request by injecting a SQL query to retrieve <strong>username and password </strong>from the “<strong>users” </strong>table.</p><p>The query is<strong> ‘ UNION SELECT username, password FROM users-- (remember to URL-encode properly when sending through Burp Suite)</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2NbcYd75Dzgru_Of8wIH6Q.png" /></figure><p>The image above shows the application’s response to my SQL injection, where I successfully retrieved credentials.<br> I then used the administrator’s login details to access the account. Just as an attacker in likely to do in a real-world scenario.</p><p>3. <strong>Retrieving Multiple values Within a Single Column</strong>:</p><p>This is similar to retrieving interesting data, but the key difference is: Instead of displaying each value in separate columns, <strong>I have to combine multiple values into a single column</strong> using functions like <strong>CONCAT() </strong>and often include a separator <strong>(~ </strong>or <strong>: ) </strong>to distinguish the combined values.</p><p>This technique is useful when an application only displays data from one column in the response.</p><p><strong>Note:</strong></p><ul><li>Syntax for combining values varies depending on the database.</li><li>For example,<strong>CONCAT()</strong> is common in MySQL, while Oracle databases use <strong>| | </strong>for string concatenation.</li><li>PortSwigger provides a helpful<a href="https://portswigger.net/web-security/sql-injection/cheat-sheet"> SQL injection cheat-sheet </a>to guide syntax across different databases.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/752/1*qOjv4Mx6Jh_ZZ7TLyXSzbg.png" /></figure><p>In this lab, I was tasked with retrieving data from the <strong>Users </strong>table again. However, this time, I needed to <strong>combine the username and password into a single column</strong> and then use the retrieved password to log into the administrator account.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x5n91Z5qqoxxu1Q5Jk1udg.png" /></figure><p>Using the PortSwigger <a href="https://portswigger.net/web-security/sql-injection/cheat-sheet">SQL injection cheat-sheet</a>, I found the appropriate syntax for the database type and crafted the following query:</p><p><strong>‘ UNION SELECT NULL,username || ‘~’ || password FROM users--</strong></p><p>I entered this query into Burp Suite, forwarded the modified traffic.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5sTCshnpVMWojum15N7uLw.png" /></figure><p>The application responded by displaying the combined data. You’ll notice the separator “<strong>~”</strong> from my query which helped separate the username and password in the application’s response.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5fzI5taOWob5HeO3L9FcaQ.png" /></figure><p>After retrieving the data, I successfully logged into the administrator’s account.</p><p><strong>What I Learned:</strong></p><ul><li>I now understand how to find the number of valid columns containing data.</li><li>I learned how to use SQL injection UNION attacks to retrieve sensitive information.</li><li>I practiced retrieving multiple values within a single column, which shows how attackers can improvise when applications restrict data responses.</li><li>I also now have access to the PortSwigger SQL injection cheat-sheet, a valuable tool for executing SQL injection attacks across different database types.</li></ul><h3>Remediation Recommendations:</h3><ul><li><strong>Use Prepared Statements:</strong><br> Always use prepared statements to prevent SQL injection. They ensure user inputs are treated as data and not executable code.</li><li><strong>Input Validation and Sanitization:</strong><br> Validate and sanitize all user inputs. Whitelist allowed input formats and use parameterized queries to avoid SQL injection risks.</li><li><strong>Apply the Principle of Least Privilege:</strong><br> Database accounts used by web applications should have the minimum necessary permissions to limit potential damage if compromised.</li><li><strong>Proper Error Handling:</strong><br> Do not expose detailed error messages to users. Show generic error messages instead, to prevent attackers from gaining insights into the database structure.</li><li><strong>Conduct Regular Security Testing:</strong><br> Regular penetration testing, especially for injection vulnerabilities, is critical to identify and patch vulnerabilities early.</li></ul><h3>For Non-Technical Readers</h3><p>In this phase of my learning, I explored how attackers find and steal sensitive information from websites by exploiting a weakness called <strong>SQL Injection</strong>.</p><p>Normally, when you click around on a website (like searching for products or logging into your account), the website talks to a database behind the scenes to fetch the right information.<br> <strong>If the website is not properly protected</strong>, an attacker can insert special tricks (called SQL queries) into the website’s input fields to make the database reveal secrets — like usernames, passwords, and other private data.</p><p>In these labs:</p><ul><li>I learned how attackers first figure out how many pieces of information (columns) the database is sending back.</li><li>Then, they find which column actually shows useful or sensitive data.</li><li>After that, they retrieve hidden data like usernames and passwords, even when the website tries to limit what is displayed.</li><li>I also learned that attackers can combine multiple pieces of stolen information into one single response if the website restricts what they can see.</li></ul><p><strong>Impact on Daily Life:</strong></p><ul><li>If a website is vulnerable to SQL Injection, your personal accounts (email, banking, shopping, etc.) could be stolen without you realizing.</li><li>This is why it’s important for companies to properly secure their websites and for users to enable extra security measures like two-factor authentication<strong> (2FA)</strong>, so that even if your account credentials are exposed, an attacker would still need a second form of verification to access your account.</li><li>It’s also a reminder to stay cautious about where you enter your personal data and to watch for unusual activities on your accounts.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=775614bd6388" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My PortSwigger Journey: Exploring SQL Vulnerabilities Using Burp Suite (Pt 1)]]></title>
            <link>https://medium.com/@rootchisco/my-portswigger-journey-exploring-sql-vulnerabilities-using-burp-suite-pt-1-a9fd6859c7ae?source=rss-c107d4c93d10------2</link>
            <guid isPermaLink="false">https://medium.com/p/a9fd6859c7ae</guid>
            <category><![CDATA[portswigger]]></category>
            <category><![CDATA[cybersecurity]]></category>
            <category><![CDATA[sql-injection]]></category>
            <category><![CDATA[burpsuite]]></category>
            <category><![CDATA[portswigger-lab]]></category>
            <dc:creator><![CDATA[Emmanuel Chibuzor Kingsley]]></dc:creator>
            <pubDate>Fri, 25 Apr 2025 01:03:03 GMT</pubDate>
            <atom:updated>2025-04-25T22:05:58.025Z</atom:updated>
            <content:encoded><![CDATA[<p>SQL injection (SQLi) is a common web vulnerability that allows attackers to interfere with an application’s database by injecting malicious SQL queries. It can lead to data exposure, login bypass, and even full system compromise.</p><p>In the first lab I learnt about <strong><em>Retrieving Hidden Data</em></strong>, this works by by manipulating the SQL query to return more results than the application originally intended.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*n2_ccHuwT2JAlxKSL5fuTA.png" /></figure><p>in the above image I used Burp Suite to intercept the traffic and modified the request by injecting <strong>+OR+1=1-- </strong>I used <strong>+OR+1=1 — </strong>because the <strong>+ </strong>signs represent spaces in URL encoding. So instead of typing <strong>OR 1=1</strong>, which might break the request format.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HYg7_SMA_SuV4Alwv1RosA.png" /></figure><p>By modifying the request I was able to view hidden products that weren&#39;t meant to be displayed and got the congratulations message shown in the image.</p><p>In the next lab, I explored how to<strong> Subvert Application Logic </strong>using SQL injection.</p><p>The goal was to bypass login restrictions by injecting malicious SQL into the login form</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/836/1*gwg_1OJqL12eOSzd7r3t1A.png" /></figure><p>In the above image I inputted a random username and password into the respective fields</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U7T0oY-D4WKZ5lERTr872Q.png" /></figure><p>Then, using Burp Suite, I intercepted the request and modified the <strong>username</strong> parameter by injecting a malicious SQL query:</p><p><strong>administrator’-- </strong>this effectively invalidated the <strong>password</strong> parameter and turned it into a comment, allowing me to bypass the authentication check and log in.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/803/1*wZ_N5VhrxdOeXVDJLpWELw.png" /></figure><p>In the next lab I explored how to <strong>Retrieve Data From Other Database Table.</strong></p><p>My goal was to find and determine the number of column in the database to help me with further exploitation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/859/1*sGavfoXPoP_e_ZrB_s51Hg.png" /></figure><p>I had to first click on a category <strong>“gifts” </strong>(other categories would work too) and then modified the request on Burpsuite</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6X24pV2NzJ5glPLjbKWnGg.png" /></figure><p>Then, I intercepted the request in Burp Suite and modified it by injecting the following SQL query into the parameter: <strong>‘+UNION+SELECT+NULL,NULLNULL--+</strong></p><p>Through this, I was able to determine that the database had <strong>3 columns</strong> by testing different numbers of <strong>NULL </strong>values to match the database table’s structure.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cImQxBkUr9bH-Cs4LqjyZg.png" /></figure><p>The page returned with a different structure, indicating that the query successfully executed</p><p>Also i used the <strong>‘+ORDER+BY+3--+</strong> to also test</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UuQ-52Z_Dab33A2fouLovQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/806/1*LLhYZ_WzjiY9Si_xnGGlmA.png" /></figure><p><strong>From these labs I got to understand how attackers can easily manipulate SQL queries if user input isn’t properly handled by the application.</strong></p><p><strong>Developers should use prepared statements instead of building raw SQL queries with user input.</strong></p><p><strong>Also, Input Validation and proper error handling should be enforced.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a9fd6859c7ae" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Start]]></title>
            <link>https://medium.com/@rootchisco/the-start-3b0432d292c5?source=rss-c107d4c93d10------2</link>
            <guid isPermaLink="false">https://medium.com/p/3b0432d292c5</guid>
            <dc:creator><![CDATA[Emmanuel Chibuzor Kingsley]]></dc:creator>
            <pubDate>Mon, 21 Apr 2025 12:11:02 GMT</pubDate>
            <atom:updated>2025-04-21T12:11:02.391Z</atom:updated>
            <content:encoded><![CDATA[<p>A few days ago, I wrapped up the TryHackMe Junior Penetration Tester pathway; a journey that opened my eyes to the world of ethical hacking. From scanning networks to uncovering hidden vulnerabilities, it gave me a solid foundation and sharpened how I think.</p><figure><img alt="THM Jr Penetration Testing Cert" src="https://cdn-images-1.medium.com/max/1024/1*uumsN3bxUXnspK_PpITxDw.jpeg" /></figure><p>Now, I’m turning my focus to something deeper.</p><p>Web Application Security, there’s something fascinating about how a single line of code, a misplaced trust, or an overlooked logic flaw can open the doors to an entire system.</p><p>To explore that, I’ll be learning through PortSwigger Web Security Academy diving into the mechanics behind vulnerabilities like XSS, SQLi, SSRF, and more. Not just to pass labs, but to understand <strong>why</strong> things break, and how to defend against them.</p><p>This blog is where I’ll document that process, the lessons, the roadblocks, the breakthroughs. I’ll share what I learn in simple language, hoping it helps someone else who’s walking this path too.</p><p>It’s not just about hacking. It’s about growth, curiosity, and building something meaningful along the way.</p><p>Let’s see where this takes us.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3b0432d292c5" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>