Stage 1 clear!
Firstly, there has argv. It sames like that behind.
such as /bin/ls -l
: left one represent argv[0], right one represent argv[1], …etc. argc represent the length of argv list.
So in order to satisfy strcmp(argv['A'],"\x00") != 0
, I can set argv['A'] = "\x00"
, and next condition.
1 | argv = ['./input'] |
Stage 2 clear!
stdio: standard input/output
It uses the read
.
- read - read from a file descriptor
- include: unistd.h
ssize_t read(int fd, void *buf, size_t count);
整数值 | 名称 | unistd.h符号常量 | stdio.h文件流 |
---|---|---|---|
0 | Standard input | STDIN_FILENO | stdin |
1 | Standard output | STDOUT_FILENO | stdout |
2 | Standard error | STDERR_FILENO | stderr |
read(0, buf, 4);
: read 4 bytes from stdinread(2, buf, 4);
: read 2 bytes from stderr
We can easily use pwntools to start our play. This tool we need called process.
1 | process() - Spawns a new process, and wraps it with a tube for communication. |
We can create program.
1 | from pwn import process |
Cation! stderr_we_want="\x00\x0a\x02\xff"
can’t work well. stderr is a file descriptor. open
return file descriptor, we can hand it.
Stage 3 clear!
also use process.
Stage 4 clear!
It open a file named \x0a
that mean newline in program, but don’t care it. Start to write in file like Stage 2.
fread
size_t fread(void *__restrict__ __ptr, size_t __size, size_t __n, FILE *__restrict__ __stream)
- Read chunks of generic data from STREAM.
- return: This number equals the number of bytes transferred only when size is 1. If an error occurs, or the end of the file is reached, the return value is a short item count (or zero).
memcpy
int memcmp(const void *__s1, const void *__s2, size_t __n)
- Compare N bytes of S1 and S2.
Stage 5 clear!
create a new endpoint for communication, usually 127.0.0.1 as host, 9999 as port(out can link).
use remote
in pwntools.
- AF_INET: IPv4 Internet protocols, remote support both IPv4 and IPv6.
- INADDR_ANY:
\#define INADDR_ANY ((in_addr_t) 0x00000000)
, we can use any address we want. htons( atoi(argv['C']) )
: depend on we set value onargv['C']
bind
- bind a name to a socket
int bind(int __fd, const struct sockaddr *__addr, socklen_t __len)
- Traditionally, this operation is called “assigning a name to a socket”.
code:
1 | #!/usr/bin/env python |
OMG! one write the exp in /tmp/pwn
,admin’s soltion
exp
1 | #!/usr/bin/env/ python |
os.pipe
: create a pipe,return (rear, write), left one is “read out”, right one is “write in”.