Code-Audit-Challenges解题记录
Contents
github上面的代码审计“小”题目。
代码审计和开发不同的是,代码审计需要异常关注程序语言的各种
小边界,各种开发所遗漏的语言安全特性。
这里将记录我解答这些题目的思路,以加深我对各种语言安全特性的了解。
PHP
challenge 1
题目如下:
|
|
代码的意思很简单, 通过控制传入cookie的值使得最后的流程进入echo "Hello Admin How can I serve you today?\n";
代码块。
正常来说,我们传的cookie要是这样的: Cookie: user[0]=0;user[1]=unknowpassword;
,user[1]的
md5值需要跟9b5c3d2b64b8f74e56edec71462bd97a相等。
既然是md5相关的,那上cmd5.com查查看有没有相关记录,可惜没有。
提示也说了,admin的密码是个强密码,看来出题人不希望我们往密码爆破那方面去想。
尝试去查其他md5值,发现只有$users的第六个元素是可以查出密码的, 密码是: hund。
在比较$user和$input时,用的是===
,那么密码比较是无法绕过的,所有最终答案的user[1]肯定等于hund,
即Cookie: user[0]=5;user[1]=hund;
。
然而在比较$uid和0时,用的却是==
,或许我们可以通过php==
的类型转换来绕过比较。
到这里我就卡住了,怎么看都绕不过,提示里说代码跑在php 5.4.30,那么这可能是只存在于这一版本php里的
安全漏洞, 看下change log, 实在太多,找不到。看write up好了。
如write up所言, 在5.6.11之前的版本里面, php在比较数组index时犯了一个错,导致:
|
|
先看下php比较数组index的实现代码:
|
|
通过两个数组index相减来判断是否index是否相等,如上, p1->h减去p2->h.
问题在于h是unsigned long类型的整数, 在64位系统上有64bit, 而相减的结果result却是32bit的int
类型, 导致2的32次方减0的结果是0.
最后,答案已经很明显了: Cookie: user[4294967296]=5;user[1]=hund;
challenge 2
题目:
|
|
主要考查is_numeric和(int)之间的不同, php5钟is_numeric认为十六进制的字符串也是数字,而
(int)强制类型转换不能转换十六进制字符串, 那么答案便是?time=0x76a700
.
注意: 从php7.0开始is_numeric不再认为二进制字符串和十六进制字符串为数字。
challenge 3
题目:
|
|
这在真实情况中是有可能出现的,接受用户的信息,过滤后并把它写入到文件当中。
如果过滤不当的话很容易造成get shell.
我们看看这个, 首先对传入字符串addslashes,
例如’会变成', 然后会正则替换option.php中$option的值。
解法1
首先要明白'|\$option=\'.*\';|'
匹配单引号内的所有内容,但是不包括换行符。那么我们的思路
就是第一次写入一个单引号、换行符以及php代码,然后第二次把第一次的单引号注释掉,那么我们的
php代码就逃逸出来了。
例如: 第一次访问index.php?option=aaa%27%0a;phpinfo();//
,option.php文件内容变为:
|
|
此时第二次访问index.php?option=aaa
, 文件内容变为:
|
|
phpinfo();已经逃逸出来了
解法2
preg_replace替换字符串时会再进行一次转义操作的,例如''会变成'\',所以答案为:
|
|
$str的值为aaa\\\'%0a;phpinfo();//
,经过preg_replace后变成(此处存疑,preg_replace的转义机制是怎样的? ):
|
|
phpinfo();也已经逃逸出来了
challenge 4
由于原代码和题目考察的相关度不高,就不贴代码了。
大概意思是如果你可以控制命令注入的参数,但是参数中不允许出现.\/
三个字符,应该怎么弹shell呢?
解法1
用编码绕过:
|
|
优缺点: 存在字符长度问题,当然如果是无法连接外网的时候,这个还是能写shell的
解法2
十进制 —||||||> 十六进制 —||||||> 八进制 然后在访问时 指定协议然后加个0
http://0[八进制] 比如 115.239.210.26 首先用.分割数字 115 239 210 26 然后选择10进制转换16进制! (要用0来表示前缀,可以是一个0也可以是多个0 跟XSS中多加几个0来绕过过滤一样!)
首先把这四段数字给 转成 16 进制!
结果:73 ef d2 1a 然后把 73efd21a 这十六进制一起转换成8进制!
结果:16373751032
然后指定协议 http:// 用0表示前缀 加上
结果 链接: http://0016373751032
|
|
以上都行,总之算是个小技巧吧
challenge 5
题目:
|
|
大意是接受用户参数并写到php中,但是该参数中不要包括$black_list中的值, 就是不能数字,字母
以及一些符号。 然后跟JSFUCK类似,利用php中的异或,取反和字符串自增可以构建出可执行的php函数
和参数。具体可看一些不包含数字和字母的webshell.
动态语言真是可以玩出花来。
challenge 6
题目:
|
|
使用换行符: %0a可绕过过滤.
|
|
challenge 7
题目:
|
|
真是扭曲的代码,看得人头大,要是真实开发这么写非得让人打死不可。
题目大意是考察php弱类型比较,也算是经典题目了。 附爆破脚本一则,可自行修改:
|
|
challenge 8
应该是要考察sql注入,做不出来,先跳过