fei's work logs

fei's work logs

Stay hungry, stay curious

RouterSpace [Easy]

  • nmap,访问web端口,下载apk,用anbox安装运行,设置代理,burp抓包,运行apk,看到访问routerspace.htb,同时post请求一个ip,这里可以注入命令。绑定host后,注入反弹shell,获取普通用户权限。
  • 通过sudo漏洞提权获取root权限。

Catch [Medium]

  • nmap,4个服务:gitea,lets chat,cachet,web,通过web下载apk,apk反编译,里面有3个token。通过lets chat token获取room,message列表,里面有john账号密码,可以登录cachet。cachet有sql注入,sqlmap跑user表获取john的token,cachet集成的twig模板有命令注入漏洞,但是只可以在api方式下调用可触发命令执行,后台添加模板,再用john的token调用api创建incident,触发模板命令注入反弹shell,拿到普通用户权限。
  • 通过pspy64s监控有个sh脚本定时运行,脚本里APP_NAME是从apk里提取的,可注入命令。修改apk注入sh需要的命令,cp bash再chmod u+s,重新打包签名,放入指定目录,执行bash -p,成功获取root权限。

Retired [Medium]

  • nmap,一个web服务,参数可实现任意文件读取,读index.php知道过滤规则,可用file://绕过,读取文件无果。扫路径,发现beta.html,表单有个activate php,查看php内容,功能是socket send用户上传的文件到1337端口。通过/proc/scdhed_debug查看进程,找到activate进程,通过/proc/pid/exe下载文件。逆向,一个栈溢出漏洞,开了nx aslr pie,下载glibc用于构造rop,查看/proc/pid/maps确定基址,构造反弹shell rop成功拿到shell。进去后有个定时zip备份任务,通过软连接把用户目录备份出来,用id_rsa成功ssh获取普通用户权限。
  • 查看用户主目录下有emuemu,查看代码发现用到了binfmt_misc机制,可利用此机制构造shadow suid进行提权。找相对唯一的具有suid的文件头作为mask,该文件作为被解释文件,解释器则是提权程序,flag加上C,拼接作为参数,运行reg_helper添加binfmt_misc,这里关键是reg_helper文件具有dac cap,可绕过文件权限控制。运行被解释文件触发解释器提权,成功获取root权限。

Timing [Medium]

  • nmap,一个web服务,dirsearch扫描发现image.php,爆参数名img,可读取系统文件。读passwd知道用户名aaron,用aaron作为密码登录web系统,权限低,通过编辑信息处加role=1提高权限。在上传头像处上传图片马,通过源码审计猜上传路径名,通过马遍历系统目录,发现/opt下面zip备份文件。拖回来分析,发现.git,dump出db_conn.php的历史记录,里面的密码可ssh登录aaron账号。
  • sudo -l查看权限,可以root执行netutils,软连接/root/.ssh/authorized_keys,再提供ssh公钥链接下载到软连接的路径,可ssh免密登录root。这里有个要注意的是如果keys文件存在就无法下载覆盖了,会被重命名为.0,需要重置机器。

Meta [Medium]

  • nmap,一个web服务,301跳转到目标域名,hosts绑定域名,扫描目录无果。扫子域名,发现dev01,有一个上传页面,处理展示图片exif信息。猜测后台使用的是exiftool,通过对应exp获得反弹shell。pspy64s查看用户thomas有定时处理图片的任务,使用该ImageMagick组件的exp可获取thomas的id_rsa,用key pair登录获取权限。
  • pspy64s查看有neofetch定时在跑,审计脚本发现变量XDG_CONFIG_HOME可控,指向自己的配置文件,配置文件里可直接写反弹shell命令,获取root权限。

Unicode [Medium]

  • 扫描,一个web服务,有一个重定向的地址,注册,登录,发现cookie是jwt,通过jwt.io解开,保存header里jku指向的jwks.json,通过mkjwk.org生成rsa秘钥,替换jwt payload里user为admin,替换header里jku地址为重定向地址,重定向到自己主机上的jwks.json,替换本机jwks.json的n为生成的n,此时用生成的key替换cookie,可登录admin dashboard。有个链接可读任意文件,用unicode ‥替换..,可绕过过滤。读取nginx的两个配置文件,再读db.yaml,可读到mysql配置,用密码可登录用户code的ssh。
  • sudo -l查看权限,treport可以root下载文件,下载treport逆向,使用File://绕过过滤,也可使用{--config,file},file里可配-o和url。读取root.txt,此时可以读取id_rda,不过公钥没有加入authorized_keys文件,不能登录。

