- Score:
- Description:
- Write two programs with the following properties:
- On a host, called server host, write a program, called
password_holder.c
, that allows a user to input a character string. - After obtaining an input string from a user,
password_holder.c
opens a TCP/IP socket and listens on the socket to wait for any incoming request from a host, called client host. - When an incoming connection is established,
password_holder.c
sends the input string to the the client host as a password. - On a host, called client host, write a program, called
mission_impossible.c
, that connects to the above remote server to retrieve a password. - The compiled executable file of
mission_impossible.c
is called mission_impossible.exe
. - After obtaining a password from the above server,
mission_impossible.c
asks its users to input a password. - If an input password is identical to the passwrod that
mission_impossible.c
retrieved from the above server, the program will execute a piece of code, called Mission Briefing Code (MBC) hereafter, that will display the following message ("Ethan Hunt, Run Now!") for 2 minutes and then delete the file
and terminate itself. - If an erroneous password is input, the program will delete the file mission_impossible.c and terminate itself.
- Initially, MBC must be stored in a global array and is encoded with your password. You can use any approach to encode MBC. When the input password is correct, your program will decode MBC and place it in the heap and then transfer your execution flow to the decoded MBC.
英文太差了,於是中文翻。
- 首先,password_holder.c 是一 server 端的程式,必在行向者求入一密,密做 client 端程式的依,得到入密後,等待 client 上,後密 client 端的程式。server 端的程式功能到此止。
- 接著,mission_impossible.c 是一 client 端的程式,必在向 server,接收由 server 的密。比懂的地方在於 MBC 的存在,MBC 一段 ASM code,且以列形式的方式存在 mission_impossible.c 的全,因作是限制的。
- 藉由 function pointer MBC 的料成程式中的一部分行 (不然一般而言,料究只是料,不可以行的),而在 MBC 段 ASM code 要做 1) 打印字串 2) 停止分 3) 除指定案
- 如何撰 ASM code ? 其很一言道,首先要理解段 ASM code 一般 ASM 有何不同,先去照 http://www.vividmachines.com/shellcode/shellcode.html 的介。
char code[] = "bytecode will go here!";
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}
段是核心的,*func 即是上面所述的 function pointer,首先 data 段的料位址制成的 function pointer 的型,藉由 call function 跳到 data 上行。
一般 ASM 作有何不同 ? 段 ASM code 有使用到 .data 段的宣告,一整片都是行的 code,打印字串,抓取位址的方式非常特。
址中例子
_start:
jmp short ender
starter:
xor eax, eax ;clean up the registers
xor ebx, ebx
xor edx, edx
xor ecx, ecx
mov al, 4 ;syscall write
mov bl, 1 ;stdout is 1
pop ecx ;get the address of the string from the stack
mov dl, 5 ;length of the string
int 0x80
xor eax, eax
mov al, 1 ;exit the shellcode
xor ebx,ebx
int 0x80
ender:
call starter ;put the address of the string on the stack
db 'hello'
可以看到,使用 call starter 下一行的指令(好是字串"hello" 的位址)入 stack 之中,然後藉由 pop ecx 得到位址打印出。
但只是一法,但是要需要多字串,一直在 ASM 後方增加新的字串,累的候就相不方便,要自己算偏移多少值,於增加或修改都相不方便,不以 DEMO 向的,什都行!
- 行常用的法
- 次作最大的疑惑,好的 BOA 呢?其它有做於次的作之中。
操作境理解完,正是要明 shell code 撰的候了,但次系境用 Linux 而非 Windows,Windows 尚未研究它的各麻,等到有人意出分享他的心得。
明年的候,又有多少人修查到一篇呢?
「弟妹考古,他失自我的能力。」by 富皓
的部分,等作交了之後再吧。
特注意到,除案的理,通常透的 system call 有 unlink() 或者是
int execve(const char *filename, char *const argv[], char *const envp[]);
相信很多人仍不明白指列,而形式。
[2013/12/11 Update]
- 目模糊不清的下,我有新的理解方式。
「解密 function 在 MBC ,然後整 MBC 可以收 server ,因此 server 到 client 是一段加密 MBC。而 client 要先分配 global 一段 MBC。而 MBC 也有一段 header,如果解密 function 形於 MBC 後段,header 需加入跳的 offset。」
目也是故意的,意去吧。
- 首先,看一下 Linux system call table
作,好入的存器所的(不管是值是址)。
- 如何使用 system call,根素材 http://mike820324.blogspot.tw/search/label/shell%20code ,址相重要,其中要用到的式 nanosleep() 和 execve()
int nanosleep(const struct timespec *req, struct timespec *rem);
....
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
函理,的是指,而配置如上, time_t tv_sec 位址低,而 long tv_nsec 址是高的 (ANSI C 的 struct 法都是如此配置)。
如果我用放到 stack 方式,先入 nanoseconds 的值 (push #val),再入 seconds 的值。整 timespec 占有 8 bytes 大小,分占 4 bytes,放入束後,由 esp (stack pointer) 指到 timespec 位置,因此把 esp 移入到 nanosleep() 指定存器中,接著呼叫 int 80 行即可。
int execve(const char *filename, char *const argv[],
char *const envp[]);
函稍微了,通常我使用到 main(int argc, char *argv[]),入程式的相,但是 execve() 有定 int argc,那它是怎理的 ? 其也不想像,由於定的是指列,因此在最後一指一定指向於 null (zero)。
但是明白些後,很多人又把字串尾的 '\0' 和 null 搞混了。
char *argv[]={"/bin/rm","./test",NULL};
execve(argv[0],argv,NULL);
一助教的例,宣告字串 '/bin/rm', 0x00, '/test', 0x00
其中 0x00 即 '\0' 的字串尾的十六制。
假使用直接打在 asm code 中,db '/bin/rm', 0x00 ... 似的方法。
由於函要求指列,仍需要每字串的 offset 收集成一的列,又是新的了,要怎拿到且每字串的 offset 放入?如果法使用 malloc(),入 stack 是一好法,倒入 offset 最後再 esp 取出,便可拿到的指列的起始位址。
- 一下,合言
- 在 ANSI C 操作,的 push 序,是由右到左。假如呼叫 foo(a, b, c)
依序 push c, push b, push a
- stack 是高位址往低位址填。
因此如果要字串塞到 stack 中,必字串倒 push 去。同理利用 stack 的指列使用。
- 得知了 ANSI C 的 function 中,也可以呼叫 function 完成 stack 上可行程式的指令,就不必在期加入定。
- 番外篇:
由 server 送加密的 MBC code,而解密 function 放在起位置。
重 - 如何自己做解密?// 解密 function 有被加密,但是真正行的 code 被加密。
也就是段 MBC 自己的一部分 code 行解密作。
初步是子的:
- 一始 MBC 需要得到一字串位址作。
接著行解密作,跳到解密 function,跳利用 call 得到後段的位址,使用 for loop 行解密作 (每一 byte 著手 xor 操作 ... 等)。
- 查 MBC 的 check sum 位,然後跳到指定的指令流上。
// check sum 位在 server 那端加入。
- 法提供程式代。
文章定位: