πŸ“œ ⬆️ ⬇️

The solution to the task with pwnable.kr 07 - input. Understanding pwntools

image

In this article we will analyze the solution of a multi-level task using the pwntools library.

Organizational information
Especially for those who want to learn something new and develop in any of the areas of information and computer security, I will write and talk about the following categories:

  • PWN;
  • cryptography (crypto);
  • network technologies (Network);
  • reverse (Reverse Engineering);
  • steganography (Stegano);
  • search and exploitation of WEB-vulnerabilities.

In addition, I will share my experience in computer forensics, analysis of malware and firmware, attacks on wireless networks and local area networks, pentesting and writing exploits.

So that you can learn about new articles, software and other information, I created a channel in Telegram and a group to discuss any issues in the field of i & kb. I will also personally consider your personal requests, questions, suggestions and recommendations and answer all .

All information is presented solely for educational purposes. The author of this document does not bear any responsibility for any damage caused to anyone as a result of using the knowledge and methods obtained as a result of studying this document.

Solution job input


We click on the icon with the signature input, and we are told that we need to connect via SSH with the guest password.
')
image

When connected, we see the appropriate banner.

image

Let's find out what files are on the server, as well as what rights we have.

ls -l 

image

Thus, we can read the source code of the program, since there is a right to read for everyone and execute the input program with the owner's rights (the sticky bit is set). Let's review the outcome code.

Source code input.c
 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> int main(int argc, char* argv[], char* envp[]){ printf("Welcome to pwnable.kr\n"); printf("Let's see if you know how to give input to program\n"); printf("Just give me correct inputs then you will get the flag :)\n"); // argv if(argc != 100) return 0; if(strcmp(argv['A'],"\x00")) return 0; if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0; printf("Stage 1 clear!\n"); // stdio char buf[4]; read(0, buf, 4); if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0; read(2, buf, 4); if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0; printf("Stage 2 clear!\n"); // env if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0; printf("Stage 3 clear!\n"); // file FILE* fp = fopen("\x0a", "r"); if(!fp) return 0; if( fread(buf, 4, 1, fp)!=1 ) return 0; if( memcmp(buf, "\x00\x00\x00\x00", 4) ) return 0; fclose(fp); printf("Stage 4 clear!\n"); // network int sd, cd; struct sockaddr_in saddr, caddr; sd = socket(AF_INET, SOCK_STREAM, 0); if(sd == -1){ printf("socket error, tell admin\n"); return 0; } saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons( atoi(argv['C']) ); if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){ printf("bind error, use another port\n"); return 1; } listen(sd, 1); int c = sizeof(struct sockaddr_in); cd = accept(sd, (struct sockaddr *)&caddr, (socklen_t*)&c); if(cd < 0){ printf("accept error, tell admin\n"); return 0; } if( recv(cd, buf, 4, 0) != 4 ) return 0; if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0; printf("Stage 5 clear!\n"); // here's your flag system("/bin/cat flag"); return 0; } 


From the code it follows that we need to go through five levels. We will take them in turn.

image

At the first level, it is checked that the number of program arguments is 100. In this case, the 65th element should be the string β€œ\ x00”, and the 66th element should be β€œ\ x20 \ x0a \ x0d”. Create your own directory in the / tmp / directory and create a Python script there.

image

To solve the first level, we will create an array of one hundred lines 'A'. And assign the necessary values ​​to the necessary arguments. We can start the process with these arguments as follows:

 from pwn import * a = ['A']*100 a[0] = '/home/input2/input' a[ord('A')] = '\x00' a[ord('B')] = '\x20\x0a\x0d' ex = process(argv=a) ex.interactive() 

image

We passed the first level. Take a look at the second.

image

At this level, two lines are read, one and the standard input stdin, and the other from stderr. We need to create two files that will contain these lines.

image

Open streams to these files and specify the file stream of one file as a stdin descriptor, and another file as a stderr descriptor.

 from pwn import * a = ['A']*100 a[0] = '/home/input2/input' a[ord('A')] = '\x00' a[ord('B')] = '\x20\x0a\x0d' fin = open('/tmp/ex/in.txt', 'r') ferr = open('/tmp/ex/err.txt', 'r') ex = process(argv=a, stdin=fin, stderr=ferr) fin.close() ferr.close() ex.interactive() 

image

We proceed to the solution of the third level.

image

The getenv () function returns the value of an environment variable, which must be equal to the reference value. Thus, you need to create an environment variable with a specific value.

 from pwn import * a = ['A']*100 a[0] = '/home/input2/input' a[ord('A')] = '\x00' a[ord('B')] = '\x20\x0a\x0d' fin = open('/tmp/ex/in.txt', 'r') ferr = open('/tmp/ex/err.txt', 'r') e={'\xde\xad\xbe\xef':'\xca\xfe\xba\xbe'} ex = process(argv=a, stdin=fin, stderr=ferr, env=e) fin.close() ferr.close() ex.interactive() 

image

We coped with the environment variable, now we proceed to the fourth level.

image

By code, we can say that the program opens a file with the name β€œ\ x0a” and reads 4 characters from it, after which it compares them with the bytes β€œ\ x00”. Since both the characters themselves and the file name consist of unprintable characters, we use python.

image

image

Stayed last level. Let's get started

image

The program opens a socket on the port indicated in the 66th argument. Then it receives 4 bytes over the network and compares it with the reference string. We need to add one more argument to the program - the port number, establish a connection and send the necessary 4 bytes.

 from pwn import * a = ['A']*100 a[0] = '/home/input2/input' a[ord('A')] = '\x00' a[ord('B')] = '\x20\x0a\x0d' a[ord('C')] = '1234' fin = open('/tmp/ex/in.txt', 'r') ferr = open('/tmp/ex/err.txt', 'r') e={'\xde\xad\xbe\xef':'\xca\xfe\xba\xbe'} ex = process(argv=a, stdin=fin, stderr=ferr, env=e) fin.close() ferr.close() ex.interactive() 

image

image

That's all, get your points.

image

See you in the next articles!

Source: https://habr.com/ru/post/460249/


All Articles