原文链接:某CMS审计之SQL注入篇(连载)
https://mp.weixin.qq.com/s?__biz=Mzg2NDY2MTQ1OQ==&mid=2247489939&idx=2&sn=4bba734bdfa1f5035f5c75ad3df4e74e&chksm=ce64a32ff9132a39fa84220d591ad1658be981dd4547954d02509c6cbba9df7583272674c12e&mpshare=1&scene=23&srcid=0325XqqqVRw0AgUVkluyveH6&sharer_sharetime=1648178978382&sharer_shareid=ee83a55e0b955b99e8343acbb61916b7#rd前言 最近工作不是太忙,正好达达做公众号需要文章,就审计一个小CMS帮达达发一下。 温馨提示:本篇只用来学习交流技术,不要将所学技术用到违法的事情上面。 网站配置: 后台管理员账号密码:admin/admin 数据库账号和密码: >代码审计: @SQL注入1: 查看源码cms/admin/art_list.php: 通过源码这里发现,这里利用isset()函数来判断$_GET['tid']传递的tid值是否为空,然后再将GET方式传递的tid值赋值给变量$tid,下面的代码就很关键: $tid_zis=$c_sql->select("select id from type where tid={$tid}"); 这里就是$c_sql来引用select("select id from type where tid={$tid}"),这里就继续追踪select()函数发现在/cms/include/class_sql.php被定义: 这里就发现select($sql)函数下面是直接执行了,那么这里就有问题了,在前面GET方式进行传参的时候tid并没有进行过滤,这里在进行调用select()函数来查询数据库的时候是直接执行了,所以这里就存在SQL注入,那么就可以进行漏洞检测,通过源码我们可以定位到是art_list.php: 然后根据代码,是通过GET方式来传递tid值,所以可以构造payload: http://127.0.0.1:8086/cms/admin/art_list.php?tid=3 and (length(database())>3) 这里发现回显正常,继续进行判断,通过判断数据库长度是否大于6发现回显和判断是否大于3的时候不一致,所以继续判断: http://127.0.0.1:8086/cms/admin/art_list.php?tid=3 and (length(database())>6) 继续判断数据库长度是否等于6,回显正常,所以这里判断正确,查看数据库长度为6: http://127.0.0.1:8086/cms/admin/art_list.php?tid=3 and (length(database())=6) 这里就可以继续判断数据库库名的第一个字符,发现ascii码大于122时,回显无数据,但是ascii码为122时,回显正常,ascii码为122是正好对应的字符串为“z”: http://127.0.0.1:8086/cms/admin/art_list.php?tid=3 and (ascii(substr(database(),1,1))>122) http://127.0.0.1:8086/cms/admin/art_list.php?tid=3 and (ascii(substr(database(),1,1))=122) 这里就是成功的通过回显发现存在SQL布尔注入。 @SQL注入2: 查看源码查看源码cms/admin/art.php: 这里就发现此处代码含义和之前art_list.php代码中的含义一样,同样都是使用GET方式来传值,但是在传值的过程中,并没有做过滤,同时还是调用了select()函数来执行SQL语句,从而触发了SQL注入,这里就可以继续测试一下: http://127.0.0.1:8086/cms/admin/art.php?aid=1 and (length(database())=6) 这里也是通过布尔注入测试发现数据库库名的长度为6,可以继续测试数据库库名的第一个字段的ASCII码: http://127.0.0.1:8086/cms/admin/art.php?aid=1 and (ascii(substr(database(),1,1))=122) 通过结果发现ascii码大于122时,回显无数据,但是ascii码为122时,回显正常,ascii码为122是正好对应的字符串为“z”,所以可以知道这里存在SQL注入。 @SQL注入3:前端 通过之前的分析,这里我们知道在/cms/include/class_sql.php被定义的select($sql)函数是可以执行SQL语句的 $query = mysqli_query($this->link(),$sql),所以这里可以全文搜索select()函数在哪里进行了调用: 查看源码查看源码cms/include/make.php: 在这里就发现有一个if判断,如果利用GET传值的php和art不为空,就会执行下面的 SQL语句:$tid=$c_sql->select("select tid from art where id=".$_GET['art']); 所以这里就可以直接构造payload: http://127.0.0.1:8086/cms/include/make.php?php=0&art=1 and (length(database())=6) 这里也是通过之前的回显来判断数据库库名的长度,这里就发现当库名长度为6的时候和正常回显是一样的,不为6的时候则网页输出了字符串,所以这里也是存在SQL注入的,这里使用SQLMAP来测试一下: 通过SQLMAP测试,这里是存在SQL注入。 @SQL注入4:前端 继续通过搜索select()函数的调用,查看源码查看源码common/php/ajax.php: 通过源代码发现,这里存在一个if判断,变量$run=ad并且通过GET方式来传递id值,然后就通过接收GET方式传递过来的id值来进行执行select()函数中的SQL语句,由于通过GET方式传递的id值并没有进行过滤,所以这里就判断存在SQL注入,这里就可以进行测试: http://127.0.0.1:8086/common/php/ajax.php?run=ad&id=1 and (length(database())=6) 这里也是通过之前的回显来判断数据库库名的长度,这里就发现当库名长度为6的时候和正常回显是一样的,不为6的时候则网页在输出中并没有“xxxxx”而是空的,所以这里也是存在SQL注入的,这里使用SQLMAP来测试一下: 这里就通过SQLMAP测试出来是存在SQL注入的,同时存在多个类型的SQL注入,这里既然存在union类型的SQL注入,就可以进行union注入测试: 这里就发现利用union注入,成功回显出来数据库的库名。 同理,查看源码查看源码common/php/ajax.php: 通过源代码发现,和之前的SQL注入源代码类似,这里存在一个if判断,变量$run=dj并且通过GET方式来传递id值,然后就通过接收GET方式传递过来的id值来进行执行select()函数中的SQL语句,由于通过GET方式传递的id值并没有进行过滤,所以这里就判断存在SQL注入,这里就可以进行测试: http://127.0.0.1:8086/common/php/ajax.php?run=dj&id=1 and (length(database())=5) 这里也是通过之前的回显来判断数据库库名的长度,这里就发现当数据库为6的时候,回显是document.write('8'),而当数据库库名为5的时候,回显是document.write('0'),这里就是通过判断write('数字')中的数字来进行判断,如果为0则布尔判断错误,如果大于0则布尔判断成功,这里也可以通过源代码中的注释“点击量api”和后续的代码可以知道,这 里的点击后,“document.write('{$dianji}')”这里的('{$dianji}')在后续的代码中是进行了+1,所以在正常回显的时候是会进行加1的。布尔SQL注入测试和分析完代码后,继续测试来进行查看是否有其他回显: http://127.0.0.1:8086/common/php/ajax.php?run=dj&id=-1 union select database() 这里就可以成功通过union注入得到正常的回显数据库库名。 @SQL注入5: 继续通过全文搜索select(),查看源码/api/caiji.php: 这里通过源码发现,当run=shenhe时进入else if判断,同时利用GET方式来传递lanmu参数,然后在调用select()函数执行SQL语句,这里也是和之前的SQL注入代码同理,都是在run参数等于特定的字符串时进去if判断,然后传递的GET参数并没有进行过滤,传递的参数直接执行了SQL语句,所以这里可以进行SQL注入尝试,直接构造payload: http://127.0.0.1:8086/api/caiji.php?run=shenhe&lanmu=1 and (length(database())=6) 这里通过回显发现,当判断数据库库名长度为6和7的时候,回显一样,并没有不同,所以这里无法判断是否存在SQL注入,继续查看源代码,发现其中的SQL执行语句和之前的SQL语句有所不同,在语句后面添加了limit 1,并且还用where关键字,利用()括号把后面输入的{$tid}包起来,所以这里就可以修改一下payload,将and修改为or: 这里通过将and修改为or后,回显的结果即为不同,这里就可以继续SQLMAP来测试一下: 到这里,关于这个CMS的SQL就结束了。
|