Passing input with netcat to a simple server - ruby

I am trying to write an Ruby script to pass strings to a simple server running in a VM and I am stuck at passing the strings without creating inifinite loops in my server program.
The Content of the Server(written in C):
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORTNO 12346
int h=0,b=0,p=0;
#define BUFFER_SIZE 512
int checksec(FILE* f){
FILE* key;
char buf[1024];
if(h&b&p){
key=fopen("easy_key","r");
fread(buf,1024,1,key);
fprintf(f,"%s",buf);
fclose(key);
return 0;
}
return 1;
}
void hekers(FILE* f){
volatile int zeroWeekend;
char buf[32];
fprintf(f,"So you want to be an 31337 Hax0r?\n");
fgets(buf,40,f);
switch(strcmp("y3$\n",buf)){
case 0:
fprintf(f,"First you must get power\n");
break;
default:
fprintf(f,"Well then go away\n");
break;
}
if(zeroWeekend==0xcafebabe){
h=1;
}
return;
}
void batmenss(FILE* f){
volatile int batsignet;
char buf[32];
fprintf(f,"So you want to be the batman?\n");
fgets(buf,40,f);
switch(strcmp("YESSSSSSS\n",buf)){
case 0:
fprintf(f,"First you must get rich\n");
break;
default:
fprintf(f,"Well then go away\n");
break;
}
if(batsignet==0x12345678){
b=1;
}
return;
}
void pokemans(FILE* f){
volatile int pikachy;
char buf[32];
fprintf(f,"So you want to be the best there ever was?\n");
fgets(buf,40,f);
switch(strcmp("catchemall\n",buf)){
case 0:
fprintf(f,"First you must get respect\n\n");
break;
default:
fprintf(f,"Well then go away\n");
break;
}
if(pikachy==0xfa75beef){
p=1;
}
return;
}
void readInput(int sock){
int msg;
char choice[4];
char buffer[BUFFER_SIZE];
FILE* fptr = fdopen(sock, "r+");
char* prompt="Do you want to be a?\n"
"1.) Pokemon Master\n"
"2.) Elite Hacker\n"
"3.) The Batman\n";
while(checksec(fptr)){
fprintf(fptr,"%s",prompt);
fgets(choice,4,fptr);
switch(choice[0]){
case '1':
pokemans(fptr);
break;
case '2':
hekers(fptr);
break;
case '3':
batmenss(fptr);
break;
default:
fprintf(fptr,"\nThat is not one of the choices\n");
fflush(fptr);
}
}
fprintf(fptr, "%s", buffer);
fflush(fptr);
fclose(fptr);
return;
}
int main(int argc, char *argv[])
{
char buffer[BUFFER_SIZE];
int sockfd, newsockfd, portno, pid;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
/*
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0){
perror("ERROR opening socket");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
//portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
serv_addr.sin_port = htons(PORTNO);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0){
perror("ERROR on binding");
exit(1);
}
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
perror("ERROR on accept");
pid = fork();
if (pid < 0)
perror("ERROR on fork");
if (pid == 0) {
close(sockfd);
readInput(newsockfd);
return;
}
else close(newsockfd);
waitpid(-1,NULL,WNOHANG);
} /* end of while */
close(sockfd);
return 0; /* we never get here */
}
When I connect to the server, it looks like this:
user#DESKTOP-LINUX:~/Documents/tob/ctf/exploits/binary1_workshop/easy$ nc 192.168.178.40 12346
Do you want to be a?
1.) Pokemon Master
2.) Elite Hacker
3.) The Batman
Now the Program waits for an input and another string will be printed and then the Program waits for another input and so on...
Now the real problem comes when I try to use a Ruby Script that should dictate the input that the Program should get.
I tried it with this Ruby Script (Filename: script.rb):
#!/usr/bin/env ruby
firstinput = "1"
puts select + "\r\n"
secondinput = "2"
puts secondinput + "\r\n"
And executed it with this command:
user#DESKTOP-LINUX:~/Documents/Code/binary1_workshop_exploits$ ./script.rb | nc 192.168.178.40 12346
But the output is just an infinite loop of the "main menu"...
How do I fix this problem?
P.S. I am running Ubuntu 14.04 64-Bit and the VM with the Server is running Ubuntu 14.04 32-Bit

