'|'(파이프)를 사용한 페이로드 작성

해킹/개념 정리 2016. 1. 21. 14:28

시스템 관련 문제들을 풀다보면 stdin으로 특정 16진수를 넣어줘야 하는 상황이 꼭 발생한다.

이럴경우 해당 16진수가 ascii상 키보드로 입력할 수 없는 값이면 어쩔수 없이 프로그램으로 전달해줘야 한다.

그리고 이럴때 간단하게 사용할 수 있는 perl이나 python을 주로 이용하게 된다.


물론 c언어 등 다른 언어에서도 pipe 함수를 제공하여 프로세스간의 통신을 제공한다.

예컨데 c언어에서 특정 프로그램에 stdin으로 값을 집어넣으려면 파이프로 사용할 배열을 만들고 pipe()함수를 사용해서 커널에 파이프를 만들 수 있다. 그리고나서 fork()함수를 사용해서 부모-자식간에 공유되는 pipe변수를 가지고 통신을 하는 방식이다.


http://satanel001.tistory.com/33

이 포스팅에 조금더 자세한 구현방식이 나와있다.



하지만 위 방법은 코드도 길고 컴파일도 해야해서 bash에서 바로 사용할 수 있는 파이썬 스크립트와 '|' 사용에 비하면 효율성이 많이 떨어진다.

'|'(shift+\)는 bash에 들어갈 경우 특이한 기능을 하는데 '|'를 기준으로 좌측 부분의 실행결과 stdout으로 출력되는 부분을 우측 프로그램의 stdin으로 넣어주는 역할을 한다. 좀더 자세한 설명을 위해 테스트 프로그램을 작성해봤다.





       

   

받은 입력을 그대로 출력하는 get_print와 hello world를 출력하는 helloworld라는 프로그램을 각각 작성해주었다.

그리고 ./helloworld | ./get_print 라고 명령어를 입력해주면





이렇게 helloworld의 출력이 get_print의 입력으로 들어가서 input은 hello world라고 말해주는 것을 볼 수 있다.

여기서 helloworld를 c를 이용한 프로그램이 아닌 bash에서 바로 사용할 수 있는 간단한 python 스크립트로 바꿔주면


(python -c 'print "hello python!!"')|./get_print

이렇게 쓸수 있다. 결과를 보면




역시 입력값이 제대로 들어가는 것을 확인했다.

이런식으로 파이프를 기준으로 좌측에 python 스크립트를, 우측에 입력을 넣고자 하는 프로그램을 놓아서 입력을 전달할 수 있다.



하지만 만약 쉘코드를 사용해서 페이로드를 작성한다면 (python -c 'print "~~"';cat)|./input 이런식으로  ;cat을 붙여줘야 한다.

이유는 파이썬 스크립트가 출력하는 과정에서 마지막에 EOF를 넣기 때문이다. 스크립트가 정상적으로 쉘을 띄우더라도 그 쉘이 EOF를 만나서 꺼져버린다고 한다.





LOB의 전형적인 파이프를 이용한 bof 문제인데 보이는것처럼 같은 입력이더라도 ;cat이 없을때는 쉘이 실행되지 않는 것을 볼수있다.




Tags
Social