시스템 해킹을 위한 pwntools 명령어

oolongeya

·

2021. 8. 24. 15:37

여러분들이 pwnable 분야에 입문해서 문제들을 풀었다면,

아마 페이로드를 터미널 창에 한 줄씩 입력하거나 기호를 사용해서 코드를 길게 한 줄로 공격했을 것이다.

 

이러한 공격은 한계가 있고, 불편함이 있으니 pwntools 를 사용하면 다른 세상(?)을 느낄 수 있다.

 

pwntools 설치는 아래의 링크를 참고하자

 

https://kkomii22.tistory.com/50?category=948682 

 

최신 칼리 리눅스 pwn 설치, 오류 해결

리눅스에서 자동, 무작위값, 빠르게 반복 행위 같은 경우 해킹대회에서 필요한 경우도 있는데, 이 경우 pwn을 이용하면 쉽게 문제를 해결할 수 있다. pwn 설치를 위해 터미널을 이용하는데 루트 권

kkomii22.tistory.com

 

또한 이 게시글은 아래 링크의 게시글을 정리한 것이다. 작성해주신 아래 링크 '독학두비니' 님께 감사합니다.

https://dokhakdubini.tistory.com/236

 

Pwntools 처음 쓰는 사람들에게

후배들 주려고 작성한 문서인데 다른분들에게도 될 수 있다면 좋겠습니당 Introduction to pwntools 작성자. dubini0 이 문서는 pwntools 공식문서를 참고하였습니다: https://docs.pwntools.com/en/stable/index...

dokhakdubini.tistory.com


from pwn import * 

 

을 작성해서 import를 해야 pwntools를 사용할 수 있다.

 

pwntools에서 자주 사용하는 명령어들은 아래와 같다.

 

< 접속 명령어 >

1
2
3
4
5
6
7
from pwn import *
 
= process('./test')                             
= remote('komi.tistory.com'1234)       
= ssh("komi""pwn.kr", 1234)                  
 
p.close()           
 
 
명령어 설명 사용 예
process 로컬 바이너리에 대해서 익스플로잇을 실험할 때 사용하는 함수
로컬에서 문제 파일을 실행할 때 사용
p = process('./test')
# process(filename)
remote 원격 서버를 대상 으로 실제 익스플로잇을 작동할 때 사용하는 함수 p = remote('komi.tistory.com', 1234)
# remote(host, post)
ssh ssh를 통해서 접속하는 함수 p = ssh("komi", "pwn.kr", 1234)
# ssh(user, host, port, password)

 

< 페이로드 전송 >

1
2
3
4
5
6
7
from pwn import *
= process('./test')
 
p.send('A')                       
p.sendline('A')                    
p.sendafter('1234''A')       
p.sendlineafter('1234''A'
cs
명령어 설명 사용 예
send ./test에 'A' 입력 p.send('A')
sendline ./test에 'A' 입력 뒤에 개행문자(\n)까지 입력 p.sendline('A')
sendafter ./test가 '1234' 출력 시, 'A'를 입력 p.sendafter('1234', 'A')
sendlineafter ./test가 '1234' 출력 시 'A' + 개행문자(\n)까지 입력 p.sendlineafter('1234', 'A')

 

< 데이터 받기 >

프로그램이 출력하는 output을 확인하려면 recv 함수를 사용한다.

1
2
3
4
5
6
7
8
from pwn import *
= process('./test')
 
data = p.recv(1024)            
data = p.recvline()            
p.recvn(5)                    
print p.recvuntil('1234')    
print p.recvall()    
cs
명령어 설명 사용 예
recv (파일)이 출력하는 데이터 중 최대 1024바이트의 데이터를 받기 data = p.recv(1024)
print(data)
데이터를 받아서 data에 저장
recvline (파일)이 출력하는 데이터 중 개행문제를 만날 때까지를 받기 data = p.recvline()
print(data)
데이터를 받아서 data에 저장
recvn (파일)이 출력하는 데이터 중 정확히 5바이트를 받기 p.recvn(5)
recvuntil ('1234')문자열을 (파일)이 출력할 때까지 받아서 출력 print p.recvuntil('1234')
recvall 연결이 끊어지거나 프로세스가 종료될 때까지 받기 print p.recvall()

print (파일).recv(1024)의 방식도 많이 사용한다.

 

< 패킹 >

p32, p64 / u32, u64

대부분의 CPU는 little endian 방식을 이용한다. 

little endian 방식으로 패킹할 때는 p32, p64

언패킹할 때는 u32, u64를 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'''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))
cs
data32 = 0x41424344
data64 = 0x4142434445464748

print p32(data32) 
print p64(data64) 

-------------------------------------------

output : 

DCBA

HGFEDCBA

 

data32 = "ABCD"
data64 = "ABCDEFGH"

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

-------------------------------------------

output : 

0x44434241

0x4847464544434241

 

< 디버그 >

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

1
2
3
4
import pwn from *
 
= process('./test')
gdb.attach(p)
cs

 

< 쉡 >

입력을 하면서 디버깅을 하려는 경우 유용하다.

1
2
3
4
from pwn import *
 
= process('./test')
p.interactive()
cs

 

 

반응형