본문 바로가기

docker process에 gdb attach 방법 그 외

@eouya22025. 9. 30. 21:57

 

이번 포스팅도 마찬가지로 워게임, CTF 풀면서 알게된 정보에 관한 포스팅이다.

 

1. Docker process에 gdb attach하기

평소 patchelf 자동화 툴인 pwninit을 쓰는 나는 워게임 풀면서 도커 컨테이너 들어갈 일이 pwninit 사용할 때 libc 빼오는 것 밖에 없었는데, 평소와 같이 libc 빼와서 patch까지 다 해주고 로컬에서 쉘까지 다 딴 상황에서 아주 기분좋게 리모트로 쐈는데 쉘이 안따지는 것이었다. 로되리안 경험이 많지 않아 이를 해결할 실력이 많이 부족한 상황에서 도무지 이유를 알 수가 없었다. 그래서 문제에서 제공된 도커파일을 빌드해서 한번도 해본 적 없는 도커 process에 gdb attach하는 방법을 수소문해서 알게 되었다. 물론 이미 알고 계시는 분들이 더 많겠지만.. 허허

먼저 문제에서 주어진 도커파일 내부를 보면 사진과 같이 아래에 TCP-LISTEN뒤에 포트번호가 써져 있을 것이다. 해당 포트는 주어진 도커 내부포트이고, 원하는 포트 번호로 수정하고 싶으면 해도 된다. 도커파일을 빌드한 후, 아래와 같이 포트포워딩으로 도커 컨테이너를 실행해준다.

docker run -it -d -p <외부포트>:<내부포트> --name <컨테이너 이름> <이미지 이름>

여기서 외부 포트는 마음에 드는거로 하면 되고 내부 포트는 도커파일에서 확인한 포트번호를 넣으면 된다.

 

컨테이너를 실행하면 백그라운드에서 socat listen을 하는 서버가 돌아가게 된다.

nc 0.0.0.0 <외부 포트>

이제 nc 명령어를 사용해 도커 컨테이너에 연결해주면,

바이너리가 실행되는 것을 볼 수 있다. nc 로 연결한 터미널 창을 그대로 두고 새 터미널 창을 열고, 프로세스를 확인하고 PID를 구한다.

ps -ef | grep "<바이너리 명>"

확인 된 PID는 2188이다. 다음으로는 gdb를 attach 할 차례이다.

sudo gdb attach -p <PID>

그러면 이렇게 gdb가 붙게 된다. 처음 실행할 때는 사진과 다르게 플러그인이 붙지 않을 수 있는데, 그럴 때는 홈 디렉토리에 있는 .gdbinit 파일을 /root 디렉토리에 복사하고, source ~/.gef-… 이런식으로 상대경로로 되어있는 것을

source /home/<username>/.gef….와 같이 절대경로로 바꿔주면 플러그인이 정상적으로 적용된다.

익스코드를 도커 환경에서 디버깅 또한 가능한데, pwntools remote 인자로 localhost와 아까 도커 실행할 때 포워딩 설정한 외부 포트를 넣고 평소 하던 것처럼 pause()를 넣어서 실행한 다음, 다른 터미널 창에서 위에서 했던 방법 그대로 PID 확인 후 sudo gdb attach … 하면 익스코드 디버깅도 가능하다.

물론 이걸 배운게 소용 없었던게 그냥 문제가 도커환경이랑 서버환경이랑 다른 것이었.ㄷ…

2. GOT overwrite를 통한 FSB 아이디어

사용자의 입력값을 인자로 사용하는 함수에 대해서 GOT overwrite가 가능하다면 해당 함수를 포맷스트링을 사용하는 printf 와 같은 함수로 덮어써서 포맷스트링 버그를 트리거할 수 있다.

3. Heap size 수정 후 해제 시 heap 사용 영역 관련(환경은 glibc 2.39)

malloc으로 할당할 청크 Size를 조작하지 못하는 상황에서, libc leak을 해야했다. 공격할만한 벡터가 unsortedbin으로 청크를 보내는 방법밖에는 없었는데, malloc size가 0x50으로 고정되어있어서 tcache를 7개 채운 이후 fastbin으로 들어가는 바람에 unsorted bin에 보낼 수가 없었다. heap base는 알고 있었기에, tcache poisoning을 통해 heap주소를 할당 받아 size를 0x500으로 조작을 했다.

그런데 조작한 해당 청크를 해제한적이 없음에도 freed상태가 되어있고, 어떠한 bin에서도 찾아볼 수 없었다.

저 상황에서 청크를 unsorted bin으로 보내고자 하면 double free or corruption이 발생하게 된다.

해당 에러가 발생하는 이유는 청크의 size를 0x500으로 조작을 하고 free를 하는데 그 다음 청크로 인식하는 위치인 0x55b48d013d0 + 0x500위치의 메모리가 malloc으로 할당된 영역이 아니기 때문이다. 다시 말해서 malloc으로 할당한 영역이 아닌 메모리를 사용하고 free를 하려고 했기 때문에 발생한다.

 

따라서 0x50만큼 할당할 수 있는 청크를 10개정도 추가로 만든 후에 free를 한다면 해당 청크가 unsortedbin에 들어가게 된다.

여유 공간의 청크를 할당한 후 상태를 보면 아까와 달리 Used Chunk 상태인 것을 볼 수 있고,

청크를 free 했을 때 unsorted bin에 들어가 libc leak이 가능한 상태가 되는 것을 볼 수 있다.

'PWN > 개념' 카테고리의 다른 글

House of botcake  (0) 2025.10.31
calloc without memset ..  (0) 2025.10.27
fflush() 이용한 libc leak, 그 외  (0) 2025.09.11
fastbin attack시의 size check  (0) 2025.09.08
__run_exit_handler 이용한 exploit 간단 정리  (0) 2025.09.02
eouya2
@eouya2 :: eouya2

개인공부 기록 / 틀린거 있으면 돌팔매질 부탁드립니다

목차