wargame/dreamhack

[시스템해킹]shell_basic 문제 풀이

seungwon9201 2024. 9. 26. 18:58

Shell_basic

-문제-
원격 서버에 /home/shell_basic/flag_name_is_loooooong경로에 flag파일이 있다. 플래그 값을 구해보자.
단, main 함수가 아닌 다른 함수들은 execve, execveat 시스템콜 사용을 못하도록 하며 풀이와 상관없다.

우선 서버에 접속해 보자.

서버에 접속해 보니 shellcode : 라고 쉘 코드를 입력하라는 텍스트가 뜬다. 

그럼 원하는 경로에 있는 파일을 출력하는 쉘코드를 짠 다음 저곳에 보내면 flag가 출력될 거 같다. 

쉘코드는 pwntools를 활용해서 만들면 쉽게 풀린다.(orw코드로 풀려했으나 어려워서 패스...)

우선 원하는 flag가 원격에 있는 서버에 있으니 remote함수로 접속하는 코드를 만들자.

64비트인지 32비트인지는 직접넣어서 실행시켜보면 된다. 64비트 기반으로 했더니 에러없이 정상적으로 되었다.

그리고 그 서버가 64비트 기반인지 32비트 기반인지 입력하고 플래그가 들어있는 주소를 지정해 주자.

우선 시스템 콜을 차례대로 실행해야 하니 쉘코드를 초기화해주자.

시스템 콜을 써야 하는 이유?
main 함수가 아닌 다른 함수들이 이 시스템 콜을 사용할 수 없다는 조건이 있기 때문에, 파일 읽기와 출력 작업을 할 때 execve대신에  시스템 콜(open, read, write)을 사용해야 하기 때문!

 

그다음 flag위치의 파일을 열고 파일디스크립터(rax)로 파일의 내용을 읽고 스택(rsp)에 데이터를 저장하자.

스택(rsp)에 저장된 데이터를 표준출력(stdout(1))으로 출력해 주자.

맨 위의 사진에서 서버에 처음 접속하면 shellcode: 라는 메시지가 출력됐었다.

즉, 처음 서버를 실행했을 때 서버는 shellcode: 라는 메시지를 출력하면서 쉘 코드를 받을 준비가 됐다는 걸 나타냈었다.

그래서 print(p.recv())를 통해서 서버에서 오는 메시지를 출력시켜 서버가 준비가 됐는지 확인할 것이다. 만약 print(p.recv())를 처음에 실행시키지 않으면 서버가 준비되지 않은 상태에서 쉘코드를 받을 수 있으므로 먼저 실행시켜야 한다.

그다음 서버주소로 쉘코드를 보내자.(다만 서버의 CPU가 쉘 코드를 실행하려면 binary로 변환을 시켜주어야 한다. 그렇기 때문에 어셈블리어를 binary어로 바꿔주는 asm함수로 쉘코드를 변환시켜주자.)

마지막으로 서버가 보낸 flag값을 출력하면 끝이다.

그러면 이렇게 flag값이 나온다.

flag값 뒤에 나오는 \nong\x00... 은 처음에 데이터를 읽을 때 0x100(256바이트)로 지정해서 그렇다. 사진에서 보듯이 flag값의 출력값은 짧은데 빈 공간이 많아서 메모리에 남아있는 이전값이 그대로 출력된 것이다. (문제와는 큰 상관없다.)