代码审计之各语言相关[ING]

Published: 二 15 三月 2022

In Vuln.

慢慢记,现在是草稿状态,不要看!!!!

PHP

php有很多语言特性可能会造成安全问题...危险函数:

类型 说明
命令执行 system(),     passthru(),    exec(),     shell_exec(, ``    ,     popen(),     proc_open(),     pcntl_exec(
代码执行 eval\s(,     asert\s( ,preg_replace\s(,     call_user_func\s(,    include,    require,call_user_func_array(,     create_function(,     array_map(,     ob_start(,     mail(,     usort,     uasort
反序列化 unserialize,    phar
变量覆盖 $$,    extract,    parse_str,    import_request_variables,    register_globals=ON(配置文件)
文件操作 file_get_contents,    file_put_contents,move_uploaded_file,    rename,unlink,    rmdir,fopen,    fread,    fwrite,    fputs,    fgets,    fgetc
解码操作 base64_decode,    urldecode,    decode,aes,    des,    sm4,    (a)rc4,    ,blowfish,    ,crypt,    decrypt,md5,    auth, rand,    srand,    seed

短标签:

<?php ?>
<%  %>  <!--需要开启 -->
<?  ?>
<?= >  <!--总是有效 -->
<script language="php"> </script>  

一些语言特性:

特性 说明
弱类型 =====,字符串与数字比较等,0与false等
反序列化漏洞 反序列化可构造任意值,而一些魔法方法(__destruct__toString__sleep__wakeup__call__construct)若存在问题可执行危险操作
截断 在旧版中\x00会被截断(Windows也会有),iconv在转换时遇到非法字符也可能会截断
伪协议 gopherzippharphp等协议
变量覆盖 $$等可覆盖其他变量的值

特殊配置:

配置 说明
register_globals 早期支持,会把请求注册到全局
magic_quotes_gpc 设置后GPC的'"\0x00会被转意
disable_functions 限制了能使用的函数,通过其他其他组件绕
open_basedir 限定了能打开的目录,可通过DirectoryIterator+Glob绕

附:由于PHP代码保护已经比较成熟,很多产品会使用一些保护方案,此时可尝试用https://www.dezender.net/,https://www.unzend.com/,http://www.dezend.ir/,https://easytoyou.eu/等去解密。

shell

  1. shell需要过滤的字符:\'"|<>()[]~?*{};&$\r\n"重音符\在不需要转义的字符上无效,一个正确的转义方法是将参数用''包裹,并将所有'替换为'\''

  2. 对于空白符可尝试用${IFS},$IFS$9,%09 等方式绕过。

  3. 注意一些命令的参数,如find-exec {} \;-ok,-deleteawksystemprint等都可以执行命令

Python

沙盒逃逸

Python 沙盒绕过禁用import的情况下绕过python沙箱用python继承链搞事情...

反序列化

PyYalm和自身的序列化都可实现任意代码执行,存放于外部的pickle数据也是不安全的,如redis可能存在漏洞数据被改写,可参考Python反序列化漏洞的花式利用Python pickle 反序列化实例分析...

格式化串

Python格式化字符串漏洞(Django为例),Python的format若能控制格式化串则可泄漏任意数据,而f’’型若内容可控则可执行任意代码,不过后者出漏洞的情况应该很少。Python Web之flask session&格式化字符串漏洞。对此的防御当然是不让它可控最好,若实在要可控就上沙盒过滤吧

命令注入

Python内置的代码注入就是system/popen/subprocess/getoutput等方法,一般现代的代码会使用subprocess库,此时就看有没有用shell=True与列表传指令参数,其他若是拼接当然是看过滤是否可以绕过,shlex.quote(),可参考Python Command Execution

代码注入

eval/exec/timeit/execfile/assert/compile/input,一般eval可考虑用ast.literal_eval或json等函数代替

模板注入

模板注入一般会用到格式化串和沙箱逃逸的方法

目录穿越

有个经典的问题就是在目录拼接时,追加的路径以/字符:/开始将丢弃前面的目录,以此作为起始位置继续拼接

XXE

如果是defusedxml就当是很安全吧,毕竟下面这张图就是作者做的,其他的可以库可见下图:

image-20220721191343262

sax包从3.71默认禁用外部实体,或者使用xml_parser.setFeature(feature_external_ges, False)禁用;lxml需要手动XMLParser(resolve_entities=False, no_network=True)禁用;其他如图...

其他还可参考:[0]Pythonanquan,[1]关于Python sec的一些简单的总结

之前还有两个有名的CRLF漏洞urllib header inject(CVE-2016-5699,CVE-2019-9740) 有时也要关注导入的库,特别不知名的库可能就写了漏洞

JS

基础

node可通过添加启动参数--inspect或发送SIGUSR1启用,它默认监听9229端口,远程调试可使用如下命令建立ssh隧道[1]:

ssh -L 9229:localhost:9229 <root>@<192.168.30.204>

对于EGG,它会有多个进程,若存在或可以安装egg-bin时可使用npm run debug命令开启调试[0],否则可以直接在想调试的进程上开调试,如调试工作进程可修改app_worker进程数为1后,直接在它上面开调试。

原型链污染

最出名的是原型链污染,js是基于原型的,在读写属性时若本地没有则会向上查找,可通过这种特性去修改原型链上的属性值,基于该原型的其他实例可能会使用该值,进而造成其他漏洞[2, 3],具体来说如果能出现这种a[x][y][.]*=z语句,我们能控制xyz即可进行污染,但是通常不会出现这种情况,而是出现在递归合并与点分路径解析中,如[5]曾经爆的命令执行漏洞。

当出现原型链污染时,需要根据具体应用分析可行的利用方式,如绕过授权或命令执行,通过AST工具[9]来执行代码....

命令注入

在使用child_process时,有三个命令执行函数,exec直接调sh -c最危险,execFilespawn直接调程序一般没问题,但是如果加了shell=true选项时也有问题[6]。

SQL注入

同,基本都是用参数化查询或者ORM因此出现问题概率是比较小的,node下常见的是node-mysqlSequelize,这里简单记录下监视点的位置:

node_modules/sequelize/lib/dialects/mysql/query.js:run

同,有些语法无法用参数化,如like此时开发人员可能会做一些危险的操作,如用Sequelizeliteral方法,此时如果没有正确的过滤就可能存在安全问题。

反序列化

另外它也逃不脱反序列化影响,而且它的反序列化是最容易利用的,既不需要利用链也不需要构造复杂的payload,见[4]。

XXE

一般不会有问题,但是若libxmljs使用了{noent: true}选项则存在问题,sax-js不会处理自定义的DTD因此没问题,而xml2js依赖于sax-js因此也不受影响。

模板注入

一例[10]

其他

Buffer(Num)会存在未清空数据...

参考

[0] Node.js 和 Egg.js 项目远程调试 -- HANK WEI (2020)

[1] NODEJS官网:调试指南

[2] 深入理解 JavaScript Prototype 污染攻击

[3] Prototype pollution attack

[4] 利用 Node.js 反序列化漏洞远程执行代码 -- Ajin Abraham, Holic[译] (2017)

[5] 例: Prototype Pollution in Kibana例: Remote Code Execution via Prototype Pollution in Blitz.js

[6] Command Injection in Node.js -- NF997, gkouziik (2020)

[7] From Markdown to RCE in Atom

[8] Modern Alchemy: Turning XSS into RCE

[9] AST注入 --

[10] The Secret Parameter, LFR, and Potential RCE in NodeJS Apps -- CAPTAINFREAK (2021)

[11] A tale of making internet pollution free -- s1r1us...

Lua

除了cgi,lua经常会和nginx(openresty)一起出现,由于其性能很好因此正在被很多厂商采用成功焕发第二春因此需要多研究...

  1. 代码执行:loadfile,dofile,loadstring,require,loadlib

Perl

  1. 命令执行:system,exec,execvp,

Golang

千言万语

Go是编译型语言,入口比较稳定,像web也可以直接从main开始跟路由/中间件注册情况...

项目布局

- my-go-project
 - cmd  入口代码如主函数放这里
 - pkg  /外部依赖
 - internal  内部库在编译时会检查约束其内部可以继续命名目录来指定给哪个应用使用
 - go.mod && go.sum  go模块依赖
 - Makefile  编译脚本

编译与调试

远程调试有两种方法,先编译或直接指定项目源码,它们都需要先安装dlv服务端:

# 直接使用delev编译并调试项目
dlv debug --headless --listen=:2345 --api-version=2 --accept-multiclient

# 先编译带符号的项目再调试 
go build -gcflags "all=-N -l" github.com/app/demo  # 1.10及之后的版本
go build -gcflags "-N -l" github.com/app/demo  # 之前的版本
# 调试方式启动也可以使用attach方式附加在运行中的进程上
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./demo

其中为-gcflags编译选项,-N表示禁用优化,-l表示禁用内联。

常见组件

数据库

之前提到如果用了ORM框架一般都是比较安全,但是可能会漏掉一些或者某些点无法预编译,因此这里的检查就是查看所有的语句看是否存在问题...

Gorm

Exec, Raw, Select, Where

Sql

Query, QueryRow, QueryContext, QueryRowContext

Xorm

Query, QueryString, SQL, Where

Etcd

ETCD是一种用于分布式系统的键值型数据库,它主要用于存储配置信息,可使用etcdctl get --prefix ''获取所有的数据

WEB

Gin

序列化

protobuf

在调试接口时可以使用postman,它也支持websocket/grpc请求,不过离线环境不可用(垃圾!),所以替代的grpc可食用bloomrpc

通用问题

XSS

没问题的

如直接输出未进行任何过滤,使用模板...

特性问题

命令注入

exec.Command
exec.CommandContext -> CombinedOutput/Output/Run/Start

testres,err :=exec.Command("sh", "-c", testStr).Output()

**subshell**

文件写

os.OpenFile("./assets/img/"+handler.Filename,os.O_WRONLY|os.O_CREATE,0666) 

模板注入

它自带了text/templatehtml/template,前者容易出现xss后者会编码,除此之外的模板注入比较难利用,它的语法见文档

内存破坏

Go本身是内存安全的,但是为了提供一些烧操作接口,还是提供了两个库:unsafe可进行有限的指针运算,cgo能粘合C代码,因此当使用这两个库时需要仔细检查是否有内存破坏的问题...

未检查错误

当会返回错误状态时需要先检查错误再继续使用返回值,没检查可能会有问题...

整数溢出

Go的整数有长度限制,因此在进行运算或类型转换时可能存在溢出/截断...

自动化工具

  1. gosec: 通过分析Go代码的AST与规则匹配扫描问题(试了下各种报错...)
  2. gokart: 使用SSA做静态分析,支持污点追踪...

参考

  1. https://github.com/OWASP/Go-SCP

Misc

暂时不知道放哪里,就先扔这里吧,在挖掘CGI时为了调试方便可以先替换原文件并且抓包:

#!/bin/bash

echo 'Content-type: text/html'
echo 

env

while IFS= read -r line; do
  printf '%s\n' "$line"
done

或:

#!/usr/bin/python

import os
import sys

res += '\n'.join(["export %s='%s'"%(i,j) for i,j in os.environ.items()])
with open('/tmp/post_data', 'wb') as f:
  f.write(sys.stdin.read())
print("Content-type: text/plain")
print("Content-Length: " + str(len(res)) + "\r\n")
print(res)

之后再用直接source导入环境变量并使用<重定向输入即可,此时可用strace,或是gdb:

gdb file
> b *xxx
> run file params < /tmp/post_data