Talkative [Hard]

  • 扫描,bolt cms、jamovi在线报表和rocket.chat在线im。通过jamovi的R插件执行system命令,把root目录下omv文件base64后显示出来,还原再unzip,得到3个账号密码。用其中一个登录bolt cms,后台编辑文件利用twig模板注入bash base64反弹shell。shell环境是docker,用nps把流量转发出来,通过sock5代理ssh登录宿主机的saul账号,拿到权限。
  • ps查看mongodb在运行,尝试探测几个docker ip的27017端口,用db客户端通过上面nps转出来的sock5代理连接db,无认证,查看数据确认是rocket.chat的db。注册一个账号,修改db数据使其具有admin权限。在后台通过incoming webhook的js script添加反弹base64 shell,代码从历史exp中找的。请求一下webhook url触发执行代码,用pwncat接收shell,在无curl、wget等命令下可上传下载文件,可升级pty完全交互。上传cdk探测存在可利用的cap,直接读取root.txt文件即可。

AdmirerToo [Hard]

  • 开放22,80,扫描无果,通过404页面的mail链接发现域名,绑定到hosts文件,再扫描子域名,发现db子域名。db的web页面是Adminer组件,页面源码有密码,无用。该组件有ssrf漏洞,通过ssrf扫描到4242端口,是opentsdb,通过opentsdb的rce反弹shell,翻看组件目录下的配置文件,找到一组密码,可登录普通用户ssh。
  • 普通用户下查看端口8080开放,访问是opencats组件,可用上述密码登录。该组件有个任意文件写漏洞,但权限受限,是devel用户权限。翻看系统服务,有个fail2ban可利用,mail-whois可rce,用任意文件写的exp写whois.conf到local etc下,本机监听43端口回复反弹shell,再触发登录失败,获取反弹shell,root权限。

Late [Easy]

  • 扫描,web页面,一个images域名,绑定hosts。打开访问是一个上传ocr识别功能,识别结果存在ssti注入。用ps构造一个反弹shell命令放入图片,成功反弹获取权限。
  • pspy64查看一个脚本定时执行,修改有权限的脚本加入chmod u+s bash,再登录触发,即可获取root权限。

Paper [Easy]

  • 扫描,http response header有个域名,绑定hosts,访问是WordPress,使用漏洞查看隐藏文章,有个chat域名,绑定后访问,注册账号,有个聊天机器人,可以遍历和查看文件,查看到机器人配置文件有个密码,可ssh登录普通用户。
  • 使用linpeas扫描,提示polkit漏洞,利用exp获取权限。

Pandora [Easy]

  • 扫描,无果,扫udp,发现snmp 161 udp端口开放,用snmpwalk发现敏感信息,有个账号密码可ssh登录,但无flag。在ssh里curl本机80端口发现pandora服务,通过nps转发出来,用本地浏览器访问,搜索该组件版本漏洞,有个sql注入漏洞,可枚举表信息,找到用户matt的密码,cmd5破解,可以登录ssh。
  • 通过find suid找到一个backup文件,逆向发现是调用tar压缩文件夹,尝试通过tar参数提权,但是绝对路径,无果。这里可以在自己路径下写个tar脚本再覆盖环境变量,优先执行自己路径下的tar,即可提权到root。

Phoenix [Hard]

  • 扫描,WordPress,wpscan识别插件forum,搜索存在基于时间的盲注exp,用sqlmap跑,比较慢,可dump表users、options。users密码hash可用john加字典跑出来3个,字典用rockyou.txt。options表识别另外一个插件存在文件上传漏洞,要注意上传的扩展名phtml,通过上传反弹shell获得权限后,分析双因子插件,usermeta表有加密的secret,通过扣取插件源码可解密secret,用google Auth可生成OTP,可登录WordPress后台,不过没啥用,不能用于ssh登录。查看网卡存在另外一个ip,ssh这个ip用上述密码登录,可绕过该机器的pam双因子认证,获取普通用户权限。
  • 通过搜索本地文件,发现local bin下有个root的可执行文件比较可疑,执行用pspy64看下调用了tar rsync做备份,其中rsync命令行猜测是*通配符展开,这里可以用rsync的-e参数执行命令,用反弹shell配合参数,即可反弹获取root权限。

