물먹는산세베리아

pwntools 정리 본문

Language/Python

pwntools 정리

suntall 2021. 4. 28. 23:56

20.04.28 수정

1. pwntools란?

- pwnable 시스템해킹에 주로 사용

- python 2.7에서만 사용 가능 python3에서도 사용 가능하다.

 

2. pwntools 설치(window)

관리자 모드로 cmd를 들어간 후 'pip install pwntools' 입력

'pip list'로 설치 툴 확인 가능

pip list에서 pwntools 확인

3. 사용법

- vi 편집기 이용해서 만들때 vi 파일명.py

- 상단에 from pwn import*

- 실행 시 python3 파일명.py (현재 설치된 파이썬은 3버전이므로)

 

4. 기능

1) 연결

- nc : remote(접속주소, 포트번호)

* 접속주소는 string, 포트번호는 int

ex) p = remote("localhost", 1234)

 

- local : process("./파일이름")

* 파일 이름은 string

ex) p = process("./test")

 

- ssh : ssh("사용자이름", "접속주소", port = 포트번호, password="비밀번호")

* 사용자이름, 주소, 비밀번호는 string

* 포트번호는 int

* pwnable.kr에서 많이 사용

* run 함수를 이용하여 쉘을 띄어줌

ex) p = ssh("test", "localhost", port = 1234, password="test")

ex) p2 = p.run("/bin/sh")

 

2) 데이터 받기

문자열 형태로 받아온다.

 

- recv(int): int만큼 데이터를 받아온다.

ex)p = remote("localhost", 1234)

p.recv()

int(p.recv(10),16) -> 10바이트를 16진수로 읽어온다.

 

- recvline(): 1줄 받아온다.

ex)p = remote("localhost", 1234)

tmp = p.recvline()

 

- recvuntil(value): value까지 받아온다.

ex) p = remote("localhost", 1234)

p.recvuntil('Passcode : ')

passcode = p.recv(2048)

한 쌍으로 많이 쓰인다.

 

* ~앞까지 받아오기는 [:-1]

ex) p.recvuntil('+')[:-1] +문자 앞까지 받아온다.

 

3) 데이터 전송

- send(value): value를 보낸다.

ex) p = remote("localhost", 1234)

p.send(value)

 

- sendline(value): 데이터 한 줄을 보낸다.

* 문자열 끝에 \n이 추가된다.

ex) p.sendline(value)

 

- sendafter('hello', value): 'hello' 출력시 value를 보낸다.

- sendlineafter('hello', value): 'hello'출력시 value와 \n을 보낸다.

 

4) packing 함수

- p32(value): 32비트 리틀 엔디안 방식으로 패킹해준다.

* p32(0x12345678, endian='big'): big endian으로 패킹해준다.

ex) p32(0x12345678) -> \x78\x56\x34\x12

 

- p64(value): 64비트 리틀 엔디안 방식으로 패킹해준다.

* p32 참고

ex) p64(0x12345678) -> \x00\x00\x00\x00\x78\x56\x34\x12

ex) b = 0x701060 라고 변수 지정하고 payload를 짤 때 

pay = ... ~

pay +=p64(b) 

이렇게 사용 가능하다. p64(b+8) 이렇게 주소를 더해서 사용할 수도 있다.

 

5) unpacking 함수

- u32(str): 32비트 리틀 엔디안 방식으로 언패킹

* 패킹된 string을 인자로 넣는다.

* 32bit는 4byte사용 -> 4byte 패킹된 string을 넣어야 한다.

* u32("\x78\x56\x34\x12", endian = 'big') 가능

 

 

- u64(str): 64비트 리틀 엔디안 방식으로 언패킹

* 64bit는 8byte사용 -> 8byte 패킹된 string을 넣어야 한다.

 

* 반환값은 int

* 주소를 leak 하여 패킹된 주소를 받아오는 데 사용된다.

leak=p.recv(4)

leack_got = u32(leak)

* u64에서 64bit에서 사용되는 주소는 6byte 뿐이다. 따라서 leak 할 때 u64(p.recv(6).ljust(8,'\x00')) 라고 쓴다.

 

 6) interactive함수

- interactive(): 쉘과 직접적으로 명령을 전송, 수송할 수 있다.

ex) p.interactive()

* 코드 맨 마지막에 사용

* 쉘을 딴 후 그 쉘과 쉽게 상호작용하는 데 사용