I am really new to C and especially with socket programming so basically I have setup apache server on my local machine where I am hosting multiple audio/video/txt files.
Now I want to display those files using C. (just like ls -l in linux but it should be from the server)
I am able to fetch the html content of local server but that is something not I am looking for.
Here is my code for getting html content from the localhost
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
int main()
{
int socket_desc;
struct sockaddr_in server;
char *message , server_reply[6000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("192.168.1.3"); // localhost ip
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
//Connect to remote server
if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected\n");
//Send some data
message = "GET /?st=1 HTTP/1.1\r\nHost: 192.168.1.3\r\n\r\n";
if( send(socket_desc , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
//Receive a reply from the server
if( recv(socket_desc, server_reply , 6000 , 0) < 0)
{
puts("recv failed");
}
puts("Reply received\n");
puts(server_reply);
return 0;
}
Q: Are you trying to run this application on "Server A" and get a listing of files on "Server B"?
--
Thanks for the update to that.
Here is the problem, you are not going to be able to get a directory listing from one server to the other just by sending a standard http request. You will need a reciprocal application on "Server B". Do you have direct access to that server, or is this a public server and you are trying to mirror it?
Related
I wanted to send data from my C code using libc websocket library to my node-red Server.
the code in c below :
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
int main(int argc , char *argv[])
{
int socket_desc;
struct sockaddr_in server;
char *message , server_reply[2000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr(myIpaddr);
server.sin_family = AF_INET;
server.sin_port = htons( 1880 );
//Connect to remote server
if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected\n");
//Send some data
message = "SensorDataTest";
if( send(socket_desc , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
//Receive a reply from the server
if( recv(socket_desc, server_reply , 2000 , 0) < 0)
{
puts("recv failed");
}
puts("Reply received\n");
puts(server_reply);
return 0;
}
The probleme is in Node-red I have to specify the path of the socket for example when I send data from a Javascript code I use this address :
ws://myipaddr:1880/pathofsocket.
Now what I want to know is how I can add the "pathofsocket" to my c code.
Thanks.
I am trying to make a translator in C using Google's translator API.
So far i've been able to create sockets, initialize them and connect them.
I've sent the url that is supposed to be translating the text, but the reply size is zero bytes. The objective is to perhaps receive it as a text file or just a string.
This is the code so far.
#include<stdio.h>
#include<winsock2.h>
#include "count.c"
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
char *message , server_reply[2000];
int recv_size;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
// Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
system("ping translate.googleapis.com");
const char* ipadress;
printf("Enter IP adress of Hostname\n");
scanf("%s",ipadress);
server.sin_addr.s_addr = inet_addr(ipadress);
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
// Connect to remote server
if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected");
// Send some data
message = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=da&dt=t&q=Hello";
if( send(s , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
// Receive a reply from the server
if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR)
{
puts("recv failed");
}
puts("Reply received\n");
// Add a NULL terminating character to make it a proper string before printing
server_reply[recv_size] = '\0';
printf("size: %d\n",recv_size);
puts(server_reply);
return 0;
}
Two problems. Firstly, you can't just send the URL by itself; you need to make an HTTP request. The best way to do this is often to use a third-party library like LibCURL, but for very simple cases you might prefer to do it by hand. At the very least you'd need a GET line, a Host: header and a blank line. See the HTTP RFC for how to format a request and parse the response.
Secondly, if you want to use HTTPS, you can't just send plain text to a socket, there is also an encryption layer. Again, you will need a library. (On Linux I would use OpenSSL or libCURL, which also exist on Windows but there may be other choices there.) By the way, by default HTTP uses port 80 but HTTPS uses port 443.
#include<stdio.h>
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s;
struct sockaddr_in server;
char *message , server_reply[2000];
int recv_size;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
server.sin_addr.s_addr = inet_addr("74.125.235.20");
server.sin_family = AF_INET;
server.sin_port = htons( 80 );
//Connect to remote server
if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected");
//Send some data
message = "GET / HTTP/1.1\r\n\r\n";
if( send(s , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
//Receive a reply from the server
if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR)
{
puts("recv failed");
}
puts("Reply received\n");
//Add a NULL terminating character to make it a proper string before printing
server_reply[recv_size] = '\0';
puts(server_reply);
return 0;
}
My output
Your output shows that your code passed the "Socket created", but didn't reach the "Connected". As you have no "connect error", connect() didn't yet fail. As you have no abort either, it is highly probable that you're stuck waiting for the connection to be established.
One way to test it would be to try open the address directly in the browser with http://<ip address> (equivalent to talking to port 80)
According to this site, the address you are talking to belongs to google, but has its port 80 closed. It is possible that security measures on google side make the rejection of the connection to be filtered. THis could explain why you experience a long timeout instead of a quick failure message.
So another way to test your code would be to use the address of a valid http server. TO find one, run your command line, type "ping google.com" and take the address that is displayed for the ping requests in your programme. The connection will then succeed.
Quoting from wikipedia:
The range of port numbers from 1024 to 49151 are the registered ports.
They are assigned by IANA for specific service upon application by a
requesting entity.[1] On most systems, registered ports can be used by
ordinary users.
That means that any port bellow 1024 will not work as they are already assigned.
For a class assignment, I am told to use a xss attack to steal a cookie. We are given a VM to work on and a client from which to steal the cookie. We have the ability to use telnet to make the client go to any url we want, but are unable to view directly what happens. We were given a website that is on another server that is vulnerable. Since the network is closed and the client is only able to visit sites hosted by either the provided server or my VM, my professor suggested that I write a simple C server, have it listen on a specific port, and send the cookie through to allow my server to print it.
Here is the server I am using. It is listening on port 8888.
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Receive a message from client
while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
//write(client_sock , client_message , strlen(client_message));
printf("%s \n",client_message);
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
I have gotten to where I can use an XSS attack to get connected to my server, but do not know how to send across the cookie. I know it is stored in document.cookie. Trying ...WEBSITEURL...?user="><script>window.open("http://localhost:8888")</script> with the url of the vulnerable site establishes a connection to my server (my server says so), but I do not know what to do from here.Do I need to modify my server in some way to accept a certain kind of input? I have tried ..localhost:8888?test" and I get a 404 error.
IN SHORT: How can I use a xss attack to send a cookie to a C server?
while testing this code i figured out this echo server work well for one word.if try to echo a sentence server also echo it but after that it echo inputs with previous echoed sentence last word. i cleared buffers using memset but still get same problem. cannot understand where is the problem.
server code
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Receive a message from client
memset(client_message, 0, sizeof(client_message));
while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
write(client_sock , client_message , strlen(client_message));
memset(client_message, 0, sizeof(client_message));
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
client code :
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
puts("Connected\n");
//keep communicating with server
while(1)
{
printf("Enter message : ");
//scanf("%s" , message);
fgets(message, sizeof(message), stdin);
//Send some data
if( send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
//Receive a reply from the server
if( recv(sock , server_reply , 2000 , 0) < 0)
{
puts("recv failed");
break;
}
puts("Server reply :");
puts(server_reply);
memset(message, 0, sizeof(message));
memset(server_reply, 0, sizeof(server_reply));
}
close(sock);
return 0;
}
Sample outputs
Enter message : sample
Server reply :
sample
Enter message : sample test
Server reply :
sample test
Enter message : gamer
Server reply :
gamer
test
Enter message : pro
Server reply :
pro
r
test
Your problem is this line:
write(client_sock , client_message , strlen(client_message));
Your client does not send a \0 terminator. So if you first send a long string, then a short one then the short one will overwrite just the beginning. Change that to:
write(client_sock , client_message , read_size); // send exactly as much as you got
And on the client side print only as much as was received:
ssize_t answer_size;
if((answer_size = recv(sock , server_reply , sizeof(server_reply) , 0)) < 0)
{
puts("recv failed");
break;
}
printf("Server reply :\n%.*s\n", answer_size, server_reply);
Also please keep in mind that for implementation specific reasons you may or not get everything that was sent with the first recv and it is recommended to run it in a while loop (with nonblocking mode if nessesary). Same goes for send.
The send() and receive() functions are both blocking and will only return when the socket closes or a full buffer is processed. Your client code defines message[1000], while your server code waits for a client_message[2000] array before responding.
Unless you want to end up using select() or asynchronous I/O to recover the actual network-level messages you will need to either prefix the message with a length that allows you to limit the reads to the actual data, or to use a terminator and then process the incoming data character by character. OF these the most straight-forward is to include an explicit message length early into the stream at the start of each exchange.
The incorrect responses are because you reuse the sending buffer without clearing it. If you include a memset(message, 0, 1000) at the beginning of the while() you will avoid the problem.
The underlying problem is that your client will always send the entire buffer even if only a few characters contain data of value. The effect of this on your application will depend on the network speed, message frequency, number of parties in the landscape and host capacity to tolerate the inefficiency.