wtf

WTF is white tight feet.

  1. 1. Stage 1 clear!
  2. 2. Stage 2 clear!
  3. 3. Stage 3 clear!
  4. 4. Stage 4 clear!
  5. 5. Stage 5 clear!

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
2
3
4
5
argv =  ['./input']
argv += ['f'] * (ord('A') - 1)
argv += ['\x00'] # strcmp(argv['A'],"\x00") == 0
argv += ['\x20\x0a\x0d'] # strcmp(argv['B'],"\x20\x0a\x0d") == 0
argv += ['f'] * (100 - len(argv)) # argc = 100

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 stdin
  • read(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
2
from pwn import process
p = process(argv, stderr=stderr_we_want)

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 on argv['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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env python
from pwn import *

with open('stderr', 'wb') as f:
f.write(b'\x00\x0a\x02\xff')

with open('\x0a', 'wb') as f:
f.write(b'\x00\x00\x00\x00')

argv = ['/home/input2/input']
argv += ['f'] * (ord('A') - 1)
argv += ['\x00']
argv += ['\x20\x0a\x0d']
argv += ['8878']
argv += ['f'] * (100 - len(argv))

stderr = open('./stderr', 'rb')

env = {'\xde\xad\xbe\xef': '\xca\xfe\xba\xbe'}

def main():
# sh = ssh(user='input2',host='pwnable.kr',port=2222,password='guest')

io = process(argv=argv, stderr=stderr, env=env)

io.sendline(b'\x00\x0a\x00\xff') # stdin

p = remote('127.0.0.1', 8878) # socket

p.sendline(b'\xde\xad\xbe\xef')

p.close()

io.interactive()

if __name__ == "__main__":
main()

OMG! one write the exp in /tmp/pwn,admin’s soltion

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env/ python
import os
os.environ['PWNLIB_NOTERM'] = '1'

from pwn import *

#argv
stage1 = []
for i in range(100):
stage1.append('a')
stage1[65] = '\x00'
stage1[66] = '\x20\x0a\x0d'
stage1[67] = '7021'

#stdio
#create a pipe,return (rear,write)
fd1,data1 = os.pipe()
fd2,data2 = os.pipe()
os.write(data1,"\x00\x0a\x00\xff")
os.write(data2,"\x00\x0a\x02\xff")

#env
env = {'\xde\xad\xbe\xef':"\xca\xfe\xba\xbe"}

#file
with open("\x0a","w") as f:
f.write('\x00\x00\x00\x00')

io = process(executable = '/home/input2/input',argv=stage1,stdin=fd1,stderr=fd2,env=env)
#network
msg = remote('localhost',7021)
msg.sendline("\xde\xad\xbe\xef")
io.interactive()
  • os.pipe: create a pipe,return (rear, write), left one is “read out”, right one is “write in”.

本文作者 : wtfff
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议(CC BY-NC-SA 4.0)进行许可。This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接 : http://im0use.github.io/2022/06/10/input2/

本文最后更新于 天前,文中所描述的信息可能已发生改变