본문 바로가기

Storehouse/Diary

[Grotesque]asg (2020.08.09 클리어)

toddler 문제인 asm에서 "어셈 짤줄 알아? 그럼 asg 한번 도전해보던가." 라는 도전욕구를 불태우는 문구를 보고 나서 곧바로 asg 문제를 풀게 되었다. 저번주엔 내내 출장이라 볼 시간이 없었고.. 어제 광주와서 어디 나가지 않고 방에 콕 박혀서 문제를 봤다.

 

asg.c 코드를 잠깐 보고나서 'asm이랑 비슷하네??? 뭐.. 하루면 풀지 않을까??' 라는 가벼운 생각을 했다가 이 문제를 저녁 11시까지 붙잡게 됐고, 결국 못풀었다. ㅋㅋㅋㅋㅋㅋㅋ 오늘 대전가서 시간되면 문제를 이어서 풀어야지 싶다.

 

 

저녁내내 돌리기 위한 쉘스크립트... 하지만

 

 

 

 

 

저녁내내 터미널 8개 띄우고 쉘스크립트를 돌렸지만 Failed.txt, Flag.txt는 볼 수 없었따... 필터링의 벽이 너무 강력했다 '-'

 

 

어제 저녁 마지막으로 돌린 파이썬 코드, 쉘스크립트이다.

" asm이랑 차이점은 쉘코드 필터링하고.. mmap 주소가 랜덤으로 지정되네? 사용자가 올리는 쉘코드도 랜덤 offset에 따라 다르게 옮겨가네? 그냥 필터링 무시하고 무식하게 페이로드 때려 박아보자 ^^ 혹시 필터가 뚫리면 문제 출제자분한테 너무 죄송한데 오똑하지??.. 하아 안되는데에~?"

생각했는데.. 필터의 벽이 너무 강.력.했.다. 

 

==> 글 작성 중에 asg.c 코드의 sandbox() 밑에 alloca()를 뒤늦게 확인했는데, 내가 문제 접근 방향을 잘못 잡았다는걸 깨달았다.

접근 방법은 아래에 설명하겠다. 

 

 

 

 

그래서 본 문제의 의도대로 asg(automatic shellcode generate) 코드를 짤 예정이다.

 

문제 점수가 높다보니 대놓고 답 비슷한 걸 쓰기엔 뭐하고.. 풀이과정을 엄청 상세하게는 쓰지 않겠다.

(flag값도 못 띄웠는데 김치국부터 벌컥벌컥 마시고 있다)

===============================================================================================

 

문제를 아직 풀지 않고 티스토리에 글부터 작성하는 중인데, 문제 접근방식이 (아마도 확실히. 분명히)이게 맞을 것이다.

풀이과정을 설명하겠다.

 

asg 문제는 asm의 업그레이드 판으로 코드의 기본 구조는 asm.c와 비슷하다.

asm의 풀이과정은 https://shayete.tistory.com/75에 작성하였다.

 

asg에서 주의할 코드는 다음과 같다.

 

 

1. urandom을 통해 srand의 seed를 랜덤하게 주었다. 여기서 쓰이는 rand()는 추측할 수 없는 랜덤한 값이 된다는 뜻이다.

이후, shuffle 함수를 불러서 filter값을 shuffle하는데, 이건 별거 없고(사실 이것 때문에 asg 문제가 빡친다) 0x00~0xff까지의 값을 filter[256] 배열에 넣고 섞는다.

이후 filter[0] ~ filter[127] 까지의 값만 화면에 뿌려준다. 256개의 문자 중, 128개만 랜덤하게 필터링할테니 알아서 쉘코드 넣어서 들어오라는 거다.

 

 

 

2. popen 함수를 이용하여 genflag를 실행한 후, 출력값을 filename 버퍼에 담는다.

filename은 아래와 같이 출력된다. 

"flag is inside this file: [flagbox/NJnfyWLmzrl227tvMqxTmsshMoeU5sbH1oMn8lzxAIptDGOgVbX5ufc6reOnwPU]"

flagbox/ 까지는 고정으로 찍히고, 그 뒤에 문자들은 랜덤값이다.

 

이후 give me your shellcode에서 사용자의 입력값 1000바이트를 입력받고 1. 항목에서 설명한 filter[0] ~ filter[127]과 비교하는데, 이 부분은 내가 입력한 값이 filter[0~127]에 있는지 확인하는 프로세스이다.

 