Related

`ioctl` to read and write GPIO: invalid argument

I'm imitating the gpio-hammer example in Linux source code. I'm using Raspberry Pi 3B+ and want an LED to blink.
Here's what I do:
#include <linux/gpio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
int main(int argc, const char **argv) {
int fd, ret;
struct gpiohandle_request req;
struct gpiohandle_data data;
char *gpio_dev_name = "/dev/gpiochip0";
unsigned int gpio_line = 8;
memset(&data.values, 0, sizeof(data.values));
// open device
fd = open(gpio_dev_name, 0);
if (fd == -1) {
fprintf(stderr, "Failed to open %s, %s\n",
gpio_dev_name, strerror(errno));
}
// request gpio output
req.lineoffsets[0] = gpio_line;
req.flags = GPIOHANDLE_REQUEST_OUTPUT | GPIOHANDLE_REQUEST_ACTIVE_LOW;
strcpy(req.consumer_label, "blink");
req.lines = 1;
memcpy(req.default_values, &data, sizeof(req.default_values));
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
if (ret == -1) {
fprintf(stderr, "Failed to issue %s (%d), %s\n",
"GPIO_GET_LINEHANDLE_IOCTL", ret, strerror(errno));
}
// blink
while (1) {
// read data
ret = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
if (ret == -1) {
ret = -errno;
fprintf(stderr, "Failed to issue %s (%d), %s\n",
"GPIOHANDLE_GET_LINE_VALUES_IOCTL", ret, strerror(errno));
exit(ret);
}
// flip digits
data.values[0] = !data.values[0];
// set data
ret = ioctl(fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret == -1) {
ret = -errno;
fprintf(stderr, "Failed to issue %s (%d), %s\n",
"GPIOHANDLE_SET_LINE_VALUES_IOCTL", ret, strerror(errno));
exit(ret);
}
// delay
sleep(1);
}
}
I can compile the gpio-hammer example on RPi and run it with ./gpio-hammer -n gpiochip0 -o 8. Attached to gpiochip0 line8 is an LED and it blinks.
But my program does not work. It fails with
Failed to issue GPIOHANDLE_GET_LINE_VALUES_IOCTL (-22), Invalid argument
I looked into the implement of gpiolib. The ioctl of gpio line handle returns EINVAL (22) if ioctl cmd is not GPIOHANDLE_GET_LINE_VALUES_IOCTL nor GPIOHANDLE_SET_LINE_VALUES_IOCTL. But that's not the case. What's going wrong?
In linux/gpio.h, the description of struct gpiohandle_request says:
/*
* ...
* #fd: if successful this field will contain a valid anonymous file handle
* after a GPIO_GET_LINEHANDLE_IOCTL operation, zero or negative value
* means error
*/
struct gpiohandle_request {
__u32 lineoffsets[GPIOHANDLES_MAX];
__u32 flags;
__u8 default_values[GPIOHANDLES_MAX];
char consumer_label[32];
__u32 lines;
int fd;
};
When use GPIO_GET_LINEHANDLE_IOCTL, the file handle of GPIO chip device is passed through the first argument of ioctl(), and another file handle will be sent back in gpiohandle_request::fd, if the operation successes. This new fd should be used in ioctl of GPIO_GET_LINE_VALUES_IOCTL or GPIO_SET_LINE_VALUES_IOCTL.
So the code should be
ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
if (ret == -1) {
fprintf(stderr, "Failed to issue %s (%d), %s\n",
"GPIO_GET_LINEHANDLE_IOCTL", ret, strerror(errno));
}
else {
if (close(fd) == -1) {
fprintf(stderr, "Failed to close GPIO char dev.\n");
}
fd = req.fd;
}

