수업/pwnable

pwntools 사용법

핏디 2021. 5. 6. 23:38
SMALL

1. pwntools 사용하기 위해 pwn 모듈 import

from pwn import *

 

2. process 클래스의 인스턴스를 만들며, elf 파일 실행할 수 있음.

r = process("파일 이름")

-> 해당 프로그램 실행시키고, 입력 대기함.

-> 이후, 실행된 프로그램에는 r 변수를 통해 접근 가능.

-> process() 로 실행시킨 프로그램은 입출력을 화면에 직접 할 수 없음.

-> r 변수를 통해 함수를 호출시키면서 파이썬 코드를 통해 프로그램의 stdin에 입력을 넣어주고, stdout에서 출력을 받아올 수 있음.

 

3. 접속

-process : 로컬 바이너리에 대해 익스플로잇 실험 시 사용하는 함수

p = process('./test')       # process(filename)

- remote : 원격 서버 대상으로 실제 익스플로잇 작동시 사용

p = remote('dokhakdubini.tistory.com', 123456)        # remote(host, port)

- ssh :  ssh를 통해 접속하는 함수 

p = ssh("fd", "pwnable.kr", 2222)                    # ssh(user, host, port, password) 순서

-접속 종료

p.close()            # 접속 종료

 

4. 페이로드 전송 (send)

from pwn import *
p = process('./test')

p.send('A')                        # ./test에 'A'입력
p.sendline('A')                    # ./test에 'A'입력 뒤에 newline character(\n)까지 입력
p.sendafter('asdf', 'A')        # ./test가 'asdf'를 출력할 시, 'A'를 입력한다
p.sendlineafter('asdf', 'A')    # ./test가 'asdf'를 출력할 시, 'A'+'\n'를 입력한다

- send함수를 이용할 때는 반드시 앞에 어떤걸 process remote했는지 붙여야 함 -> p. 붙임 

 

5. 데이터 받기 (recv)

from pwn import *
p = process('./test')

data = p.recv(1024)            # p가 출력하는 데이터 중 최대 1024바이트의 데이터를 받아서 data에 저장
data = p.recvline()            # p가 출력하는 데이터 중 개행문자를 만날 때까지를 data에 저장
p.recvn(5)                    # p가 출력하는 데이터 중 정확히 5바이트 받아서 data에 저장
print p.recvuntil('asdf')    # 'asdf'라는 문자열을 p가 출력할 때까지 받아서 출력
print p.recvall()            # 연결이 끊어지거나 프로세스가 종료될 때까지 받아서 data에 저장

- 변수에 직접 받아오는 방법

> 따로 결과값을 저장하고 싶을 때 사용하고, 출력시키고싶으면 print data의 식으로 출력

- 단순히 recv를 실행시키는 방법

> 필요없는 데이터를 받을 때 사용

- print p.recv() 실행하는 방법

> 받은 값 출력

 

* p.recv와 p.recvn의 차이

- p.recv() : 최대 n바이트를 받는 것이기 때문에, 예시의 경우 1024바이트를 모두 다 채워 받지 못해도 에러를 발생시키지 않음.

- p.recvn() : 정확히 인자만큼의 데이터를 받지 못하면 계속 대기함.

-주로 print p.recv(1024)의 방식 사용.

 

6. 라이브러리/바이너리 - ELF / run

from pwn import *

p = process('./test')             
e = ELF('./test')                # e에 test의 라이브러리를 불러옴

sh = p.run('/bin/sh')            # test로 /bin/sh를 바이너리에 실행시킴
sh.sendline("whoami")            # "echo hi"를 전송(권한이 있다는 전제 하에)
puts_plt = e.plt['puts']        # ELF ./test에서 puts()의 PLT주소를 찾아서 puts_plt에 넣는다.
read_got = e.got['read']        # ELF ./test에서 read()의 GOT주소를 찾아서 read_got에 넣는다.

- 리눅스에서 작동하는 실행파일에서 ELF에는 각종 정보가 기록되어 있음.

- 대표적으로 GOT, PLT등이 있는데, pwntools를 통해 쉽게 구할 수 있음.

- run : 바이너리 실행시킬 수 있음.

 

7. 패킹 - p32, p64 / u32, u64

'''test.py'''
from pwn import *

data32 = 0x41424344
data64 = 0x4142434445464748

print p32(data32)
print p64(data64)

data32 = "ABCD"
data64 = "ABCDEFGH"

print hex(u32(data32))
print hex(u64(data64))

실행 결과

sik@ubuntu:~$ vi test.py
sik@ubuntu:~$ python test.py
DCBA
HGFEDCBA
0x44434241
0x4847464544434241

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

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

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

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

 

8. debug - gdb.attach

- 페이로드를 진행하는 도중 gdb를 실행시킬 수 있는 함수

import pwn from *

p = process('./test')
gdb.attach(p)

- 실행 시, 새 창에서 해당 프로그램이 gdb로 보여짐.

- 그러나 서버 접속으로는 불가능하고, process(파일 실행)로만 가능.

 

9. 쉘 접속 - interactive

from pwn import *

p = process('./test')
p.interactive()

- interactive() : 쉘을 획득한 경우이거나, 익스플로잇 시 직접 입력을 주면서 디버깅이 필요한 경우 이용하는 함수

- 익스플로잇 파일과 프로세스와의 연결을 stdin/stdout에서 process로 바꿔줌.

- pwntools동작이 끝난 뒤 $가 나오는 이유도 이 함수 때문.

 


실습 - pwntools 사용하기

v다음 프로그램을 작성 후 컴파일

gcc –o hello hello.c

#include <stdio.h>
void main(){
	printf("hello\n");
	char buf[10];
	scanf("%10s", buf);
	if(!strcmp(buf, "test123")){
		printf("pwntool test ok\n");
	}
	else{
		printf("not working\n");
	}
}

 

v다음 프로그램을 작성 후 컴파일 (x.py)

from pwn import *
r = process('./hello')
print (r.recv(100))
r.sendline('test123')
print (r.recv(100))

vPwntools 사용하기

python3 x.py

아래처럼 pwntool test ok 가 나오면 성공.

네트워크를 대상으로 데이터 주고받기

- Process 대신 ‘remote’ 를 이용

아래와 같이 IP 주소, 포트번호를 전달한 뒤 동일하게 이용

\xcc\xaa\xbb를 입력해야 할 때

이렇게로도 가능

 


[출처]

dokhakdubini.tistory.com/236

tekiter.tistory.com/4

security-nanglam.tistory.com/155

 

 

 

 

 

 

 

 

 

 

 

LIST

'수업 > pwnable' 카테고리의 다른 글

[기말] 커맨드 인젝션  (0) 2021.06.07
10주차 이론  (0) 2021.06.06
[기말] 쉘코드(ShellCode)  (0) 2021.06.05
엔디안 (Endianess)  (0) 2021.06.05
메모리 구조 - 스택(stack)  (0) 2021.06.05