ICMP Covert Channel: Reading ICMP message at receiver - channel

I am currently doing an assignment about ICMP Covert Channel. The environment is provided in Docker.
I am required to send an ICMP message, let say "Hello", from the sender and I used scapy for crafting the message, simply encrypted, without echoing:
import sys
import subprocess
from scapy.all import *
def encrypting(message):
strlen = len(message)
reverse = message[strLen::-1]
return reverse
if __name__ == "__main__":
encryptedMes = encrypting(sys.argv[2])
send(IP(dst=sys.argv[1])/ICMP(type=9)/encryptedMes)
However, at sender, It seemed like I am not allowed to install scapy to use the sniff(). I could use tcpdump but the furthest I could go is:
My expection is to print only the Hello part.
I need to write a python script to run indefinitely at receiver.
What are other ways I should try at receiver to run definitely and only print the content I crafted at sender.
Thank you, Huy Nguyen.

Related

Easier way to use pika asynchronous (twisted)?

This is my first project using rabbitmq and I am complete lost because I am not sure what would be the best way to solve a problem.
The program is fairly simple, it just listen for alarms events, and then put the events in a rabbitmq queue, but I am struggling with the architecture of the program.
If I open, publish and then close the connection for every single event, I will add a lot of latency, and unnecessary packages will be transmitted (even more than the usual because I am using TLS)...
If I keep a connection open, and create a function that publish the messages (I only work with a single queue, pretty basic), I will eventually have problems because multiple events can occur at the same time, and my program will not know what to do if the connection to the rabbitmq broker end.
Reading their documentations, the solution seems use one of their "Connection Adapters", which would fit me like a glove because I just rewrite all my connection stuff from basic sockets to use Twisted (I really liked their high level approach). But there is a problem. Their "basic example" is fairly complex for someone who barely considers himself "intermediate".
In a perfect world, I would be able to run the service in the same reactor as the "alarm servers" and call a method to publish a message. But I am struggling to understand the code. Has anyone who worked with pika could point me a better direction, or even tell me if there is a easier way?
Well, I will post what worked for me. Probably is not the best alternative but maybe it helps someone who gets here with the same problem.
First I decided to drop Twisted and use Asyncio (nothing personal, I just wanted to use it because it's already in python), and even tho pika had a good example using Asynchronous, I tried and found it easier to just use aio_pika.
I end up with 2 main functions. One for a publisher and another for a subscriber.
Bellow is my code that works for me...
# -*- coding: utf-8 -*-
import asyncio
import aio_pika
from myapp import conf
QUEUE_SEND = []
def add_queue_send(msg):
"""Add MSG to QUEUE
Args:
msg (string): JSON
"""
QUEUE_SEND.append(msg)
def build_url(amqp_user, amqp_pass, virtual_host):
"""Build Auth URL
Args:
amqp_user (str): User name
amqp_pass (str): Password
virtual_host (str): Virtual Host
Returns:
str: AMQP URL
"""
return ''.join(['amqps://',
amqp_user, ':', amqp_pass,
'#', conf.get('amqp_host'), '/', virtual_host,
'?cafile=', conf.get('ca_cert'),
'&keyfile=', conf.get('client_key'),
'&certfile=', conf.get('client_cert'),
'&no_verify_ssl=0'])
async def process_message(message: aio_pika.IncomingMessage):
"""Read a new message
Args:
message (aio_pika.IncomingMessage): Mensagem
"""
async with message.process():
# TODO: Do something with the new message
await asyncio.sleep(1)
async def consumer(url):
"""Keep listening to a MQTT queue
Args:
url (str): URL
Returns:
aio_pika.Connection: Conn?
"""
connection = await aio_pika.connect_robust(url=url)
# Channel
channel = await connection.channel()
# Max concurrent messages?
await channel.set_qos(prefetch_count=100)
# Queue
queue = await channel.declare_queue(conf.get('amqp_queue_client'))
# What call when a new message is received
await queue.consume(process_message)
# Returns the connection?
return connection
async def publisher(url):
"""Send messages from the queue.
Args:
url (str): URL de autenticação
"""
connection = await aio_pika.connect_robust(url=url)
# Channel
channel = await connection.channel()
while True:
if QUEUE_SEND:
# If the list (my queue) is not empty
msg = aio_pika.Message(body=QUEUE_SEND.pop().encode())
await channel.default_exchange.publish(msg, routing_key='queue')
else:
# Just wait
await asyncio.sleep(1)
await connection.close()
I started both using the ``loop.create_task```.
As I said. It kinda worked for me (even tho I am still having an issue with another part of my code) but I did not want to left this question open since most people can have the same issue.
If you know a better approach or a more elegant approach, please, share.

How to access REST API on a unix domain socket with Akka HTTP or Alpakka?

I would like to access the docker API using the /var/lib/docker.sock unix domain socket. I've seen examples where you can use (modern versions of) curl to call the API as follows:
curl --unix-socket /var/run/docker.sock http:/containers/json
where the REST command is expressed in the /containers/json path. I was excited to see the Alpakka Unix Domain Socket adapter, but you only seem to be able to send and receive raw bytes. Is there any elegant way to do this? Or do I have to manually construct an HTTP header and manage all the difficult stuff manually?
Here's a working snippet (see also the rest of the discussion at akka/akka-http#2139):
build.sbt:
val scalaV = "2.12.6"
val akkaV = "2.5.14"
val akkaHttpV = "10.1.3"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http" % akkaHttpV,
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpV,
"com.typesafe.akka" %% "akka-stream" % akkaV,
"com.lightbend.akka" %% "akka-stream-alpakka-unix-domain-socket" % "0.20",
)
DockerSockMain.scala:
import java.io.File
import java.net.InetSocketAddress
import akka.actor.ActorSystem
import akka.http.scaladsl.ClientTransport
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.HttpRequest
import akka.http.scaladsl.model.HttpResponse
import akka.http.scaladsl.settings.ClientConnectionSettings
import akka.http.scaladsl.settings.ConnectionPoolSettings
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import akka.stream.alpakka.unixdomainsocket.scaladsl.UnixDomainSocket
import akka.stream.scaladsl.Flow
import akka.util.ByteString
import spray.json.JsValue
import scala.concurrent.Future
object DockerSockMain extends App {
object DockerSockTransport extends ClientTransport {
override def connectTo(host: String, port: Int, settings: ClientConnectionSettings)(implicit system: ActorSystem): Flow[ByteString, ByteString, Future[Http.OutgoingConnection]] = {
// ignore everything for now
UnixDomainSocket().outgoingConnection(new File("/var/run/docker.sock"))
.mapMaterializedValue { _ =>
// Seems that the UnixDomainSocket.OutgoingConnection is never completed? It works anyway if we just assume it is completed
// instantly
Future.successful(Http.OutgoingConnection(InetSocketAddress.createUnresolved(host, port), InetSocketAddress.createUnresolved(host, port)))
}
}
}
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
import system.dispatcher
val settings = ConnectionPoolSettings(system).withTransport(DockerSockTransport)
import SprayJsonSupport._
def handleResponse(response: HttpResponse): Future[String] =
// TODO: create docker json model classes and directly marshal to them
Unmarshal(response).to[JsValue].map(_.prettyPrint)
Http().singleRequest(HttpRequest(uri = "http://localhost/images/json"), settings = settings)
.flatMap(handleResponse)
.onComplete { res =>
println(s"Got result: [$res]")
system.terminate()
}
}
Interesting use-case. You should be able to use Alpakka Unix Domain socket flow and put Akka Http ClientLayer on top of it.
The short answer to the question is "It Can't be Done"—at least not with the existing building blocks of Akka HTTP and the Alkappa Unix Domain Sockets. You would have to handle writing the HTTP GET request by manually sending the headers, i.e. (using the Docker API as an example)
GET /v1.24/containers/json HTTP/1.1\n
Host: localhost\n
\n\n
...and then reading the TCP response manually. Additionally, the Unix Domain Socket logic can't use the Alpakka code because it only currently provides a ServerBinding, and thus is designed to create a server that handles requests to a Unix socket, not to send data to a Unix socket and handle the response.
So everything has to be done manually. There's another StackOverflow question here that points out how the AFUNIXSocket github source code could be used to help with some of the low-level Unix Domain Socket logic that might be of help to others wanting to tackle this same problem.
The most elegant solution would also involve (as suggested by dvim's comment) writing an HTTP.ClientTransport to plug in the Unix Domain Socket communication layer and allow the HTTP library to expose the low-level functionality of writing request/response headers, etc. (One interesting note on that is that the API assumes a host/port parameter pair, which is tightly bound to the TCP paradigm.)

Wireshark dissector that works with tls/ssl

I have a protocol that uses SSL/TLS over a non-standard port and transmits non-standard data (not http) through it. I'm trying to make a wireshark dissector (in lua) to dissect this protocol.
How do I do this? I can register a dissector that gets called for tcp fragments on that port
local dissector_table_tcp = DissectorTable.get("tcp.port")
dissector_table_tcp:add(1234, myprotocol)
I can get the SSL dissector to then decode all the fragments as SSL
function myprotocol.dissector(tvb, pinfo, root)
local ssl_dissector = Dissector.get("ssl")
local ssl_dissected_len = ssl_dissector:call(tvb, pinfo, root)
pinfo.cols.protocol:set("My Protocol")
At this point, if I have a premaster key file set in Wireshark (Preferences->Protocols->SSL->Master key file), I can see the decrypted contents of the packets and all is good. Sort of.
But I want to create fields for my protocol and put them in the protocol tree. How do I get at the decrypted data that the ssl dissector produced?
Update:
I'm trying to muddle through this as best as I can; there's no tutorial on how exactly you're supposed to do this. It sort of looks like Wireshark has a programming model based on fields/variables that are populated by dissectors, and that in theory it should be possible to interrogate those variables to find the output of a dissector.
To that end, I've been running the SSL dissector and then looking at fields that it declares, but it doesn't actually seem to populate them. When I run a post-dissector after the SSL dissector, none of the seemingly-useful fields, like ssl.segments or ssl.segment.data, are set:
protocol_foo = Proto("foo", "Foo protocol")
port = 4172
g_field_segment = Field.new("ssl.segment")
g_field_segment_data = Field.new("ssl.segment.data")
g_field_segments = Field.new("ssl.segments")
g_field_reassembled_data = Field.new("ssl.reassembled.data")
function protocol_foo.dissector(tvb, pinfo, root)
print("====== protocol_foo")
for k,v in pairs({ g_field_segment, g_field_segment_data, g_field_segments, g_field_reassembled_data }) do
if v() ~= nil then
print("Field " .. v.name .. " is NOT nil")
else
print("Field " .. v.name .. " is nil")
end
end
end
-- post-dissector registration
local ssl_dissector = Dissector.get("ssl")
local dissector_table_tcp = DissectorTable.get("tcp.port")
dissector_table_tcp:add(port, ssl_dissector)
register_postdissector(protocol_foo)
When I run this code on my protocol, none of those ssl.segment* variables test positive; lots of variables (like the ssl.handshake.*) variables do test positive (at least with handshake pdus), but not the ones with the decrypted contents.
Does anyone have any ideas?

Getting OpenFlow rules from a datapath

In Ryu Controller, for a selected datapath, how can I get the OpenFlow rules from the switch? For example, for the rule below:
cookie=0x0, duration=18575.528s, table=0, n_packets=1, n_bytes=98,
priority=1,ip,in_port=3,nw_dst=10.0.0.1 actions=output:1
I want to get nw_dst and actions fields.
Use the OFPTableStatsRequest object. It will return a list with all the installed flows.
Note there is also an OFPGroupStatsRequest that does the same thing for groups.
An untested example that relies on an instance variable datapath.
import ryu.app.ofctl.api as api
def ofdpaTableStatsRequest(datapath):
parser = datapath.ofproto_parser
return parser.OFPTableStatsRequest(datapath)
def getFlows(self):
"""
Obtain a list of Flows loaded on the switch
`
:return: A list of Flow Entires
"""
msg = ofdpaTableStatsRequest(self.datapath)
reply = api.send_msg(self.ryuapp, msg,
reply_cls=self.parser.OFPTableStatsReply,
reply_multi=True)
// the flow entries you are looking for will be in the reply
Let me know if this works for you

how to get balance by USSD commands?

I have tired to search how to send USSD command on Google.
I want to check may balance from operator.
All of the samples I have seen use commands like this:
"AT+CUSD=1,\"*140*1#\"\r\n";
It seems to be correct. I am using something like this that I think works. I have a D-Link GSM modem, and when I send this command using it, it makes some noise on my speaker, which I believe tells me something happened.
my modem have it's own windows application when i disconnected modem by my own application,i check it by modem's application and in USSD tab i can found the result of my commands that i sent by myself application.
then that command works fine but i 'm confuse what is happens when i sent my command it return me "OK" and do not return operator answer and how my modem's application can read that answer????????
i test these commands but can not get result and my modem just return somethings like this:
"AT+CUSD=1,\"*140*1#\"\r\n\OK\r\n" only.
1) "AT+CUSD=1,\"*140*1#\",15\r\n"
2) "AT+CUSD=1,\"*140*1#\",1\r\n"
3) "AT+CUSD=1,\"*140*1#\",15\r"
4) "AT+CUSD=1,\"*140*1#\",1\r"
5) "AT+CUSD=1,\"*140*1#\""
i think reading command's result maybe has difference command or i should set some config on my modem .
it is very interesting for me that my modem do not return error to me and always return OK.
You need to set the Message format to AT+CMGF=0, before sending your USSD Command. This is PDU Mode (http://www.smartposition.nl/resources/sms_pdu.html). I was stumped using AT+CMGF=1, which is Text mode, before I decided to try AT+CMGF=0.
Worked like Magic.
So:
Set Message Format to PDU (AT+CMGF=0)
Execute Your USSD Command (AT+CUSD=1,*544*2*3#,15) - example message
Read response from the Port.
I am assuming that you know already how to form your AT Commands and Read the response from the Port.
I found that my modem use more than one port and i should connect at the first port to send my command and listen to another port to get the USSD command's result
Try This using Hyperterm Serial Monitor Application ( https://www.hilgraeve.com/hyperterminal-trial/ )
First Convert Modem to PDU Mode :
AT+CMGF=0
Second USSD Code Send :
AT+CUSD=1,"#132#",15
( Use your Country Carrier Codes )
Finally Read Output from Terminal :)
i just use this "AT+CUSD=1,'*120#',15" in my country the USSD code is *120# but remember if you are using it withing a code you must add crlf character to the end hope this help