p.sendlineafter(b'>', b'1')
p.sendlineafter(b':', str(libc_environ).encode())
p.recv(1)
강의 페이로드중 p.recv(1)을 하는이유가 뭔가요??...
p.recv(20)을 해도 똑같이 잘 작동하던데
recv 하는 이유가 뭔가요?... 받아오는건 몇바이트를 받아오던 ' ' 공백 하나밖에 없는거같은데...
안녕하세요, 비누스님.
답변이 늦어 죄송합니다.
p.recv(1)
없이도 다음과 같이 코드를 수정하면 정상적으로 동작합니다. 차이점은 p.recv(1)
을 제거한 후, b':'
대신 b': '
를 사용하였습니다.
-p.sendlineafter(b':', str(libc_environ).encode())
-p.recv(1)
+p.sendlineafter(b': ', str(libc_environ).encode())
p.recv(20)
가 똑같이 작동하는 이유도 위 수정사항과 연관이 깊습니다.
솔버 코드에서 addr:
를 수신(recv) 한 후, libc_environ
의 주소 값을 송신(send) 하기 위해 아래의 코드를 사용하고 있습니다.
p.sendlineafter(b':', str(libc_environ).encode())
그런데 자세히 살펴보시면 b': '
가 아니라 b':'
을 사용하고 있습니다. 따라서 마지막에 띄어쓰기가 하나 빠진 셈인데, 이로 인해 Addr:
대신 Addr:
까지만 수신하게 되고, 수신한 후, 버퍼에 아직 공백문자 한 개가 남아 있는 상태가 됩니다.
따라서 버퍼에 남은 공백문자 한 개를 비우기 위해 p.recv(1)
을 했던 것입니다. 그러면 p.recv(20)
은 왜 동일하게 작동하는가? 이는 recv(n)
의 작동 자체가 n바이트를 읽다가 버퍼가 비워지면 수신을 멈추기 때문입니다. p.recv(20)
이어도 버퍼에 남아 있던 공백 문자 한 개 마저 모두 수신하였으므로 버퍼는 빈 상태가 되고 recv()
는 그 즉시 반환됩니다.
p.s. recvn(n)
이라는 메서드도 있는데, 이 메서드는 수신하다가 버퍼가 비워져도, 버퍼에 값이 새로 들어와서 n바이트가 읽힐 때까지 기다립니다.