저 프로세스의 의미는 위의 flagfile과 내가 실행해야 할 쉘코드(open, write, read 등)를 필터링으로부터 잘 우회해서 넣어주면 된다는 뜻이다. 감이 오나? asg 문제는 내가 쓰고자 하는 쉘코드가 filter[]에 존재하면, 그걸 다른 값으로 대체해서 생성하라는 의도를 가지고 만들어졌다.

 

 

 

3. (shutdown error가 뭔지 모르겠지만 별로 중요한것 같지는 않으니 패쓰) chroot로 바이너리의 root 주소를 /home/asg_pwn 으로 고정했다. /tmp에서 임의의 바이너리를 실행하지 못하도록 막은 것 같이 보인다. (덕분에 /tmp에서 디버깅을 못했다.)

 

이후 sandbox를 부르고(asm의  sandbox와 동일) alloca() 함수를 호출한다. alloca()는 스택에 랜덤하게(rand()*12345) % 1024) 공간을 할당해주는 역할을 한다. 

alloca()로 스택을 랜덤하게 할당한 이유는, 스택 내에 존재하는 값들을 쓰지 말라는거다.

예를 들면 mmap으로 할당된 주소값(sh)을 스택에서 참조한다랄지, 주소값에서 랜덤하게 추가되는 offset을 참조한다랄지.. 아니면 flagbox/... 문자열이 저장된 주소값을 쓴다랄지.

스택에서 사용할 수 있는 모든 값들을 쓰지 말라고 alloca()를 박아놨다.

 

여기까지 설명했을 때, 다음과 같은 것들을 주의해야 하는 것을 알 수 있다.

=========================================================================================

1. filter[0] ~ filter[127]의 값을 피해서 쉘코드를 생성해야 한다.

2. mmap으로 할당되는 주소는 random이며(사실 서버는 항상 열려있으니 주소 자체가 랜덤은 아니겠지만, 우리가 알 수 있는 방법이 없다) rsp를 제외한 모든 레지스터를 초기화하는 쉘코드(stub)의 뒤에 붙는 offset도 랜덤이다. 이 점을 고려해야할 것이다.

3. pwnable.kr 서버의 /tmp에서 뭐 못한다. 허튼짓 x

4. alloca()로 스택 공간을 랜덤하게 할당한다. 기존 스택에 쌓여있는 값들 사용 못함

5. flagbox 뒤에 붙는 문자열도 당연히 filter[0] ~ filter[127]에 걸린다. 그걸 고려해서 쉘코드를 작성해야 한다.

=========================================================================================

 

여기서 다행인 점은 stub 쉘코드가 rsp를 초기화하지 않는다는 점이다. 접근 가능한 스택 주소가 있다는 것에 감사하자.

이 문제는 초기화되지 않은 rsp를 잘 활용하고, 쉘코드에 사용되는 16진수 범위를 최소화시켜서 쉘코드를 생성해야 할 것이다.