Reading and printing last N characters

I have a program that I want to use to read a file and output its last N characters (could be 50 or whatever that I have coded). From my piece of code, I get output that is question marks in diamond boxes,(unsupported unicode?)
I'm using lseek to set the cursor, could someone please assist me?
int main(int argc,char *argv[]){
int fd; //file descriptor to hold open info
int count=0; //to hold value of last 200th char number
char ch; //holds read char
char* outputString = "The file does not exist!\n";
if(!access("myFile.txt",F_OK)==0){
write(2,outputString,strlen(outputString));
exit(1);
}
fd = open("myFile.txt",O_RDONLY| O_NONBLOCK);
int ret = lseek(fd,200,SEEK_END); //get position of the last 200th item
while (ret!=0) {
write(1, &ch,1);
ret--;
}
close(fd);
return(0);
}
I don't want to use <stdio.h> functions so I'm using the file descriptors not making a FILE* object.
I slightly modified your attempt. The lseek(fd, 200, SEEK_END) seeks the file 200 characters past the end of file. If you want to read last 200 character from a file, you need to seek to 200 character to end of file, ie lseek(fd, -200, SEEK_END).
I places some comments in code to help explaining.
// please include headers when posting questions on stackoverflow
// It makes it way easier to reproduce and play with the code from others
#include <unistd.h>
#include <error.h>
// I use glibc error(3) to handle errors
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int argc,char *argv[]){
// no idea if a typo, myFile.txt != logfile.txt
if(!access("myFile.txt", F_OK) == 0) {
error(1, errno, "The file does not exist!");
exit(1);
}
int fd = open("logfile.txt", O_RDONLY | O_NONBLOCK);
if (fd == -1) {
error(1, errno, "Failed opening the file");
}
// move cursor position to the 200th characters from the end
int ret = lseek(fd, -200, SEEK_END);
if (ret == -1) {
error(1, errno, "Failed seeking the file");
}
// we break below
while (1) {
char ch = 0; // holds read char
ssize_t readed = read(fd, &ch, sizeof(ch));
if (readed == 0) {
// end-of-file, break
break;
} else if (readed == -1) {
// error handle
// actually we could handle `readed != 1`
error(1, errno, "Error reading from file");
}
// output the readed character on stdout
// note that `STDOUT_FILENO` as more readable alternative to plain `1`
write(STDOUT_FILENO, &ch, sizeof(ch));
}
close(fd);
return 0;
}

Read binary data from QProcess in Windows