Hathor [Insane]

  • 扫描,ldap、dns、smb枚举,无果。扫描web,发现用的是mojoportal,搜索默认账号密码,成功登录后台,通过文件编辑和修改后缀为aspx得到反弹shell。在c盘根目录下获得bm账号的hash,cmd5反查得到密码,通过账号密码在远程机器上挂载smb共享目录。

Timelapse [Easy]

  • 扫描,smb枚举,shares可匿名读取,下载zip文件,字典破解,得到pfx证书,再字典破解,从pfx文件导出公钥和私钥,使用公私钥可evil-winrm连接到主机,获得普通用户权限。
  • 在主机运行winpeas,可获取powershell的一个敏感文件,里面有另一个账号密码,该账号有laps权限,使用cme导出域控的密码,登录可获取域控权限。

Undetected [Medium]

  • 扫描,只有web,页面有个store域名,绑定hosts,扫描路径,发现phpunit组件,搜索到rce的exp,直接拿到www的反弹shell。再搜索到可疑二进制文件info,通过strings发现base64字符串,解码后可看到密码hash,爆破,拿到密码可登录获得普通用户权限。
  • linpeas查看有mail,说apache有异常,排查modules目录下有一异常时间文件,通过strings发现base64字符串,解码发现sshd文件可能被植入后门,逆向分析,在auth_password验证密码处有后门密码,xor后拿到后门密码登录root获得权限。

Noter [Medium]

  • 扫描,开放ftp,web,注册账号,尝试用不存在账号登录可发现响应内容有区别,用用户名字典爆破出一个账号名。通过cookie可猜到是flask的应用,类似jwt,用flask-unsign可解开cookie,破解出secret,用前面爆破出的用户名替换进去在签名出cookie,注意签名的机器时间要对,不然用不了。用这个cookie可查看所有note,通过note内容得知密码和规则。用账号密码登录ftp,下载文档查看得知默认密码规则,可得出ftp_admin密码,登录ftp下载zip备份文件。文件里有mysql的账号密码,同时查看源码可挖一个rce,通过rce可反弹shell,获得普通用户权限。
  • 用上述mysql密码登录mysql,由于mysql运行的账号是root,可通过udf提权,写入一个udf,提权获取flag文件内容,注意mysql会定时清理数据,可以把命令放一起执行节省时间。

basis

pip install frida-tools # CLI tools
pip install frida # Python bindings
pip install objection
frida-ps -U
objection: memory list modules

tcpdump

tcpdump -i any -s 0 -w /sdcard/capture.pcap

sslkey with wireshark

frida -U -f com.twitter.android -l ./sslkeyfilelog.js --no-pause
filter in wireshark: (http.request or tls.handshake.type eq 1) and !(ssdp)

disable ssl pinning

objection --gadget "com.twitter.android" explore

- android sslpinning disable  
- ios sslpinning disable  

frida --codeshare machoreverser/ios12-ssl-bypass -f com.ss.iphone.ugc.Aweme -U
frida -U --no-pause -f com.ss.iphone.ugc.Aweme -l ssl.js

frida-ios-dump

win env:

- download & place zip from http://stahlworks.com/dev/index.php?tool=zipunzip  
- comment "chmod" call  

py -3 dump.py -l
py -3 dump.py -H 192.168.3.129 -p 22 "Aipo"

url dump

frida-trace -U -f identifiers.home1.huanjing6id -m "+[NSURL URLWithString:]"
show url: edit in handlers add log(ObjC.Object(args[2]))

socket dump

