Security_RNRF
0x26. 본문
26. First steps into networking with net0 from exploit.education protostar - bin.0x19
: Now we move on to networking issues in the Explorers exercise.
-> Some basics need to be set first.
-> In the description, you must convert the string to a small endian integer
: C Code(/opt/protostar/bin/net0)
#include "../common/common.c"
#define NAME "net0"
#define UID 999
#define GID 999
#define PORT 2999
void run()
{
unsigned int i;
unsigned int wanted;
wanted = random();
printf("Please send '%d' as a little endian 32bit int\n", wanted);
if(fread(&i, sizeof(i), 1, stdin) == NULL) {
errx(1, ":(\n");
}
if(i == wanted) {
printf("Thank you sir/madam\n");
} else {
printf("I'm sorry, you sent %d instead\n", i);
}
}
int main(int argc, char **argv, char **envp)
{
int fd;
char *username;
/* Run the process as a daemon */
background_process(NAME, UID, GID);
/* Wait for socket activity and return */
fd = serve_forever(PORT);
/* Set the client socket to STDIN, STDOUT, and STDERR */
set_io(fd);
/* Don't do this :> */
srandom(time(NULL));
run();
}
: This level is very easy, but not enough code to fully understand the situation.
-> Let's think about the reason.
-> "main" calls the "background_process" function and forwards the name and user and group.
-> This function is not a typical "libc" function.
-> You can also see "/etc/passwd" for the user "ID 999" and that there is no such "ID".
-> cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
Debian-exim:x:101:103::/var/spool/exim4:/bin/false
statd:x:102:65534::/var/lib/nfs:/bin/false
sshd:x:103:65534::/var/run/sshd:/usr/sbin/nologin
protostar:x:1000:1000:protostar,,,:/home/protostar:/bin/bash
user:x:1001:1001::/home/user:/bin/sh
-> id
uid=1001(user) gid=1001(user) groups=1001(user)
-> None “999”
-> This may seem strange, but it is not abstract about computers.
-> What does having a user on a Linux computer mean?
-> In the end, the user is the same as the ID, number of memory, and file owner.
-> The owner number of this file means that it is this file.
-> Now if the user is listed in the "/etc/passwd" file, "linux" will use the name instead of the number, but still an integer under the hood.
-> Therefore, they are free to use even if they do not have a name assigned to that "ID
: Return to the code again.
-> Other features such as "background_process" and "serve_forever" and "set_io" are also not known.
-> And if you look at "include," you can see that you refer to the "common.c" file.
: The author of this task embodied many codes in other files.
-> We don't know what it is.
-> However, one function is here and is a "run()" function.
-> You can see it called at the end of "main()".
-> The "run()" function informs you that any number must be generated and sent to Little Endian.
-> Then, perform a read from the file's disk.
-> This input is numeric and compares whether it is the same as the previous random number.
(2:13) -> It's a simple test.
: As I said earlier, we don't know about the unknown function below, but we can solve the problem.
-> Because you can know everything you need to know by reading the annotations and function names.
-> But, as you know, ignoring the basic concept is not enough for this channel.
: And these functions embody two interesting concepts mentioned here.
-> One is about the process as a daemon, the other is about networking and sockets.
: So what should we do?
-> We already know everything we need to reverse engineer this.
: Start by looking at the program's behavior before you begin.
-> ./net0
-> Nothing happens when you try to run a program.
-> ps aux | grep net0
999 1650 0.0 0.0 1532 272 ? Ss Oct31 0:00 /opt/protostar/bin/net0
user 6485 0.0 0.0 3296 728 pts/1 S+ 10:07 0:00 grep net0
-> However, the running process shows that "net0" is already running.
-> You can now quickly switch to the root user to end and start the process.
-> su root
Password:(godmode)
-> By default, the default root password for this "VM" is "godmode".
-> kill 1650
-> ps aux | grep net0
root 6500 0.0 0.0 3296 728 pts/1 S+ 10:11 0:00 grep net0
-> You can now exit "net0" and verify that it is no longer running.
-> ./net0
-> Try "net0" again.
-> There is no response this time again.
-> ps aux | grep net0
999 6502 0.0 0.0 1532 276 ? Ss 10:14 0:00 ./net0
root 6504 0.0 0.0 3296 728 pts/1 S+ 10:14 0:00 grep net0
-> However, checking the process shows that the process is running again.
-> Let's kill again and start with "strace."
-> kill 6502
-> strace ./net0
execve("./net0", ["./net0"], [/* 15 vars */]) = 0
brk(0) = 0x804b000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe0000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=13796, ...}) = 0
mmap2(NULL, 13796, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fdc000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320m\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1319176, ...}) = 0
mmap2(NULL, 1329480, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e97000
mprotect(0xb7fd5000, 4096, PROT_NONE) = 0
mmap2(0xb7fd6000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13e) = 0xb7fd6000
mmap2(0xb7fd9000, 10568, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fd9000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e96000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e966c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7fd6000, 8192, PROT_READ) = 0
mprotect(0xb7ffe000, 4096, PROT_READ) = 0
munmap(0xb7fdc000, 13796) = 0
rt_sigaction(SIGCHLD, {0x8048dc4, [CHLD], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
open("/opt/protostar/run/net0.pid", O_RDWR|O_CREAT|O_TRUNC, 0700) = 3 # open()
setgroups32(1, [999]) = 0
setresgid32(999, 999, 999) = 0 # drop privileges
setresuid32(999, 999, 999) = 0 # drop privileges
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e96728) = 6507 # return value
exit_group(0) = ? # exit()
-> It ends with "exit," but what happens before then?
-> It seems to open a "net0.pid" file with write permissions.
-> Then, set the effective "uid" and "gid" to change the user and group "ID" to "999".
-> This therefore means that the process renounces root privileges.
-> Then call "clone()"
-> man clone
DESCRIPTION
clone() creates a new process, in a manner similar to fork(2).
-> According to the "man" page, "clone" creates a new process similar to "fork."
-> Thus, a new process is created as a copy of the replica itself.
-> The return value is the process "ID" of this new process and equal to that value.
-> It is written to the file ".pid".
-> Therefore, the file is created a new process will help to track.
-> The parent process is then terminated and the subprocess is separated.
-> cat "/opt/protostar/run/net0.pid"
6507
-> This is literally called the "an orphan process," and we now call it a daemon because we have done this work intentionally.
-> It is now a background process.
-> All we can do is run "straces" with the "-f" flag to follow the child process created.
-> strace -f ./net0
execve("./net0", ["./net0"], [/* 15 vars */]) = 0
brk(0) = 0x804b000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe0000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=13796, ...}) = 0
mmap2(NULL, 13796, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fdc000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320m\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1319176, ...}) = 0
mmap2(NULL, 1329480, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e97000
mprotect(0xb7fd5000, 4096, PROT_NONE) = 0
mmap2(0xb7fd6000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13e) = 0xb7fd6000
mmap2(0xb7fd9000, 10568, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fd9000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e96000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e966c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7fd6000, 8192, PROT_READ) = 0
mprotect(0xb7ffe000, 4096, PROT_READ) = 0
munmap(0xb7fdc000, 13796) = 0
rt_sigaction(SIGCHLD, {0x8048dc4, [CHLD], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
open("/opt/protostar/run/net0.pid", O_RDWR|O_CREAT|O_TRUNC, 0700) = 3
setgroups32(1, [999]) = 0
setresgid32(999, 999, 999) = 0
setresuid32(999, 999, 999) = 0
clone(Process 6571 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e96728) = 6571
[pid 6570] exit_group(0) = ? # parent exit
setsid() = 6571
chdir("/") = 0
open("/dev/null", O_RDWR) = 4
fstat64(4, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
dup2(4, 0) = 0 # stdin
dup2(4, 1) = 1 # stdout
dup2(4, 2) = 2 # stderr
close(4) = 0
write(3, "6571\n", 5) = 5 # child process "ID"
close(3) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(2999), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EADDRINUSE (Address already in use)
write(2, "serve_forever: unable to bind():"..., 56) = 56
exit_group(6) = ?
Process 6571 detached
-> Instead of maintaining the parent process, it is connected to the new process after cloning and the old process is terminated.
-> Then change the directory and open "/dev/null". This file is another special doctor file.
-> Act like a black hole.
-> And we double the "stdinput", "stdoutput" and "stderror" in this process.
-> man dup
DESCRIPTION
These system calls create a copy of the file descriptor oldfd.
dup() uses the lowest-numbered unused descriptor for the new descriptor.
dup2() makes newfd be the copy of oldfd, closing newfd first if necessary, but note the
following:
-> Bend all standard streams to point to black holes.
-> Basically we just throw away anything.
-> Then the previous "with the "field scripter. Write child process "ID" in “.pid” file.
-> Now the fun part begins and a new socket is made.
-> Sockets are used for network communication and can select different types of sockets.
-> man socket
DESCRIPTION
socket() creates an endpoint for communication and returns a descriptor.
-> I want that flag and setting.
-> But the most important thing is the bind call, and this process attempts to bind here. At port 2999.
-> man bind
DESCRIPTION
When a socket is created with socket(2), it exists in a name space (address family) but has
no address assigned to it. bind() assigns the address specified to by addr to the socket
referred to by the file descriptor sockfd. addrlen specifies the size, in bytes, of the
address structure pointed to by addr. Traditionally, this operation is called “assigning a
name to a socket”.
-> Which means that if the operating system receives a packet that want’s to establish a connection with this process, it will do so and then forward the packet with data inside to the process.
-> However, the other address and port call is a function is failing because it is already in use.
-> That part is meaningful because I've already called "net0."
-> Let's end the process again and try again.
-> killall net0
-> strace -f ./net0
execve("./net0", ["./net0"], [/* 15 vars */]) = 0
brk(0) = 0x804b000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe0000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=13796, ...}) = 0
mmap2(NULL, 13796, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fdc000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320m\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1319176, ...}) = 0
mmap2(NULL, 1329480, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e97000
mprotect(0xb7fd5000, 4096, PROT_NONE) = 0
mmap2(0xb7fd6000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13e) = 0xb7fd6000
mmap2(0xb7fd9000, 10568, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fd9000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e96000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e966c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7fd6000, 8192, PROT_READ) = 0
mprotect(0xb7ffe000, 4096, PROT_READ) = 0
munmap(0xb7fdc000, 13796) = 0
rt_sigaction(SIGCHLD, {0x8048dc4, [CHLD], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [PIPE], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
open("/opt/protostar/run/net0.pid", O_RDWR|O_CREAT|O_TRUNC, 0700) = 3
setgroups32(1, [999]) = 0
setresgid32(999, 999, 999) = 0
setresuid32(999, 999, 999) = 0
clone(Process 6715 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e96728) = 6715
[pid 6714] exit_group(0) = ?
setsid() = 6715
chdir("/") = 0
open("/dev/null", O_RDWR) = 4
fstat64(4, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
dup2(4, 0) = 0
dup2(4, 1) = 1
dup2(4, 2) = 2
close(4) = 0
write(3, "6715\n", 5) = 5
close(3) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(2999), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 10) = 0
accept(3,
-> Now we listen to the open port and wait for it to arrive with the acceptance of the packet
-> man accept
DESCRIPTION
The accept() system call is used with connection-based socket types
(SOCK_STREAM, SOCK_SEQPACKET). It extracts the first connection
request on the queue of pending connections for the listening socket,
sockfd, creates a new connected socket, and returns a new file descrip‐
tor referring to that socket.
-> Open the second terminal and use "netstat" to locate this listening process.
(second) -> su root
Password:(godmode)
-> netstat -plant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 1097/portmap
tcp 0 0 0.0.0.0:2993 0.0.0.0:* LISTEN 1664/final2
tcp 0 0 0.0.0.0:2994 0.0.0.0:* LISTEN 1661/final1
tcp 0 0 0.0.0.0:2995 0.0.0.0:* LISTEN 1658/final0
tcp 0 0 0.0.0.0:2996 0.0.0.0:* LISTEN 1656/net3
tcp 0 0 0.0.0.0:2997 0.0.0.0:* LISTEN 1654/net2
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1794/sshd
tcp 0 0 0.0.0.0:2998 0.0.0.0:* LISTEN 1652/net1
tcp 0 0 0.0.0.0:2999 0.0.0.0:* LISTEN 6715/net0
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1638/exim4
tcp 0 0 0.0.0.0:51427 0.0.0.0:* LISTEN 1109/rpc.statd
tcp 0 0 192.168.70.130:22 192.168.70.1:49843 ESTABLISHED 6304/sshd: user [pr
tcp 0 0 192.168.70.130:22 192.168.70.1:51299 ESTABLISHED 6439/sshd: user [pr
tcp 0 52 192.168.70.130:22 192.168.70.1:52051 ESTABLISHED 6774/sshd: user [pr
tcp6 0 0 :::22 :::* LISTEN 1794/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1638/exim4
-> Here it is. Process “net0” is listening on port “2999”.
-> You will now use "netcat" to establish a "TCP" connection with this port.
-> nc 127.0.0.1 2999
(first) -> Part of the terminal page of "strace -f ./net0".
listen(3, 10) = 0
accept(3, {sa_family=AF_INET, sin_port=htons(42333), sin_addr=inet_addr("127.0.0.1")}, [16]) = 4
clone(Process 6802 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7e96728) = 6802
[pid 6715] close(4) = 0
[pid 6715] accept(3, <unfinished ...>
[pid 6802] close(3) = 0
[pid 6802] dup2(4, 0) = 0
[pid 6802] dup2(4, 1) = 1
[pid 6802] dup2(4, 2) = 2
[pid 6802] time(NULL) = 1572622584
[pid 6802] write(1, "Please send '63283035' as a litt"..., 52) = 52 # printf("Please send '%d' as a little endian 32bit int\n", wanted);
[pid 6802] read(0, # if(fread(&i, sizeof(i), 1, stdin) == NULL)
-> Since a new connection has been established, the "accept" bleed will be returned.
-> Upon acceptance, another call for replication is displayed and a different process is created.
-> Processes server-client connections.
-> This method allows other users to establish connections and does not require waiting.
-> It was completed because it now has its own dedicated process.
-> A new file technician referring to this socket will also be returned.
-> Therefore, as with regular files, you can read and write with this file descriptor.
-> This kernel sends data written in TCP packets to the client.
-> And when you receive the data, make sure that it is readable from this socket.
-> Now change the standard input, output, and error stream from "/dev/null" to this new one.
-> The program then reads the data sent after reading from "stdinput".
-> This is the action function.
-> When comparing the last two "syscalls" and "runs," there is first a writing about "stdout".
-> This is where it unfolded in this "printf" and in "stdin."
-> Entering a line in "netcat" indicates that "netcat" has read a string from a network, server, and server family for this text.
(second) -> terminal of "nc 127.0.0.1 2999"
Please send '1236053420' as a little endian 32bit int
1234 (Entry Key)
I'm sorry, you sent 875770417 instead
(first) -> termianl of “strace -f ./net0”
[pid 6847] read(0, "1234", 4) = 4
[pid 6847] write(1, "I'm sorry, you sent 875770417 in"..., 38) = 38
[pid 6847] exit_group(38) = ?
Process 6847 detached
<... accept resumed> 0xbffff7b8, [16]) = ? ERESTARTSYS (To be restarted)
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 38}], 0, NULL) = 6847
sigreturn() = ? (mask now [])
accept(3,
-> And I did a writing that the numbers were wrong.
-> The failed "printf" in "run()".
: Let's summarize the function of the hidden code.
-> First, to become an orphan, they clone themselves and remove daemons by killing their parents.
-> It then starts receiving the TCP connection on port 2999.
-> Once the connection is established, we will take a closer look at the TCP protocol.
-> In other cases, different copies of the process are created to handle this established connection.
-> The parents are ready to accept the other connections in parallel.
-> The child process that handles the connection is basically to call "run()".
: Simply put, the program runs in the background process and calls "run(") for all connected clients.
: Now let's try and solve it.
-> First of all, you must obtain the string representation of that number.
(second) -> nc 127.0.0.1 2999
Please send '304052221' as a little endian 32bit int
-> Using Python.
-> With "struct.pack", you can convert a number to a byte string representation.
(first) -> python
>> import struct
>> struct.pack("I", 304052221)
'\xfdw\x1f\x12'
-> As you can see, however, the resulting string does not use characters that can be typed on the keyboard.
-> This byte value can be printed in "echo" and "-e" but it is not simple to "nc" pipe this.
-> It works because numbers are random.
-> However, simple tricks can be used.
-> "echo -e" may be used, but within quotation marks, a backtick is used to perform a negative "cat".
-> ex.)
-> echo "\x41"
\x41
-> echo -e "\x41"
A
-> cat -
asd (Enter Key)
asd
\x41 (Enter Key)
\x41
-> Redirecting the input back to the output will place the output.
-> Now you can see numbers and "cat" waiting for input by connecting pipes to "netcat".
(second) -> echo -e "`cat -`" | nc 127.0.0.1 2999
Please send '1745922617' as a little endian 32bit int
-> Use Python to convert numbers and then paste the escape string back.
(first) -> python
>> import struct
>> struct.pack("I", 1745922617)
'9\xaa\x10h'
(second) -> Please send '1745922617' as a little endian 32bit int
9\xaa\x10h (Enter Key & CTRL+D)
Thank you sir/madam
-> The other terminals will press the "Enter" key and then use "CTRL+D" to indicate that the input has been completed.
-> When "cat" is closed, "echo" sends the string to "netcat".
-> Success!
: Tips.
-> strace -f ./net0
-> netstat -plant
-> echo -e “`cat -`” | nc 127.0.0.1 2999
Please send '<…>' as a little endian 32bit int
-> python
import struct
struct.pack(”I”, <…>)