I have some .exe file (say some.exe) that writes to the standard output binary data. I have no sources of this program. I need to run some.exe from my C++/Qt application and read standard output of the process I created. When I'm trying to do this with QProcess::readAll someone replaces byte \n (0x0d) to \r\n (0x0a 0x0d).
Here is a code:
QProcess some;
some.start( "some.exe", QStringList() << "-I" << "inp.txt" );
// some.setTextModeEnabled( false ); // no effect at all
some.waitForFinished();
QByteArray output = some.readAll();
I tried in cmd.exe to redirect output to file like this:
some.exe -I inp.txt > out.bin
and viewed out.bin with hexedit there was 0a 0d in the place where should be 0d.
Edit:
Here is a simple program to emulate some.exe behaviour:
#include <stdio.h>
int main() {
char buf[] = { 0x00, 0x11, 0x0a, 0x33 };
fwrite( buf, sizeof( buf[ 0 ] ), sizeof( buf ), stdout );
}
run:
a.exe > out.bin
//out.bin
00 11 0d 0a 33
Note, that I can't modify some.exe that's why I shouldn't modify my example like _setmode( _fileno( stdout, BINARY ) )
The question is: how can I say to QProcess or to Windows or to console do not change CR with LF CR?
OS: Windows 7
Qt: 5.6.2
how can I say to QProcess or to Windows or to console do not change CR with LF CR?
They don't change anything. some.exe is broken. That's all. It outputs the wrong thing. Whoever made it output brinary data in text mode has messed up badly.
There's a way to recover, though. You have to implement a decoder that will fix the broken output of some.exe. You know that every 0a has to be preceded by 0d. So you have to parse the output, and if you find a 0a, and there's 0d before it, remove the 0d, and continue. Optionally, you can abort if a 0a is not preceded by 0d - some.exe should not produce such output since it's broken.
The appendBinFix function takes the corrupted data and appends the fixed version to a buffer.
// https://github.com/KubaO/stackoverflown/tree/master/questions/process-fix-binary-crlf-51519654
#include <QtCore>
#include <algorithm>
bool appendBinFix(QByteArray &buf, const char *src, int size) {
bool okData = true;
if (!size) return okData;
constexpr char CR = '\x0d';
constexpr char LF = '\x0a';
bool hasCR = buf.endsWith(CR);
buf.resize(buf.size() + size);
char *dst = buf.end() - size;
const char *lastSrc = src;
for (const char *const end = src + size; src != end; src++) {
char const c = *src;
if (c == LF) {
if (hasCR) {
std::copy(lastSrc, src, dst);
dst += (src - lastSrc);
dst[-1] = LF;
lastSrc = src + 1;
} else
okData = false;
}
hasCR = (c == CR);
}
dst = std::copy(lastSrc, src, dst);
buf.resize(dst - buf.constData());
return okData;
}
bool appendBinFix(QByteArray &buf, const QByteArray &src) {
return appendBinFix(buf, src.data(), src.size());
}
The following test harness ensures that it does the right thing, including emulating the output of some.exe (itself):
#include <QtTest>
#include <cstdio>
#ifdef Q_OS_WIN
#include <fcntl.h>
#include <io.h>
#endif
const auto dataFixed = QByteArrayLiteral("\x00\x11\x0d\x0a\x33");
const auto data = QByteArrayLiteral("\x00\x11\x0d\x0d\x0a\x33");
int writeOutput() {
#ifdef Q_OS_WIN
_setmode(_fileno(stdout), _O_BINARY);
#endif
auto size = fwrite(data.data(), 1, data.size(), stdout);
qDebug() << size << data.size();
return (size == data.size()) ? 0 : 1;
}
class AppendTest : public QObject {
Q_OBJECT
struct Result {
QByteArray d;
bool ok;
bool operator==(const Result &o) const { return ok == o.ok && d == o.d; }
};
static Result getFixed(const QByteArray &src, int split) {
Result f;
f.ok = appendBinFix(f.d, src.data(), split);
f.ok = appendBinFix(f.d, src.data() + split, src.size() - split) && f.ok;
return f;
}
Q_SLOT void worksWithLFCR() {
const auto lf_cr = QByteArrayLiteral("\x00\x11\x0a\x0d\x33");
for (int i = 0; i < lf_cr.size(); ++i)
QCOMPARE(getFixed(lf_cr, i), (Result{lf_cr, false}));
}
Q_SLOT void worksWithCRLF() {
const auto cr_lf = QByteArrayLiteral("\x00\x11\x0d\x0a\x33");
const auto cr_lf_fixed = QByteArrayLiteral("\x00\x11\x0a\x33");
for (int i = 0; i < cr_lf.size(); ++i)
QCOMPARE(getFixed(cr_lf, i), (Result{cr_lf_fixed, true}));
}
Q_SLOT void worksWithCRCRLF() {
for (int i = 0; i < data.size(); ++i) QCOMPARE(getFixed(data, i).d, dataFixed);
}
Q_SLOT void worksWithQProcess() {
QProcess proc;
proc.start(QCoreApplication::applicationFilePath(), {"output"},
QIODevice::ReadOnly);
proc.waitForFinished(5000);
QCOMPARE(proc.exitCode(), 0);
QCOMPARE(proc.exitStatus(), QProcess::NormalExit);
QByteArray out = proc.readAllStandardOutput();
QByteArray fixed;
appendBinFix(fixed, out);
QCOMPARE(out, data);
QCOMPARE(fixed, dataFixed);
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
if (app.arguments().size() > 1) return writeOutput();
AppendTest test;
QTEST_SET_MAIN_SOURCE_PATH
return QTest::qExec(&test, argc, argv);
}
#include "main.moc"
Unfortunately it has nothing to do with QProcess or Windows or console. It's all about CRT. Functions like printf or fwrite are taking into account _O_TEXT flag to add an additional 0x0D (true only for Windows). So the only solution is to modify stdout's fields of your some.exe with WriteProcessMemory or call the _setmode inside an address space of your some.exe with DLL Injection technique or patch the lib. But it's a tricky job.

Shell Program in C, running executable in background

I am writing a simple shell program in C and I believe I have it just about finished. The program should continually print "Prompt>" and wait for a user to either enter the name of an executable along with any parameters the executable needs. The shell only has one built in function, quit, which ends the program. If the user were to put an '&' at the end of the line then the given executable should be run in the background. (Built-in functions and commands without the '&' should run in the foreground and wait for the child process to finish.) However when I run my code and put an '&' at the end of my line, the executable runs and finishes but I no longer see the "prompt>" show up. I can still enter the name of an executable or quit and it runs and everything but I don't understand why the prompt isn't showing up.
Also as a side question. Is my program properly handling child processes? Basically, am I not leaving zombie processes with this code?
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#define MAXBUFF 100
#define MAXLINE 200
int parse_line(char *buffer, char **arg_array);
void evaluate_commandline(char *commandline);
int builtin_command();
int parse_line(char *buffer, char **arg_array){
char *delimiter;
int num_args;
int run_background;
buffer[strlen(buffer)-1] = ' ';
while(*buffer && (*buffer == ' '))
buffer++;
num_args = 0;
while((delimiter = strchr(buffer, ' '))){
arg_array[num_args++] = buffer;
*delimiter = '\0';
buffer = delimiter + 1;
while(*buffer && (*buffer == ' '))
buffer++;
}
arg_array[num_args] = NULL;
if(num_args == 0)
return 1;
if((run_background = (*arg_array[num_args-1] == '&')) != 0)
arg_array[--num_args] = NULL;
return run_background;
}
void evaluate_commandline(char *commandline){
char *arg_array[MAXBUFF];
char buffer[MAXLINE];
int run_background;
pid_t pid;
strcpy(buffer, commandline);
run_background = parse_line(buffer, arg_array);
if(arg_array[0] == NULL)
return;
if(!builtin_command(arg_array)){
if((pid = fork())== 0){
if(execvp(arg_array[0],arg_array)< 0){
printf("%s: Command not found.\n", arg_array[0]);
exit(0);
}
}
if(!run_background){
int child_status;
wait(&child_status);
}
}
return;
}
int builtin_command(char **arg_array){
if(!strcmp(arg_array[0],"quit"))
exit(0);
return 0;
}
int main(){
char commandline[MAXLINE];
while(1){
printf("prompt> ");
fgets(commandline, MAXLINE, stdin);
if(feof(stdin))
exit(0);
evaluate_commandline(commandline);
}
}
i think where you say:
if(!run_background){
you forget a "else"
else if(!run_background){

when long option is given as argument to short option - getopt_long

I was learning how to accept command line arguments using getopt_long function, I made 2 long options 'filename' (required arg) and 'clear' (no arg) and 2 short args 'a' (with arg) and 'b' (no arg) when i executed:
$ ./a.out -a --filename=test.txt
instead of showing 'a' has no arg it shows the optarg for 'a' is:
--filename=text.txt and skips the filename long option
Any work around for this?
My code is:
#include <iostream>
#include <getopt.h>
using namespace std;
int main(int argc, char* argv[]){
static struct option long_options[] = {
{"filename",1,0,0},
{"clear",0,0,0},
{NULL,0,0,0}
};
int op,option_index = 0;
string filename;
while((op = getopt_long(argc,argv,"a:b",long_options,&option_index))!=-1){
switch (op){
case 0:
switch(option_index){
case 0:
filename = optarg;
cout<<filename<<endl;
break;
case 1:
cout<<"clear is yes\n";
break;
default:
cout<<"Please enter valid long option\n";
break;
}break;
case 'a':
cout<<"a is set as "<<optarg<<endl;
//cout<<optarg<<endl;
break;
case 'b':
cout<<"b is set"<<endl;
break;
default:
cout<<"Please enter valid Arguments"<<endl;
break;
}
}
cout<<"\n\n";
return 0;
}
I found a better Answer, my friend told me this.
I could directly use :: instead of : that means 'a' requires an optional argument so getopt_long will check whether the arg is an option or not if there is no arg or arg is an option 0 is returned which I can handle separately and if 'a' has non option arg is there that situation is handled normally.
The final code stands as:
#include <iostream>
#include <getopt.h>
using namespace std;
int main(int argc, char* argv[]){
static struct option long_options[] = {
{"filename",1,0,0},
{"clear",0,0,0},
{NULL,0,0,0}
};
int op,option_index = 0;
string filename;
while((op = getopt_long(argc,argv,"a::b",long_options,&option_index))!=-1){
switch (op){
case 0:
switch(option_index){
case 0:
filename = optarg;
cout<<filename<<endl;
break;
case 1:
cout<<"clear is yes\n";
break;
default:
cout<<"Please enter valid long option\n";
break;
}break;
case 'a':
if(optarg)
cout<<"a is set as "<<optarg<<endl;
else
cout<<"a needs an argument"<<endl;
//cout<<optarg<<endl;
break;
case 'b':
cout<<"b is set"<<endl;
break;
default:
cout<<"Please enter valid Arguments"<<endl;
break;
}
}
cout<<"\n\n";
return 0;
}
There is no need of hard-coding anything in this.
One way is to look at the argument to -a and see if it's really an option. If so, handle the error and set optind -= 1 so that further processing by getopt_long() will treat the option that incorrectly followed -a as an option. Not particularly elegant, but it works.
Here's an example:
#include <iostream>
#include <getopt.h>
#include <string.h>
using namespace std;
int str_startswith( char const* s, char const* prefix)
{
return strncmp(prefix, s, strlen(prefix)) == 0;
}
bool is_option(char const* arg)
{
int result = 0;
result = result || str_startswith( arg, "--filename=");
result = result || (strcmp( arg, "--clear") == 0);
result = result || (strcmp( arg, "-b") == 0);
return result;
}
int main(int argc, char* argv[]){
static struct option long_options[] = {
{"filename",1,0,0},
{"clear",0,0,0},
{NULL,0,0,0}
};
int op,option_index = 0;
string filename;
while((op = getopt_long(argc,argv,"a:b",long_options,&option_index))!=-1){
switch (op){
case 0:
switch(option_index){
case 0:
filename = optarg;
cout << "filename is: " <<filename<<endl;
break;
case 1:
cout<<"clear is yes\n";
break;
default:
cout<<"Please enter valid long option\n";
break;
}break;
case 'a':
if (is_option(optarg)) {
cout << "-a option requires an argument" << endl;
optind -= 1; // put the option back into consideration for getopt_long()
}
else {
cout << "a is set as " << optarg << endl;
}
break;
case 'b':
cout<<"b is set"<<endl;
break;
default:
cout<<"Please enter valid Arguments"<<endl;
break;
}
}
cout<<"\n\n";
return 0;
}
One way I'd look to improve this is to have the function that checks if an argument is potentially an option is to have it look through he same structures as getopt_long() (long_options[] and the string argument to getopt_long()) instead of hard-coding it like in my quick-n-dirty example.
In fact, since this is the second time in a few weeks I've come across this question on SO (I can't find the other one), it might pay to create a wrapper for getopt_long() and friends that provides a helper function do exactly this. Maybe I'll work on that later this weekend...

Resources