<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>web security &#8211; Secure Batatas</title>
	<atom:link href="/category/web-security/feed/?simply_static_page=451" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description>Batatas is my foobar. Security.</description>
	<lastBuildDate>Mon, 19 Oct 2015 17:17:07 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=</generator>
	<item>
		<title>Testing uploads with Burp Intruder &#8211; Updated</title>
		<link>/testing-uploads-with-burp-intruder-updated/</link>
					<comments>/testing-uploads-with-burp-intruder-updated/#respond</comments>
		
		<dc:creator><![CDATA[tmendo]]></dc:creator>
		<pubDate>Tue, 01 Sep 2015 10:28:27 +0000</pubDate>
				<category><![CDATA[burp]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[web security]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[payload]]></category>
		<category><![CDATA[upload]]></category>
		<guid isPermaLink="false">/?p=268</guid>

					<description><![CDATA[Just updated my Intruder extension (described here) to provide two payload generators: the original one with the file contents and another one with the matching file name. So, if you need both the content and file name in your Intruder attack, choose Pitchfork as the Attack type and use File as Payload for one Payload [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Just updated my Intruder extension (described <a href="/?p=250">here</a>) to provide two payload generators: the original one with the file contents and another one with the matching file name.</p>
<p>So, if you need both the content and file name in your Intruder attack, choose Pitchfork as the Attack type and use File as Payload for one Payload set and Filename as Payload for the other.</p>
<p>With this update you can synchronize the file name and its contents in the attack without much hassle, something that was not trivial in the previous version. </p>
]]></content:encoded>
					
					<wfw:commentRss>/testing-uploads-with-burp-intruder-updated/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Testing uploads with Burp Intruder</title>
		<link>/testing-uploads-with-burp-intruder/</link>
					<comments>/testing-uploads-with-burp-intruder/#respond</comments>
		
		<dc:creator><![CDATA[tmendo]]></dc:creator>
		<pubDate>Sat, 22 Aug 2015 01:29:56 +0000</pubDate>
				<category><![CDATA[burp]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[web security]]></category>
		<category><![CDATA[bapp store]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[intruder]]></category>
		<category><![CDATA[payload]]></category>
		<category><![CDATA[upload]]></category>
		<guid isPermaLink="false">/?p=250</guid>

					<description><![CDATA[While testing an file upload functionality with Burp&#8217;s Repeater I noticed the site response changed depending on the file being uploaded, which is normal if the server is validating the file headers. After a few requests with different responses I got tired of doing this manually and decided to use Burp&#8217;s Intruder feature. I quickly [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>While testing an file upload functionality with Burp&#8217;s Repeater I noticed the site response changed depending on the file being uploaded, which is normal if the server is validating the file headers.<br />
After a few requests with different responses I got tired of doing this manually and decided to use Burp&#8217;s Intruder feature. I quickly noticed that there is no way of telling the Intruder to inject the contents of a list of files in the request.</p>
<p>So I wrote an extension that reads a folder files and feeds their content, one at a time, as a payload to use in the Intruder.<br />
Suppose you have a folder with your best malicious files, zip and xml bombs, jpegs with other contents, php shells, etc. You point the extension to this folder and just use the Repeater normally, setting the payload source as being this extension.<br />
If you need/want to synchronize the file contents with the file name, the extension tab shows the names of the files it just read so you can use them as payload for a second position in the request, using the pitchfork attack.  </p>
<blockquote><p><code><strong>EDIT</strong></code><br />
There is a new version of the extension that provides two generators, one for the file name and other for the file contents, easing this synchronization process. See <a href="/?p=268">this</a> update post.
</p></blockquote>
<div id="attachment_258" style="width: 1065px" class="wp-caption alignnone"><a href="/wp-content/uploads/2015/08/BurpIntruderFilePayload.png"><img aria-describedby="caption-attachment-258" decoding="async" src="/wp-content/uploads/2015/08/BurpIntruderFilePayload.png" alt="Burp Intruder File Payload Extension tab" width="1055" height="449" class="size-full wp-image-258" /></a><p id="caption-attachment-258" class="wp-caption-text">Choosing the input files</p></div>
<div id="attachment_262" style="width: 562px" class="wp-caption alignnone"><a href="/wp-content/uploads/2015/08/BurpIntruderFilePayload2.png"><img aria-describedby="caption-attachment-262" decoding="async" loading="lazy" src="/wp-content/uploads/2015/08/BurpIntruderFilePayload2.png" alt="Configuring the Intruder" width="552" height="339" class="size-full wp-image-262" /></a><p id="caption-attachment-262" class="wp-caption-text">Configuring the Intruder</p></div>
<p>The extension is available <a href="https://github.com/tmendo/BurpIntruderFilePayloadGenerator/raw/master/dist/IntruderFilePayloadGenerator.jar">here</a> as a single jar. The code is available <a href="https://github.com/tmendo/BurpIntruderFilePayloadGenerator" target="_blank">here</a>.<br />
I have submitted it to the BApp Store but it hasn&#8217;t been approved yet.</p>
<blockquote><p><code><strong>EDIT</strong></code><br />
Now available at the BApp Store, <a href="https://portswigger.net/bappstore/ShowBappDetails.aspx?uuid=880cf2cf689b4067afd9db8e2aefb8ba" target="_blank">here</a> :)
</p></blockquote>
<p>Enjoy.</p>
]]></content:encoded>
					
					<wfw:commentRss>/testing-uploads-with-burp-intruder/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>OCSP stapling</title>
		<link>/ocsp-stapling/</link>
					<comments>/ocsp-stapling/#respond</comments>
		
		<dc:creator><![CDATA[tmendo]]></dc:creator>
		<pubDate>Fri, 08 May 2015 22:35:32 +0000</pubDate>
				<category><![CDATA[operations]]></category>
		<category><![CDATA[web security]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[ocsp]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[stapling]]></category>
		<category><![CDATA[tls]]></category>
		<guid isPermaLink="false">/?p=190</guid>

					<description><![CDATA[Tired of seeing wrong OCSP stapling configurations, even those made by me, I&#8217;m writing this so I won&#8217;t forget how to do it right..and hopefully aid others. This is also an excuse to read more about the subject :) OCSP stapling is good: you have one less connection to a server that has nothing to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Tired of seeing wrong OCSP stapling configurations, even those made by me, I&#8217;m writing this so I won&#8217;t forget how to do it right..and hopefully aid others. This is also an excuse to read more about the subject :)</p>
<p>OCSP stapling is good: you have one less connection to a server that has nothing to do with the intended purpose of the original connection and still get an OCSP response. Sure, you have a few more bytes on every connection but it is harder for the attacker to interrupt the OCSP process without interfering with the target server itself.</p>
<p>For nginx, you need to use a configuration at least with these directives:<br />
<code><br />
ssl_stapling on;<br />
ssl_stapling_verify on;<br />
ssl_trusted_certificate /etc/nginx/certs/bundle_with_root_stapling.pem;<br />
</code></p>
<p><strong>ssl_stapling on;</strong> enables stapling. To be honest, you can make stapling work only with this line.</p>
<p><strong>ssl_stapling_verify on;</strong> this forces our server to check if the OCSP response is valid, meaning properly signed by the respective CA. </p>
<p><strong>ssl_trusted_certificate /etc/nginx/certs/bundle_with_root_stapling.pem;</strong> path to the chain that validates the responses. If you enabled ssl_stapling_verify you need this directive. It must have all the intermediates CAs, including the root. Just concatenate every CA in the chain, PEM encoded, with the root in the end.</p>
<p>Then just issue <code>sudo service nginx restart</code> and test it. You can test it with <code>echo | openssl s_client -connect mendo.pt:443 -status</code></p>
<p>You will likely get something like<br />
<code>OCSP response: no response sent</code></p>
<p>This happens because nginx will not prefetch a valid response until it gets a connection, so the first connection won&#8217;t receive an OCSP response. Try again after a few seconds and you will get<br />
<code><br />
OCSP response:<br />
======================================<br />
OCSP Response Data:<br />
    OCSP Response Status: successful (0x0)<br />
    Response Type: Basic OCSP Response<br />
    Version: 1 (0x0)<br />
    Responder Id: C = IL, O = StartCom Ltd. (Start Commercial Limited), CN = StartCom Class 1 Server OCSP Signer<br />
    Produced At: May  8 20:48:21 2015 GMT<br />
    Responses:<br />
    Certificate ID:<br />
      Hash Algorithm: sha1<br />
      Issuer Name Hash: 6568874F40750F016A3475625E1F5C93E5A26D58<br />
      Issuer Key Hash: EB4234D098B0AB9FF41B6B08F7CC642EEF0E2C45<br />
      Serial Number: 05A143427C3754<br />
    Cert Status: good<br />
    This Update: May  8 20:48:21 2015 GMT<br />
    Next Update: May 10 20:48:21 2015 GMT</p>
<p>    Signature Algorithm: sha1WithRSAEncryption<br />
         98:47:f1:39:4b:ef:f6:67:3d:46:d4:3c:93:fc:ab:95:20:a3:<br />
         e8:d0:2b:64:63:d8:46:d7:65:3f:00:5d:50:9c:7d:b7:2c:4c:<br />
         36:b1:58:86:9f:4b:95:d4:a4:fa:0f:bb:50:3b:a3:e8:d2:a6:<br />
         f3:5f:8c:c3:62:b1:75:90:8a:ab:50:cd:33:6a:cc:6c:ea:04:<br />
         a5:65:ff:09:15:41:0c:76:98:7a:79:93:f4:e1:8b:a5:a1:0c:<br />
         1e:90:04:25:05:98:91:2c:cc:62:0a:2b:06:a3:28:46:55:90:<br />
         f3:0f:09:3c:57:51:98:ed:9c:6f:03:f6:01:9e:d5:61:1b:cf:<br />
         f2:7a:0b:f2:9d:e1:52:ba:4a:34:ba:5c:95:7b:40:de:83:96:<br />
         55:d0:df:41:e7:14:58:28:9b:6a:67:67:fc:db:59:ab:8a:35:<br />
         90:a9:75:8b:9e:8b:46:51:0c:e9:8c:4e:43:60:34:f7:86:06:<br />
         09:0b:5f:03:16:b7:ab:15:49:ea:15:c4:f7:c6:d0:ec:22:01:<br />
         fd:8a:f1:d0:b9:f5:12:14:b7:13:5b:13:80:a6:60:be:11:bc:<br />
         28:c8:86:44:4b:1f:dd:fc:1e:5a:2e:a0:21:52:8d:c7:6c:e5:<br />
         72:c0:11:f4:15:16:54:96:14:f7:5f:5a:3f:cf:46:10:60:f5:<br />
         46:15:0a:8b<br />
</code></p>
<p>Simple.</p>
<blockquote><p><code><strong>EDIT</strong></code><br />
Because nginx will only resolve the OCSP hostname at startup and its IP can change, you might consider setting the following directive (pick you DNS resolver):</p>
<p><strong>resolver 8.8.8.8;</strong>
</p></blockquote>
]]></content:encoded>
					
					<wfw:commentRss>/ocsp-stapling/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Hardening WordPress</title>
		<link>/hardening-wordpress/</link>
					<comments>/hardening-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[tmendo]]></dc:creator>
		<pubDate>Sat, 03 Jan 2015 18:56:19 +0000</pubDate>
				<category><![CDATA[hardening]]></category>
		<category><![CDATA[web security]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">/?p=27</guid>

					<description><![CDATA[I think it makes sense that the very first post on my brand new WordPress blog would be about hardening WordPress itself. This makes even more sense if you consider it took me more time to harden this blog than to write this post. For the installation just follow the official documentation found here to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I think it makes sense that the very first post on my brand new WordPress blog would be about hardening WordPress itself. This makes even more sense if you consider it took me more time to harden this blog than to write this post.</p>
<p>For the installation just follow the official documentation found <a href="http://codex.wordpress.org/Installing_WordPress">here</a> to which I just want to make one remark about the database password strength: </p>
<p><code>GRANT ALL PRIVILEGES ON databasename.* TO "wordpressusername"@"hostname" IDENTIFIED BY "password";</code></p>
<p>Use a long password here, something like ﻿sK8ytB8mR5PtxqqTmCEYThEUJS5J6D which is 30 chars long. You won&#8217;t need to type this password often so there is no need to use a memorable one.<br />
To be honest, a weak password here wouldn&#8217;t be that bad since it is unlikely that you server will fall because of this&#8230;unless you expose it beyond 127.0.0.1.</p>
<p>For the hardening, start <a href="http://codex.wordpress.org/Hardening_WordPress">here</a>. There is some smalltalk but there are also some good advices regarding a few topics:    </p>
<ul>
<li>updates</li>
<li>file permissions</li>
<li>wp-admin</li>
<li>wp-includes</li>
<li>security plugins</li>
</ul>
<p><strong>updates</strong><br />
Keeping your installation up to date is paramount to ensure proper security. Before version 3.7 updates really sucked because the easiest way to (automatically) update was to have all files writable by the webserver process, so basically any malicious code executed by the webserver would be able to overwrite any file from our installation. The alternative was more secure but harder, so people wouldn&#8217;t update.<br />
In the latest versions there is some magic that let you have automatic updates without the need to have files writable by the webserver. I think there is more than one way to achieve this: I went for the SSH one.<br />
I followed this <a href="https://www.digitalocean.com/community/tutorials/how-to-configure-secure-updates-and-installations-in-wordpress-on-ubuntu">tutorial</a>. In addition to the 5 defines added to the wp-config.php file, I also added <code>define('FS_METHOD', 'ssh2');</code>.<br />
Since we are adding a new SSH user and we don&#8217;t want to increase your attack surface, disable password authentication for SSH at /etc/ssh/sshd_config with <code>PasswordAuthentication no</code>. Well&#8230;you should always disable password authentication for SSH. </p>
<p><strong>file permissions</strong><br />
The important thing here is to prevent the webserver from writing files. There are some exceptions, as you might want to allow functionality such as image upload (so I can haz pretty potatoes pic).<br />
You can have all files with owner and group wp-user, everything with 644 (files) or 755 (diretories).<br />
The exception is wp-content/uploads that must be writable by the group (775) and have the group www-data set. You don&#8217;t need to allow webserver writing for the others since updates and installations are done through SSH and run with wp-user.</p>
<p><strong>wp-admin</strong><br />
/wp-admin is a prime target for attackers because that is where you login to administrate your blog with your admin username and your weak password :)<br />
Leaving /wp-admin world accessible exposes you to two problems: credential bruteforce/reuse/theft and direct access to files that may have all sort of vulnerabilities.<br />
The most practical way to protect you from these is require some sort of authentication, say basic authentication. With nginx you just need to add this to your virtual host<br />
<code><br />
        location = /wp-admin {<br />
                auth_basic "Restricted";<br />
                auth_basic_user_file /path/to/your/htpasswd;<br />
        }</code></p>
<p>and define the username and password. Please use a strong password here and also for your /wp-admin accounts.</p>
<blockquote><p><code><strong>EDIT</strong></code><br />
Also protect the /wp-login.php since it is used to login to edit the blog.<br />
I include the snippet below to demonstrate the care you must take with nginx locations while configuring the rules described in this blog. Without going into details, prefix matching has precedence over regexp matching and nested locations with regex must have only regex inside.<br />
<code> location = /wp-admin {<br />
                auth_basic "Restricted";<br />
                auth_basic_user_file /etc/nginx/htpasswd;<br />
        }</p>
<p>        location ~ \.php$ {<br />
                location ~* /wp-login.php {<br />
                        auth_basic "Restricted login";<br />
                        auth_basic_user_file /etc/nginx/htpasswd;<br />
                }</p>
<p>                location ~* wp-config.php {<br />
                        deny all;<br />
                }<br />
</code></p></blockquote>
<p><strong>security plugins</strong><br />
Having many plugins installed is asking for trouble since many have vulnerabilities and don&#8217;t even get fixed. So, going against the usual recommendation of not installing plugins, install the Sucuri Security &#8211; Auditing, Malware Scanner and Hardening plugin.<br />
After installing, you get a Sucuri Security button on your dashboard side menu that lets you access the plugin dashboard<br />
<a href="/wp-content/uploads/2015/01/Screen-Shot-2015-01-03-at-17.48.34.png"><img decoding="async" loading="lazy" src="/wp-content/uploads/2015/01/Screen-Shot-2015-01-03-at-17.48.34.png" alt="Sucuri Security menu" width="880" height="238" class="alignnone size-full wp-image-55" /></a></p>
<p>Some of the features are paid, but you get a few nice things for free. In the hardening tab you can verify if have the proper secure configurations, however some only work if you are using Apache. More specifically, &#8220;Protect uploads directory&#8221;, &#8220;Restrict wp-content access&#8221; and &#8220;Restrict wp-includes access&#8221; will remain red under nginx even if properly configured, because the plugin expects Apache specific configuration.<br />
In the Settings tab you have another interesting feature: the scanner. The plugin can scan your wordpress installation for changes and notify you by email, like an HIDS. Go through the Settings tabs and activate/deactivate options as you please.</p>
<p>Additionally to the 5 previous topics, I recommend following this extra 2:</p>
<p><strong>Delete themes</strong><br />
Regarding themes&#8230;you just use one so delete those you don&#8217;t use, as well as the pre-installed useless plugin <a href="https://wordpress.org/plugins/hello-dolly/">Hello Dolly</a>.</p>
<p><strong>Limit PHP execution</strong><br />
Direct access to PHP files laying around in your installation are known to cause problem, so disable PHP execution wherever you can. If using nginx add the configuration below to your virtual host. For Apache just use the Sucuri plugin or use Google.</p>
<p>       <code> location ~* wp-config.php {<br />
                deny all;<br />
        }</p>
<p>        location ~* wp-content/(.*)\.php$ {<br />
                deny all;<br />
        }</p>
<p>        location ~* wp-includes/(.*)\.php$ {<br />
                deny all;<br />
        }</p>
<p>        location ~* wp-includes/uploads/sucuri$ {<br />
                deny all;<br />
        }</code></p>
<p>And finally&#8230;<strong>HTTPS</strong><br />
I don&#8217; need extra motivation to make my blog available only by HTTPS but you if you are thinking twice, just remember Google favors HTTPS sites in the search results and you can get certificates for free from <a href="https://www.startssl.com/">StartSSL</a>, for instance.<br />
Configuring HTTPS for WordPress is just like doing it for any another virtual host. Just remember a few things:</p>
<ul>
<li>change your site from http://example.com/ to http<strong>s</strong>://example.com at Settings->General->WordPress Address and Site Address</li>
<li>force a 301 redirect from HTTP to HTTPS</li>
<li>send a HSTS header to ensure you are always under HTTPS</li>
<li>disable all SSL versions and enable only TLS</li>
<li>enable strong ciphers such as <code>ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH</code></li>
<li>enable server cipher preference</li>
</ul>
<p>Then, go to <a href="https://www.ssllabs.com/ssltest/">SSL Labs</a> and test your configuration.</p>
<p>If you are paranoid, you can continue hardening your WordPress, webserver, PHP, and OS forever, but you have to balance that against the time you have available.</p>
<p>So..I guess I have an WordPress blog. Lets see how long it holds without being hacked&#8230;</p>
]]></content:encoded>
					
					<wfw:commentRss>/hardening-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
