Tips & theory

Python 3 + pwntools 자주 하는 실수

wyv3rn 2022. 7. 9. 10:03
728x90
반응형

변수의 타입을 확실하게 구분하며 출력함에 따라 자꾸 헷갈린다 ㅠㅠ

자주 하는 실수를 정리했다.


ssh 서버에 접속해서 특정 파일을 실행할 때

s = ssh(user='app-systeme-ch83',host='challenge03.root-me.org',port=2223,password='app-systeme-ch83')
p=s.process('./ch83')

이와 같이 선언하였을 때 서버에서 값을 받아오는지, 프로그램에서 받아오는지 확실히 해야 한다.

p.recv(12) #프로그램에서 문자를 받아올때
s.recv(12) #서버에서 문자를 받아올때

변수를 선언할 때는 확실하게 선언할 것.

보통은 byte로 값을 처리하기 때문에

payload = b''
payload += b '\x90'*100

와 같이 선언 후 값을 넣어주자.


출력 시에도 마찬가지로 byte로 값을 받아오기에 스트링으로 출력해주자.

print (p.recv(1024).decode())

decode 다음에 괄호 빠뜨리지 말자!

 


주소를 받아왔을 때는 문자열로 받아오기에 packing 하려면 0x를 제외하고 int 값으로 변경한 다음 packing 하자

offset=0x10

address1 = p.recv(4)
address2 = p32(int(address1,16) + int(offset))

address3 = p.recv(12) #64bit의 경우 앞의 4byte는 사용하지 않기에 12 byte를 입력받는다.
address4 = p64(int(adddress3,16) + int(offset))

하지만 직접 주소를 넣어줄 때는 그냥 써주면 된다.

즉, 문자열로 값을 받아왔을 때 문제가 되는 것.

address = p32(0xdeadbeef)

 

추가)

주소 값을 받는 방법은 여러가지가 있는데, 아래와 같이 세련되게 할 수 있다.

int(p.recvline()[a:b],16)

의미는

우선 출력되는 한 줄 전체를 다 받은 다음 a 부터 b 까지 끊는다.

예를 들어 123456789의 값을 받아들일 때

p.recvline()[1:3]

p.recvline()[1:3]

으로 받으면, 0부터 값이 들어가기에 끊은 값은 23 이 된다.

이후 해당 값을 16진수로 처리하면 된다.


파일을 실행하며 인자를 넘겨줄때는 list 형식으로 전달되어야 한다.

totlen = 512

pay = ['' for i in range(2)]
pay[0] = './ch7'
pay[1] = b''
pay[1] += b'\x90'*50
pay[1] += shellcode
pay[1] += b'\x90'*(totlen-len(pay[1]))
pay[1] += p32(0x0804a040)

p = process(pay)

와 같이 실행 가능하다.

또는

totlen = 512

filename = './file'

pay = b''
pay += b'\x90'*50
pay += shellcode
pay += b'\x90'*(totlen-len(pay[1]))
pay += p32(0x0804a040)

execute = ['filename',pay]

p = process(pay)

와 같이 실행 가능하다.


22.9.15

빡쳐서 한 줄 더 쓴다.

만일 바이너리에서 scanf로 값을 받아들일 때

sendline으로의 값 전달은 필수이다. (엔터가 무조건 들어가야한다는 말.)

더불어 sendline의 경우 str 값만 정상적으로 전달하기에 int 값은 반드시 str(val)와 같이 써줘야 한다.

즉, 아래와 같다.

a = b'abcdef'
p.sendlineafter(b'data: ',a)
b = 1234
p.sendlineafter(b'data: ',str(b))

 

read로 값을 받아들일때에는 sendline을 쓰면 마지막에 \x0a가 들어가기에 유의할 것.

728x90
반응형