本文总结了CTF中我所遇到的题型及其write up,本文长期更新
希望各位多多评论指正,也算作对我第一次写技术文章的鼓励!
训练场:南京邮电大学CTF题库
直接查看源码
出现场景:一般出现在第一题
write up: 直接Ctrl+u查看网页源码寻找flag
修改maxlength
出现场景:输入框输入内容有位数限制
write up:F12进入开发者模式修改maxlength后提交
IP伪造
各种伪造IP的HTTP头:
序号 | 伪造方式 |
---|---|
1 | X-Forwarded-For |
2 | Client-IP |
3 | x-remote-IP |
4 | x-originating-IP |
5 | x-remote-addr |
进制转换
源码:
1 |
|
分析:要求传入key不包含数字[1-9],但又等于54975581388,考虑转十六进制,发现54975581388=0xccccccccc
,因此get方法传值key=0xccccccccc
PHP弱类型
类型一
介绍:PHP在处理哈希字符串时,会利用“!=”或“==”
来对哈希值进行比较,它把每一个以”0e”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以“0e”开头的,那么PHP将会认为他们相同,都是0
出现场景:PHP代码审计、含md5的题
write up:
修复方法:“===”和“!==”strict比较符,只有在类型相同时才相等。“==”和“!=”即non-strict比较符,会在类型转换后进行比较
扩展:0e开头MD5值小结
string | md5() |
---|---|
s878926199a | 0e545993274517709034328855841020 |
s155964671a | 0e342768416822451524974117254469 |
s214587387a | 0e848240448830537924465865611904 |
类型二
源码:
1 | if (isset($_GET['a']) and isset($_GET['b'])) { |
分析:$_GET可以接受数组但MD5()函数若传递进去一个数组,则会返回null.因此向$_GET数组传入两个名为a、b的不相等的数组从而导致md5()均返回空:index.php?a[]=1&b[]=2(即null=null)
脑洞题
- 源码找url
- 源码看flag
jjencode/aaencode(颜文字)
介绍:
什么是jjencode?
将js代码转换成只有符号的字符串
什么是aaencode?
将js代码转换成常用的网络表情
aaencode加密:http://utf-8.jp/public/aaencode.html
解法:可以直接利用浏览器的控制台输入密文,执行后即可解密。
文件包含漏洞
典型的文件包含漏洞的格式网址:php?file=xxx.php
原因:网页后端php(或其他)代码中使用了include等文件包含语句,而且所包含的文件由变量控制,恰恰此变量又能通过GET或POST等方式进行修改所造成的
利用方法:构建file=php://filter/read=convert.base64-encode/resource=index.php
注:其中index.php可以为任意已包含文件返回base64加密过的index.php文件源码。
注意:python3中base64的解密为base64.b64decode()
mysql
- 精度问题
intval()
这个函数的作用是把参数自动转换成整数(int)
$id = intval(1024.5)//结果为$id==1024
robots.txt
介绍:robots.txt是搜索引擎中访问网站的时候要查看的第一个文件,robots.txt文件告诉了蜘蛛程序在服务器上什么文件是可以被查的。
%00
源码:
1 | if (isset ($_GET['nctf'])) { |
涉及漏洞:查到资料
1.ereg会把null视为字符串的结束,从而被%00截断,而strpos则可以越过%00
2.当ntf为数组时它的返回值不是FALSE
利用方法:
1.?nctf=1%00%23biubiubiu
2.?nctf[]=1
变量覆盖
源码:
1 | if ($_SERVER["REQUEST_METHOD"] == "POST") { |
分析:extract()
函数的作用:从数组中将变量导入到当前的符号表
可以看到这里的代码为:extract($_POST),即将POST的参数导入当前的符号表
由于extract()
函数存在变量覆盖漏洞,所以提交post参数:
pass=123&thepassword_123=123//或者pass[]=&thepassword_123
即:将两个变量的值修改成相同的,即可得到flag!
上传绕过
源码:
1 | 文件上传<br><br> |
0x00截断
绕过方法:在burpsuite—Hex中,将空格php后面一个字符的hex修改为00
SQL注入
常规注入
正常闭合
源码:
1 |
|
分析:会对传入参数两端去空格,然后sql拼接如下
$sql="select user from ctf where (user='".$user."') and (pw='".$pass."')";
所以只要用构造一下user的值,使语法无误,然后注释掉后面的即可。
MySQL主要有三种注释方式:
注释方式 | 说明 |
---|---|
# | 注释到行尾 |
/*内容*/ | 用于行间或多行注释(也可用/**/代替空格) |
– | 也是注释到行尾,但需要注意的是在两个减号后面至少要有一个\s,也就是空格,TAB,换行符等(’ or 1=1– ) |
解法:本题可post:user=admin')-- -&pass=123或user=admin')#&pass=123
sql语句就变成select user from ctf where (user='admin')#' and (pw='123')
查询语句就能成功返回user列,值为admin的那条记录。
union查询
源码:
1 |
|
解法:关键点在源代码第7、8行。首先要观察,我们能够控制的查询结果有$query[pw]
的值,通过让union前的查询语句为空,查询结果由union后面的语句控制即可。
例如:select pw from ctf where user='-1' union select 'mytest'
这样查询结果pw就是’mytest’这个字符串了。再看那个if语句,只看后面的判断,实际上只要输入的和查询的结果一致就行了。
注意别忘记输入pass后,会对其进行MD5加密。所以构造post:user=' union select md5('suqir')#&pass=suqir
查询语句就变为SELECT * FROM users WHERE name='admin' AND pass='pass';
转义
源码:
1 | <!-- |
分析:这题的clean函数用来过滤引号,会将其转化为实体编码,所以我们没有办法直接用引号来闭合了,只能运用转义字符来吃掉后面的那个单引号了,即构造username=suqir\&password=or%201%23
使得查询语句如下
SELECT * FROM users WHERE name='suqir\'' AND pass='or%201%23'
即
1 | SELECT * FROM users WHERE |
一道综合题:南邮CTF-综合题2及其writeup
GBK宽字节编码漏洞(gbk_sql_injection)
介绍:php中MYSQL数据库,如果是GBK编码.一定要小心GBK宽字节编码漏洞
正常情况下 magic_quote_gpc 为ON,如果输入
http://www.xxxx.com/index.php?user=11′ and 1=2 #
SQL语句就会变成
SELECT * FROM user WHERE user=’1\’ and 1=2 #’
自动加上了\转义,如果构造特殊的宽字节编码呢?
http://www.xxxx.com/index.php?user=11%df%27 and 1=2 #
SQL语句就变成
SELECT * FROM user WHERE user=’11運’ and 1=2#’
这样就注入上了!
11%df
会被解析成11運
,而%27
被邪恶的解析成'
就绕过了gpc转义,就成功构造注入了
Unix/Linux相关
bash_history
Bash shell在~/.bash_history
(~/
表示用户目录)文件中保存了500条使用过的命令,这样可以使你输入使用过的长命令变得容易。每个在系统中拥有账号的用户在他的目录下都有一个.bash_history
文件。
为了安全,bash shell应该保存少量的命令,并且在每次用户注销时都把这些历史命令删除。
删除方法: 第一步:/etc/profile
文件中的HISTFILESIZE
和HISTSIZE
行确定所有用户的.bash_history
文件中可以保存的旧命令条数。强烈建议把把/etc/profile
文件中的HISTFILESIZE
和HISTSIZE
行的值设为一个较小的数,比如30。编辑profile文件vi /etc/profile
,把下面这行改为:
1 | HISTFILESIZE=30 |
这表示每个用户的.bash_history
文件只可以保存30条旧命令。
第二步:网管还应该在/etc/skel/.bash_logout
文件中添加下面这行rm -f $HOME/.bash_history
。这样,当用户每次注销时.bash_history
文件都会被删除.
vi编辑器的备份文件
linux下一般使用vi编辑器,并且异常退出会留下备份文件xxx.swp
一句话木马
数组回调后门
源码:
1 |
|
分析:利用了php中回调函数的后门,可以使www
为preg_replace
函数,当array_walk()
将函数作用于数组时,POST传入的数据作为preg_replace()
的第二个参数,在替换后被当做 php 代码执行(在php5.3下可用,5.5后preg_replace函数已弃用了使替换后的字符串作为php代码执行的/e修饰符)。
测试:
未完待续。。。