CTF/포너블

리눅스에 Pwntools 설치하기

ㅇㅏ도 2023. 10. 6. 21:41

pwntools 설치 방

sudo apt-get install libcapstone-dev을 해서 disasm에러가 발생하지 않게 한 후에

cmd에서 pip install pwntools라고 입력해서 설치하면 된다 

(리눅스가 아니라면 이것만 하면 됨)

설치가 되나 했더니 이런 오류가 떴다

https://bobbyhadz.com/blog/python-warning-running-pip-as-the-root-user-can-result-in-broken-permissions를 참고해서 해결 방법을 찾았다. 

 

WARNING: Running pip as the 'root' user can result in broken permissions | bobbyhadz

Use the `--root-user-action=ignore` option to ignore the "Running pip as the 'root' user can result in broken permissions" warning.

bobbyhadz.com

위와 같이 명령어를 적어주고 pip list를 통해 pwntools가 설치되었음을 알 수 있었다. 

 

추가적으로 pwntools에 대한 팁들을 가져왔다. 

from(https://security-nanglam.tistory.com/155)

 

[python] pwntools 모듈 정리

[pwntools] pwntools 설치- cmd[관리자 권한] 에서 pip install pwntools라고 입력해서 설치를 하면 된다.- 만약 설치가 안된다면 pip 환경변수 설정이 안되있는 것이므로 환경변수를 설정하자. [python]환경변수

security-nanglam.tistory.com

 

pwntools 사용 방법

- 맨 윗부분에 from pwn import * 를 입력해줘야한다.

from pwn import *

 

pwntools 연결하기

- nc : remote(ip, port)형식으로 사용 (ip는 string이고 port는 int형이다)

p = remote("localhost", 8888)

 

- local : process(path)형식으로 사용 (path는 string이다)

p = process("./example")

 

- ssh : ssh(username, ip, port, password)형식으로 사용 (username, ip, password는 string 이고 port는 int형이다 또한 port와 password는 = 를 붙여준다 그리고 port와 password는 기본값으로 22와 guest로 설정된다)

p = ssh("username", "localhost", port=8888, password="example")

 

pwntools 데이터 받기

- recv() : 데이터를 받는다.

p = remote("localhost", 8888)
tmp = p.recv()

 

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

p = remote("localhost", 8888)
tmp = p.recvline()

 

- recvuntil(value) : 괄호안에 있는 부분까지 데이터를 받는다. (아래처럼 쓰면 개행까지 받으므로 한줄을 받아온다)

p = remote("localhost", 8888)
tmp = p.recvuntil("\n")

 

pwntools 데이터 보내기

- send(value) : 괄호안에 있는 값을 보낸다. _ read()함수에 사용

p = remote("localhost", 8888)
p.send(value)

 

- sendline(value) : 데이터 한줄을 보낸다. _ scanf(), gets(), fgets etc 등에 사용

p = remote("localhost", 8888)
p.sendline(value)

packing관련 함수

- p32(value) : 32비트 리틀 엔디안 방식으로 패킹해주는 함수 (p32(value, endian='big')을 하면 빅 엔디안으로 패킹해준다)

- p32(0x12345678) = \x78\x56\x34\x12

- p32(ABCD) = \x68\x67\x66\x65

tmp = p32(0x12345678) # \x78\x56\x34\x12
tmp = p32(ABCD) # \x68\x67\x66\x65

 

- p64(value) : 64비트 리틀 엔디안 방식으로 패킹해주는 함수 (p64(value, endian='big')을 하면 빅 엔디안으로 패킹해준다)

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

- p64(ABCD) = \x00\x00\x00\x00\x68\x67\x66\x65

tmp = p64(0x12345678) # \x00\x00\x00\x00\x78\x56\x34\x12
tmp = p64(ABCD) # \x00\x00\x00\x00\x68\x67\x66\x65

 

unpacking관련 함수

- u32(str) : 32비트 리틀 엔티안 방식으로 언패킹해주는 함수 (반환값은 int형이다 그리고 str에는 패킹된 string이 들어가야 한다.)

- u32("\x78\x56\x34\x12") = 305419896(0x12345678)

tmp = u32("\x78\x56\x34\x12") # 305419896(0x12345678)

 

- u64(str) : 64비트 리틀 엔티안 방식으로 언패킹해주는 함수 (반환값은 int형이다 그리고 str에는 패킹된 string이 들어가야 한다.)

- u64("\x00\x00\x00\x00\x78\x56\x34\x12") = 305419896(0x12345678)

tmp = u64("\x00\x00\x00\x00\x78\x56\x34\x12") # 305419896(0x12345678)

 

interactive함수

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

p = remote("localhost", 8888)
# ... code ...
p.interactive()

 

ELF 함수

- ELF에 바이너리를 인식시켜 적용되어 있는 보호기법을 보여주고, plt, got같은 ELF정보등을 가져올수 있는 함수.

elf = ELF("./filename")

 

 

- 또한 plt, got, symbols 정보를 알고싶으면 아래처럼 입력하면 된다.

p = remote("localhost", 8888)
elf = ELF("./filename")
plt = elf.plt
got = elf.got
symbols = elf.symbols