[Solved] Change httpd Document Root results in 403 Forbidden on Apache 2.4 and Fedora 22

Recently, I decided to take the leap and begin using Linux exclusively. I installed Fedora 22 and so far I like it. I hit my first major snag when setting up a LAMP development environment.
After installing Apache and setting up a virtual host all pages returned error 403 Forbidden. I am running Apache 2.4. The first thing I noticed is that Apache changed the syntax for allowing and denying access to a directory. Previously you would use:

Allow from All

to grand access to a directory. In Apache 2.4 you use:

Require all granted

After ensuring I was allowing access to the new document root in httpd.conf correctly, I started to get stuck. Only after much digging, I came across the root of the problem: SELinux Contexts. SELinux adds an additional level of security by layering more flexible and powerful access controls on top of the standard Linux access control. SELinux is found on Fedora and Red Hat systems.

You can check to see if SELinux is enforcing access control on your system by running:

$ sestatus

You must add the httpd_system_context_t context to the new document root so that Apache has access. You can read more about SELinux here.

In production you do not want to weaken security to get things working. You should give files the correct context so Apache works with SELinux. However, in a development environment, you can simply disable SELinux to make your life easier.

To disable SELinux modify /etc/selinux/config to look like:

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
# SELINUXTYPE= can take one of these three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.

Save that file then restart. You can run sestatus again to make sure SELinux is disabled. If you configured httpd.conf correctly, Apache should now be able to access the new document root.


Online WGET Tool

About a year ago I came across a page that my browser flagged as malicious. I wanted to look at the source but my browser would not allow it. The solution is to run WGET on the page in order to view the source without executing it.


I did not have a WGET utility on my computer and did not feel like downloading it just for one use. So I googled “online wget tool” and there was nothing. Just links to the WGET application.

I had just started learning PHP and LAMP stack at the time so I decided to make my own online WGET utility. Here is what I came up with: Online WGET Tool. The tool allows you to enter a URL and see the HTML code without rendering it.

The page sat around for a while – I have used it a couple times over the past year. It has also come in handy as a limited proxy server several times.

Recently, the page was indexed by search engines and has started getting traffic. The tool is free to use and as long as my server does not get overwhelmed it will stay that way.

On-screen Keyboard

On-screen keyboards are useful for people who need alternate keyboard layouts frequently or people with disabilities. On-screen keyboards can also be used to thwart keyloggers. Hardware or software keyloggers can easily be installed on public computers allowing an attacker to see anything that is typed on an infected computer.

Some operating systems come with a built-in on-screen keyboard. However if you are on a public computer the application may be missing or be modified.

I created a web-based on-screen keyboard to solve this problem. This tool lets you type passwords or other sensitive information without a keylogger recording what you type. The input is obfuscated and can be copied to where ever you need it.

The keyboard can be used from anywhere with an Internet connection and a web browser. You can also download the webpage and use it offline. This isn’t foolproof, but it’s a good solution if you are wary of the computer you are currently on.

If you are paranoid you should inspect the page source before using the on-screen keyboard. I have made the page as simple as possible so it should be straightforward to inspect.

The tool can be found at keyboard.alanreed.org

Vulnerability Disclosure: USCC CyberQuests 2013

USCC runs computer security challenges throughout the year to find qualified students for their Cyber Security Camps. The most important test is held in April — the last challenge before summer camps.

The April 2013 Cyber Quest consisted of 30 multiple choice questions based on analysis of a pcap file containing evidence of an attack. The best score wins, if there is a tie then the fastest time wins. This was one of the easier challenges throughout the year — 65 participants got perfect scores. The challenge then became a race.

To submit the test quickly, I wrote a JavaScript command that would select the correct answers and submit the test. My approach required loading the quiz and then running the script. I scored a time of 8 seconds. Some challengers wrote very cool scripts to start and submit the test in less than a second!

To write my script I recorded the HTML value parameter for each radio-button and checkbox of the correct answers. While recording the values I discovered a pattern revealing all the correct choices!

Below is an example of the HTML for a radio button from one of the answer to the test:

<input id="resp581_253" name="resp581_" type="radio" value="253">

The value parameter is the problem. For each question there are 3 or 4 choices, each with a value that is unique to the entire quiz. Of the possible answers for each question, the correct answer is always the answer with the lowest value among the possible choices for that question.

For one question on the test there were two answers. For this question, the correct answers were the checkboxes with the two lowest values among the possible choices.

The radio button of every correct answer on the test had a value that was 1 more than a multiple of 4.

Despite not having an explicit bug bounty program USCC payed a reasonable bounty.

Solved: WordPress wp_insert_post problem with post_status and tax_input keys

wp_insert_post is the WordPress functions used to create new post. I used the function to create a plugin with a front end to allow anyone (anonymous users) to create posts. The function appeared to ignore several documented parameters. wp_insert_post would create the post but would not set the Category and Tags fields when anonymous users ran the code. The offending code:

$post = array(
	'post_title'    => $title,
	'post_name'     => $slug,
	'post_author'   => $poster_id,
	'post_content'  => $content,
	'post_type'     => 'music',
	'post_status'   => 'publish',
	'tags_input'    => $tags,
	'tax_input'     => array('genre' => $term)
$new_post_id = wp_insert_post($post);

It turns out that the post_type and tax_input keys only works if you user running the code is an administrator. If the user is not an administrator then all subsequent keys after the offending key will be ignored. To solve this problem, use wp_publish_post and wp_set_object_terms functions instead of using post_status and tax_input keys, respectively. These functions will work properly regardless of users’ permissions.

This code will allow anonymous users to create and publish posts:

$post = array(
	'post_title'    => $title,
	'post_name'     => $slug,
	'post_author'   => $poster_id,
	'post_content'  => $content,
	'post_type'     => 'music',
	'tags_input'    => $tags
$new_post_id = wp_insert_post($post);
wp_set_object_terms( $new_post_id, array($term), 'genre' );
wp_publish_post( $new_post_id );

If you omit the wp_publish_post then the post’s status is subject to the current user’s permissions (Reference). Anonymous users will create pending posts.

This behavior is not undocumented in the codex. Additionally, the behavior seems to be unintended. The function fails ungracefully by simply breaking when a permissions error is encountered rather than processing the remaining keys.

ARP Cache Poisoning Defense

Last summer I attended the US Cyber Challenge Conference in Virginia. I was in the hotel room getting ready for a week of exciting security courses. The WiFi was unbearably slow but I attributed that to the masses of other conference goers downloading OS images needed for the morning classes.

The morning class was Packet Crafting with Scapy, a powerful packet manipulation tool for Python. I was refreshing my Wireshark skills for the morning class and noticed something odd — there was a flood of constant ARP traffic. Someone was poisoning my ARP cache and intercepting all of my web traffic. This was my first up-close and personal introduction to ARP Poisoning.

That experience inspired me to write a personal ARP Defense script. The script monitors a computer’s ARP table and notifies the user when an Attack is detected. The script can be found here. Additional information on ARP Poisoning can be found at arppoisoning.com.