I am using libssh to make my own ssh server (some kind of honeypot). I would like to save the ip address of connected client into my logfile. How to get this IP address? Programming in c++. Thanks in advance guys!
Here is little function I'm using.
string getClientIp(ssh_session session) {
struct sockaddr_storage tmp;
struct sockaddr_in *sock;
unsigned int len = 100;
char ip[100] = "\0";
getpeername(ssh_get_fd(session), (struct sockaddr*)&tmp, &len);
sock = (struct sockaddr_in *)&tmp;
inet_ntop(AF_INET, &sock->sin_addr, ip, len);
string ip_str = ip;
return ip_str;
}
It is based on function "get_client_ip" fromhttps://github.com/PeteMo/sshpot/blob/master/auth.c where is complete SSH honeypot implementation.
s = ssh_get_fd(session);
getpeername(s, ...);
Related
I have been trying to get a simple SFTP program working with code from this website, but I have not been able to get it to even send out data without it returning error code 10061 (WSAECONNREFUSED). I have tried using Wireshark on the active interface with all firewalls disabled, but it didn't say anything was being sent to the address I gave (ex: 72.196.212.127). However, when I give it a local address like 192.168.1.101, it gives error code 10060 (WSAETIMEDOUT), still not sending out any data on the network. I am able to connect to the target machine on both address with software like Putty and WinSCP and ping it on the command prompt.
Here is the relevant part of my connection method:
// Open socket
WSADATA data;
int err = WSAStartup(MAKEWORD(2, 0), &data);
if (err != 0) return "ERROR: Failed to initialize WSA";
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = to_uint32_t(ip);
if (net::connect(sock, (struct sockaddr*) &sin, sizeof(struct sockaddr_in)) != 0) return "ERROR: Could not connect to host. Code: " + std::to_string(WSAGetLastError());
The variable port is an integer (value = 22), with ip being a string (192.168.1.101 or 72.196.212.127). This function returns the "Could not connect to host" error. No other errors occur.
Here is the to_uint32_t method:
std::uint32_t to_uint32_t(const std::string& ip_address)
{
const unsigned bits_per_term = 8;
const unsigned num_terms = 4;
std::istringstream ip(ip_address);
uint32_t packed = 0;
for (unsigned i = 0; i < num_terms; ++i)
{
unsigned term;
ip >> term;
ip.ignore();
packed += term << (bits_per_term * (num_terms - i - 1));
}
return packed;
}
#selbie pointed out that I was not using the correct function for resolving the IP. To fix my code, I just switched sin.sin_addr.s_addr = to_uint32_t(ip); to inet_pton(AF_INET, ip, &sin.sin_addr);.
The IP address is 192.168.23.4. I am able to get the hostname from the ipaddress using the following code snippet:
struct sockaddr_in sa;
char str[INET_ADDRSTRLEN];
inet_pton(AF_INET, "192.168.23.4", &(sa.sin_addr));
struct sockaddr_in saGNI;
char hostname[NI_MAXHOST];
char servInfo[NI_MAXSERV];
u_short port = 27015;
saGNI.sin_family = AF_INET;
saGNI.sin_addr.s_addr = sa.sin_addr.s_addr;
saGNI.sin_port = htons(port);
DWORD dwRetval = getnameinfo((struct sockaddr *) &saGNI,
sizeof(struct sockaddr),
hostname,
NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);
printf("HostName: %s", hostname);
I am getting an output of the form
ComputerName.domain.com
How do I get the Computername from the hostname?
Eg Input
ComputerName.domain.com
Eg Output
ComputerName
Is there any way to directly get the ComputerName of a system whose IP address is known?
I am looking for the same result as displayed using the Hostname command on the remote system.
Check the manual pages for getnameinfo
http://man7.org/linux/man-pages/man3/getnameinfo.3.html
According to the manual pages, you should set the NI_NOFQDN flags.
NI_NOFQDN
If set, return only the hostname part of the fully qualified
domain name for local hosts.
As suggested by emirc,
the following code is printing Computername:
struct sockaddr_in sa;
char str[INET_ADDRSTRLEN];
inet_pton(AF_INET, "192.168.23.4", &(sa.sin_addr));
struct sockaddr_in saGNI;
char hostname[NI_MAXHOST];
char servInfo[NI_MAXSERV];
u_short port = 27015;
saGNI.sin_family = AF_INET;
saGNI.sin_addr.s_addr = sa.sin_addr.s_addr;
saGNI.sin_port = htons(port);
DWORD dwRetval = getnameinfo((struct sockaddr *) &saGNI,
sizeof(struct sockaddr),
hostname,
NI_MAXHOST, servInfo, NI_MAXSERV, NI_NOFQDN);
printf("HostName: %s", hostname);
Note:
I have changed the flag from
NI_NUMERICSERV
to
NI_NOFQDN
You mean, you want to truncate the string before the first period?
std::string host(hostname);
size_t pos = host.find('.');
if (pos != std::string::npos)
{
host = host.substr(0,pos);
}
strcpy(hostname, host.c_str());
If you are interested in finding the host name of the computer on which the code is running, Boost.Asio could simplify the task:
#include <iostream>
#include <string>
#include <boost/asio.hpp>
int main() {
std::string hostname = boost::asio::ip::host_name();
std::cout << "hostname = " << hostname << std::endl;
}
Note that this needs to be compiled with the -lpthread option.
I am currently learning about the internet. I am trying to set up a simple proxy server that just forwards a request from the server side to its client side. Im currently following this tutorial. This is how far I have gotten:
#define MYPORT "3490" // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
int main(int argc, const char* argv[]) {
struct addrinfo hints;
struct addrinfo *res;
int sockIn;
int sockOut;
memset(&hints, 0, sizeof hints); // make sure its empty
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM; // what kind of socket
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
//listens on the hosts ip address:
getaddrinfo(NULL, MYPORT, &hints, &res);
// make a socket, bind it, and listen on it:
sockIn = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(sockIn, res->ai_addr, res->ai_addrlen);
listen(sockIn, BACKLOG);
freeaddrinfo(res); // free the linked-list
struct sockaddr_storage their_addr;
socklen_t addr_size;
char buf[512];
while(1) {
addr_size = sizeof their_addr;
struct sockaddr *addr = (struct sockaddr *)&their_addr;
sockOut = accept(sockIn, addr, &addr_size);
recv(sockOut, buf, sizeof buf, 0);
for (auto ch : buf) {
cout << ch;
}
close(sockOut);
}
}
Right now im just displaying "hi" on every page I visit.
Before I implement the client side of the proxy id like to instead display the HTTP Get Request that my browser sends to the server side of the proxy. My issue is that I dont know how to retrieve it. The guide I'm using is not adressering this.
Edit: I added a recv call that is suppose to read everything from the socket in to a buffer. Unfortunately it does not cout anything
download and install wireshark (packet sniffer), or else Fiddler Fiddler(HTTP proxy). You will easily be able to inspect HTTP traffic. I recommend you start with fiddler. Install on computer where your browser is located.
I am working on a server client project on Qt. The server is running in a machine with more than one network interface. The design is such that the client will discover the server automatically. ie the client will broadcast its IP to a network the server get that message and sends back the server's IP. The problem now is that when I try to get the IP in the server, There are more than 1 IP. How to get the IP of the interface through which server have received the message?
This might be a solution for you
IPAddress FindLocalIPAddressOfIncomingPacket( senderAddr )
{
foreach( adapter in EnumAllNetworkAdapters() )
{
adapterSubnet = adapter.subnetmask & adapter.ipaddress;
senderSubnet = adapter.subnetmask & senderAddr;
if( adapterSubnet == senderSubnet )
{
return adapter.ipaddress;
}
}
}
How to get your own (local) IP-Address from an udp-socket (C/C++)
In order to get the incoming peer IP address you can use following solution in C
socklen_t len;
struct sockaddr_storage addr;
char ipstr[INET6_ADDRSTRLEN];
int port;
len = sizeof addr;
getpeername(s, (struct sockaddr*)&addr, &len);
// deal with both IPv4 and IPv6:
if (addr.ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in *)&addr;
port = ntohs(s->sin_port);
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
} else { // AF_INET6
struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
port = ntohs(s->sin6_port);
inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
}
printf("Peer IP address: %s\n", ipstr);
Getting the source address of an incoming socket connection
I am writing a Java interposer (using LD_PRELOAD method) that modifies the recipient information in network communication system calls (connect/sendto).
Whenever Java tries to connect to another socket, I modify the intended recipient IP and port. Java uses IPv4-mapped-IPv6 addresses. So, I need to extract the IPv4 part of it. I achieve this using the method prescribed by Nicolas Bachschmidt at link.
The problem I am facing is that for every IPv4-mapped-IPv6 address, the result string (IPv4 part) I obtain is always 0.0.0.1. Instead it should be 10.0.0.1 (for ::ffff:10.0.0.1). I have tried this with different IP addresses. The result is always the same.
Two things I would like to mention that I think may be related:
When I tested the same program a month ago on my local network (that has 192.168.1.XXX IP addresses), the program worked correctly. Point being (I don't think) there is any problem with code. To verify this, I asked a question on stackoverflow to convert IPv4-mapped-IPv6 addresses to IPv4, the link of which is mentioned earlier).
I am trying to test this program now on my university network (that has 10.XXX.XXX.XXX IP addresses) and VirtualBox (NAT mode that also gives 10.XXX.XXX.XXX addresses). However, I have tried to connect to 10.0.0.1 and 12.0.0.1 in these cases. Both give 0.0.0.1.
What am I doing wrong?
UPDATE: In Java, socket connection is done by the usual method:
Socket conn = new Socket("10.0.0.1", 50021);
The code to interpose this connect() system call is as follows:
int connect(int fd, const struct sockaddr *sk, socklen_t sl)
{
struct sockaddr_in *lsk_in = (struct sockaddr_in *) sk;
struct sockaddr_in6 *lsk_in6 = (struct sockaddr_in6 *) sk;
struct sockaddr_in addr4;
unsigned int len;
int nbytes, oport, tport, ret, i;
char ip_address[30];
char buffer[1024];
char tempBuffer[1024];
if((lsk_in->sin_family == AF_INET) || (lsk_in->sin_family == AF_INET6))
{
if(lsk_in->sin_family == AF_INET)
{
oport = ntohs(lsk_in->sin_port);
memcpy(&addr4.sin_addr.s_addr, &lsk_in->sin_addr.s_addr, sizeof(addr4.sin_addr.s_addr));
}
else if(lsk_in->sin_family == AF_INET6)
{
oport = ntohs(lsk_in6->sin6_port);
//This is where the problem is. I always get 0.0.0.1
memcpy(&addr4.sin_addr.s_addr, lsk_in6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr));
}
memset(buffer, '\0', sizeof(buffer));
sprintf(buffer, "%s%c%s%c%i", NAT_VM_CONNECT_RULE, NAT_VM_DELIMITER, (char *)inet_ntoa(addr4.sin_addr), NAT_VM_DELIMITER, oport);
nbytes = send(sock, buffer, strlen(buffer), 0);
if(DEBUG_MODE)
fprintf(stdout, "[LD_INTERPOSER] Sent[%s]\n", buffer);
memset(buffer, '\0', sizeof(buffer));
nbytes = recv(sock, buffer, sizeof(buffer), 0);
fprintf(stderr, "[LD_INTERPOSER] Received CONNECT [%s]\n", buffer);
memset(ip_address, '\0', sizeof(ip_address));
int pos = strrchr(buffer, NAT_VM_DELIMITER) - buffer;
strncpy(ip_address, buffer, pos);
ip_address[pos] = '\0';
tport = atoi(buffer + pos + 1);
if(lsk_in->sin_family == AF_INET)
{
lsk_in->sin_addr.s_addr = inet_addr(ip_address + 7);
lsk_in->sin_port = htons(tport);
}
else if(lsk_in->sin_family == AF_INET6)
{
inet_pton(AF_INET6, ip_address, &(lsk_in6->sin6_addr));
lsk_in6->sin6_port = htons(tport);
}
fprintf(stderr, "[LD_INTERPOSER] IP[%s], Port[%d] for VM[%s]\n", ip_address, tport, vm_ip);
}
return real_connect(fd, sk, sl);
}
Thanks to #ugoren hex dump technique (in comments), I was able to figure out that the IPv6 structure itself contained a 0.0.0.1 address. I realized that the problem may be due to different JDKs. The Java project was built using OpenJDK 7 while the PC I was using had OpenJDK 6. When I updated the JDK to version 7, the error disappeared. However, it has landed me to another error which is documented at a new stackoverflow question which I am still unable to resolve.