frida-trace -U -f identifiers.home1.huanjing6id -m "-[GCDAsyncSocket connectToHost:onPort:viaInterface:withTimeout:error:]"  
frida-trace -U -f identifiers.home1.huanjing6id -m "-[GCDAsyncSocket writeData:withTimeout:tag:]"  
hook all methods in class: frida-trace -U -f identifiers.home1.huanjing6id -m "*[GCDAsyncSocket *]"   
frida-trace -U -f identifiers.home1.huanjing6id -i "*SSL_write*"  
show host/data: edit in handlers add log(ObjC.Object(args[X]))  
show callstack:  
>var threadClass = ObjC.classes.NSThread  
>var symbols = threadClass["+ callStackSymbols"]()  
>console.log(symbols)  
OR:  
>console.log('\tBacktrace:\n\t' + Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n\t'));  

socket dump

objection --gadget "Aipo" explore

- ios hooking search classes socket  

generate hook.txt: ios hooking watch class XXX
objection --gadget "Aipo" explore -c hook.txt

- ios hooking watch method "XXX" --dump-args --dump-backtrace --dump-return  


v1

cat * | sort | uniq > out.txt

v2

cat * | awk '{ if (!seen[$0]++) { print $0; } }' > out.txt

v3

#!/bin/ksh

MAX_LINES_PER_CHUNK=5000000
ORIGINAL_FILE=$1
SORTED_FILE=$2
CHUNK_FILE_PREFIX=$ORIGINAL_FILE.split.
SORTED_CHUNK_FILES=$CHUNK_FILE_PREFIX*.sorted

usage ()
{
     echo Parallel sort
     echo usage: psort file1 file2
     echo Sorts text file file1 and stores the output in file2
     echo Note: file1 will be split in chunks up to $MAX_LINES_PER_CHUNK lines
     echo  and each chunk will be sorted in parallel
}

# test if we have two arguments on the command line
if [ $# != 2 ]
then
    usage
    exit
fi

#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null
rm -f $SORTED_FILE

#Splitting $ORIGINAL_FILE into chunks ...
split  -l $MAX_LINES_PER_CHUNK -a 4  $ORIGINAL_FILE $CHUNK_FILE_PREFIX

for file in $CHUNK_FILE_PREFIX*
do
    sort $file > $file.sorted &
done
wait

#Merging chunks to $SORTED_FILE ...
sort -m $SORTED_CHUNK_FILES > $SORTED_FILE

#Cleanup any lefover files
rm -f $SORTED_CHUNK_FILES > /dev/null
rm -f $CHUNK_FILE_PREFIX* > /dev/null

v4

#!/bin/bash
lines=$(wc -l $1 | sed 's/ .*//g')
lines_per_file=`expr $lines / 16`
split -d -l $lines_per_file $1 __part_$1

for file in __part_*
do
{
  sort $file > sort_$file
} &
done
wait

sort -smu sort_* > $2
rm -f __part_*
rm -f sort_*

v5

nice -n -20 ionice -c2 -n7 sort --parallel=16 -uo out.txt all.txt

符号配置

SRV*d:\Symbols*http://msdl.microsoft.com/download/symbols

启动自动附加

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\calc.exe]

"Debugger"="\"D:\\WinDbg(x64)\\windbg.exe\""

加载模块断点

sxe ld:[dll name]

所有模块

sxe ld:*

卸载模块断点

sxe ud:[dll name]

卸载所有模块

sxe ud:*

显示所有线程堆栈

~*kb

内存dump

.writemem path startaddr endaddr

字符串搜索

s -sa 01570000 L61000 搜索ascii

s -su 01570000 L61000 搜索unicode

s -a 0 L?80000000 "to_search" 搜索指定字符串

开页堆

gflags.exe /i test.exe +hpa

模块加载记录

bm msxml6!* ".frame;gc"

sxe ld msxml6
bm /a msxml6!DOMDocument* ".echo callstack; k L5; .echo ESP; dc esp L8; .echo return value; pt;"

https://research.checkpoint.com/2018/50-adobe-cves-in-50-days/

调试子进程

set follow-fork-mode child


1.二进制搜索12 34 56 78,往后偏移8字节后开始的4字节是code_bytes长度,之后是库文件名,以00结尾,之后就是code_bytes。

si = struct.pack("iiii",
    0x78563412, # a magic value,
    self.optimize,
    self.unbuffered,
    len(code_bytes),
) + relative_arcname + "\000"
script_bytes = si + code_bytes + '\000\000'

2.把code_bytes拿出来,在python中反序列化后找到需要code obj的再序列化。code obj可能嵌套code obj,用inspect.getmembers(code_obj)去找到list中的code obj位置,再dump出来。

>>>import marshal
>>>mylist=marshal.load(open("dumpfile", "r"))
>>>marshal.dump(mylist[1], open("main.pyo","w"))

3.pyo文件加上8字节header就可以反编译了。前 4 个字节代表 Python 版本号,后 4 个字节是 timestamp。文件头可以是:03 F3 0D 0A 37 77 83 56 。