쉘코드 생성하는 법 또한 이전에 작성한 글(https://shayete.tistory.com/75)에서 설명하였다.

 

 

 

위 그림은 문제 서버에서 뿌려주는 필터 값들을 리스트에 넣고 출력한 화면이다. 이처럼 필터값, flagbox값을 긁어온 후 파이썬 코드를 이용해서 쉘코드를 자동으로 잘 생성하도록 작성해주면 될 것이다.

 

머릿속에서 문제를 어떻게 풀어야할 지 정리는 다 됬는데, 주말이 끝나가니 문제 풀 시간이 애매해서 손대지 못하는 중이다..

대전 올라가는 버스 타는 중에 할 거 없어서 노트북으로 티스토리 끄적이고 있다.. '-' 글 정리했으니 다음에 시간되면 asg 문제를 이어서 풀어봐야겠다.

 

 

2020.07.25

코딩을 잘 해야 풀 수 있는 문제같다.. 코딩바본데 하아아

 

 

flag name을 4바이트씩 끊어서 스택에 밀어넣으려고, 리스트에 4바이트씩 저장해뒀다.

이제 필터값 우회용도로 수정한 부분을 모두 체크해서 (DEC QWORD [rsp+1] * replace한 만큼의 숫자) 명령어를 쓰든 다른 방법으로 수정하든.. 스택에 밀어넣을 값(Replace Flag_name)을 다시 원상태(Original Flag_name)로 복원해야하는데.

리스트에서 replace한 값을 일일히 체크할 수 있는건가???;; 그냥 4바이트 말고 1바이트씩 끊어서 변환하면 참 수월할 것 같긴 한데..

코딩공부한다고 생각하고 좀 시도해보다가 안되면 1바이트씩 끊어서 해봐야겠다.

주말에 잠깐잠깐 풀려고 하니 이거 생각보다 오래걸릴 것 같다.

================================================================================================

 

 

2020. 08. 01

'subq [rip+0x2], 0x1234'

이 어셈의 쉘코드를 알아내려고 이방법 저방법 써보다가 안되서 몇시간 구글링하다가 시간 다 보낸 것 같다.

nasm 에서는 'rip' 레지스터를 쓸 수 없게 설계해놔서, 이 문제를 풀 때는 nasm을 쓰지 않는 것이 좋겠다.

3시간 삽질하다가 겨우 알아냈다. rip도 사용 가능하게 설계된 마법의 툴!  'as'

 

 

 

보고싶은 쉘코드와 관련한 어셈을 이렇게 작성해주고..

 

 

 

as ex.s -o ex.o

ld ex.o -o ex

objdump --disassemble ex

 

우분투에 기본으로 내장된 as 어셈블러를 이용해 바이너리 파일을 만든 후 objdump로 쉘코드를 봐주면..?

 

subl 혹은 subq [rip+0x2], 0x1234 등을 쉘코드로 멋지게 변환할 수 있다!!

 

진짜 저 명령어 하나 얻어내려고 몇시간 삽질한지 모르겠다.

 

삽질중인 모습.. '-'

 

이제 진짜 끝. 코딩만 하면 플래그를 얻을 수 있따 ㅎㅎㅎㅎ

문제의 핵심은 flag name, filter 값을 잘 받아오는 것과 flag name, 실제 사용할 명령어들을 필터우회해서 밀어넣는 건데

flag name 필터링 우회는 mov, sub 명령을 이용해서 스택에 잘 push하면 되고,

명령어 필터링 우회는 rip 안의 값을 직접 조작하는 방법 뿐인 듯하다.

 

이제 가족끼리 좀 놀다가 .. 대전 올라가서 시간되면 이어서 코딩해야겠다! ... 시간없으면 또 일주일 뒤에 풀겠지 ㅠ

 

아참.

 



 

flag name은 결국 1바이트씩 받아왔다 ㅋㅋㅋㅋㅋㅋㅋ 이리저리 검색해봤는데 list에서 replace된 문자를 찾을 수 없는 것 같다.

replace가 얼마나 되었는지 replace_count list에 담아둔 후, 나중에 코드 복원할 때 활용하면 될 것이다.

 

================================================================================================

 

2020. 08. 08

 

이상하다.

필터링 우회해서 쉘코드 잘 때려넣은 것 같은데 플래그 값이 안보인다.

스택에 flagbox/... 가 있는 걸 보니, 저건 우회시켜서 잘 넣은 것 같고.

쉘코드 구성에 문제 없는지도 확인했는데.. 이상하네?

뭔가 엄청 중요한 부분을 놓치고 있는 듯 한데.

쫌만 더 살펴보다가 자야겠다.

 

================================================================================================

 

2020. 08. 09

 

새벽에 왜안되지 왜안되지 했는데, write가 주소를 잘못참조해서 그런거였다. 정확히는 file descriptor 문제였나.

asm 문제에서는 마지막에 write(0)을 사용해서 플래그를 얻었는데 이 문제에서는 이게 잘 안됬나보다.

그래서 write(1, buf, sizeof(buf)) 이런식으로 보내줬다.

 

코드를 되게 지저분하게 짜서 그런지 400줄이 넘어간다.

똑같은 기능을 하는 프로세스를 함수로 묶어서 짜면 200줄정도 될 것 같은데.. 나중에 코드좀 깔끔하게 정리할겸 코드수정해야겠다.

주말마다 3~4시간씩 풀다보니 되게 오래걸렸는데.. 실제로 푼 시간은 빡세게 이틀??? 정도 걸린 것 같다.

어우. 힘들어.. ㅋㅋㅋㅋㅋㅋ

여유되면 이제 이 글 수정해야겠다.

'Storehouse > Diary' 카테고리의 다른 글

[Grotesque] aeg (2020.10.03 클리어)  (0) 2020.10.01
책을 써보고 싶은데..  (2) 2020.09.30
SANE 연구실 소개  (0) 2020.07.13
정보보호학회 논문 이용 순위..가?  (0) 2020.06.05
강의평가 결과  (0) 2019.05.23