Decrypt "Saved Password" from Chrome in C - python

As a part of a project, we are trying to decrypt saved password in Google Chrome. After little digging we understand that Chrome encrypt the password using CryptProtectData function which let you encrypt the data using login user credential i.e. the encrypted data can only be decrypted on same machine by same user (other users also if appropiate parameters are provided).
Anyhow, I have previously wrote a Python script to do exactly that and it works perfectly fine.
from os import getenv, unlink
from shutil import copy
import sqlite3
import win32crypt
dbpath = "C:\Users\\"+ getenv('username') +"\AppData\Local\Google\Chrome\User Data\Default\\"
copy(dbpath + "Login Data", dbpath + "Login Data.db")
conn = sqlite3.connect(dbpath + "Login Data.db")
cursor = conn.cursor()
cursor.execute('SELECT action_url, username_value, password_value FROM logins')
for result in cursor.fetchall():
password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
print result[0] + " - " + result[1] + ":" + password
conn.close()
unlink(dbpath + "Login Data.db")
But due to project requirement, i have to code it in C language.
So i wrote the following code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
#include "sqlite3.h"
static int callback(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: \n", (const char*)data);
for(i=0; i<argc; i++){
if (i == 2 ){
DATA_BLOB DataIn;
DATA_BLOB DataOut;
BYTE *pbDataInput = (BYTE *) argv[i];
DWORD cbDataInput = strlen((char *) pbDataInput) + 1;
DataIn.pbData = pbDataInput;
DataIn.cbData = cbDataInput;
if (CryptUnprotectData (&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))
printf("%s\n", DataOut.pbData);
else
printf("Error number %x.\n", GetLastError());
}
// printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char* argv[])
{
sqlite3 *db;
char *zErrMsg = 0;
int rc;
char *sql;
const char* data = "Callback function called";
/* Open database */
rc = sqlite3_open("Login Data.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/* Create SQL statement */
sql = "SELECT action_url, username_value, password_value from logins";
/* Execute SQL statement, */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
return 0;
}
It compiled correctly without any error, but the decrypted data was not correct.
C:\>gcc -o decryptor decryptor.c sqlite3.o -lcrypt32
C:\>decryptor.exe
Opened database successfully
Callback function called: Important Data
Error Number 57.
Operation done successfully
C:\>
According to System Error Codes (0-499),
0x57 is for ERROR_INVALID_PARAMETER (The parameter is incorrect)
What am I missing?

This works just fine for me as you have your crypted data in 2hex.txt (just saved it from DB Browser). Your problem was really in strlen() function, because it meets first "0" in byte sequence and stops. Just avoid it.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
int main(){
FILE *fp;
DATA_BLOB DataIn;
DATA_BLOB DataOut;
char result[1000]="";
unsigned char buf[1000]="";
int tmpbuf;
int i=0;
fp=fopen("3hex.txt","rb");
printf ("Crypted data:\n");
for(i=0;(tmpbuf=getc(fp))!=EOF;i++)
{
buf[i]=tmpbuf;
if (i%16==0) printf("\n");
printf("%02X ",buf[i]);
}
DataIn.pbData=buf;
DataIn.cbData=i+1;
if (CryptUnprotectData (&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))
{
for (i=0;i<DataOut.cbData;i++)
{
result[i]=DataOut.pbData[i];
}
result[i+1]='\0';
printf("\nResult as string: %s\n", result);
}
else printf("Error number %x.\n", GetLastError());
}

Related

Segmentation fault when trying to read python process memory on Mac OS

I was trying to figure out how the Mach VM Api works as there is almost 0 documentation around it and to do that I was messing around with reading/writing to other processes' memory.
To start I basically created a c program that constantly printed a string and its address. Then I used this program to try modifying the string mid execution and it worked fine:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <libproc.h>
#include <mach/mach.h>
#include <mach/mach_vm.h>
#define EXIT_ON_MACH_ERROR(msg, retval) \
if (kr != KERN_SUCCESS) { mach_error(msg ":" , kr); exit((retval)); }
uint32_t* get_pids(uint16_t* size) {
// Gets all PIDS on the system to locate specific PID later. Probably inefficient
// but I don't care
uint32_t number_of_pids = proc_listpids(1, 0, NULL, 0);
uint32_t* buffer = malloc(sizeof(uint32_t) * number_of_pids);
uint8_t return_code = proc_listpids(1, 0, buffer, sizeof(buffer) * number_of_pids);
uint16_t sum = 0;
for(int i = 0; i < number_of_pids; i++) {
if(buffer[i] != 0) {
sum++;
}
}
uint32_t* final = malloc(sizeof(uint32_t) * sum);
for(int i = 0, t = 0; i < number_of_pids; i++) {
if(buffer[i]) {
final[t++] = buffer[i];
}
}
*size = sum;
return final;
}
int main() {
// Locate correct PID according to process name
uint16_t size;
uint32_t* pids = get_pids(&size);
uint16_t maxpathlength = 1024;
uint16_t path_size = maxpathlength * 4;
char path_buffer[path_size];
uint32_t process_pid = 0;
for(int i = 0; i < size; i++) {
memset(path_buffer, '\0', sizeof(path_buffer));
uint8_t return_code = proc_pidpath(pids[i], path_buffer, path_size);
if(strstr(path_buffer, "Python")) {
printf("%d\n", i);
process_pid = pids[i];
}
//printf("PID: %d, Process: %s\n", pids[i], path_buffer);
}
printf("%d\n", process_pid);
struct proc_taskallinfo pro_info;
uint32_t status = proc_pidinfo(process_pid, PROC_PIDTASKALLINFO, 0, &pro_info, sizeof(pro_info));
printf("Python PID: %d\n", process_pid);
printf("Self PID: %d\n", mach_host_self());
mach_port_t port = 0;
kern_return_t kr = task_for_pid(mach_task_self(), process_pid, &port);
EXIT_ON_MACH_ERROR("task_for_pid", kr);
printf("Port: %d\n\n\n", port);
// STUFF
mach_vm_address_t address = 0x102d4b770;
mach_vm_address_t address_a = 0x102d4b770;
char data[50] = "wow";
vm_offset_t buf;
mach_msg_type_number_t sz;
// MEMORY DEALLOCATION
kern_return_t suc = mach_vm_deallocate(port, (mach_vm_address_t) address, (mach_vm_size_t) 1000);
if (suc!=KERN_SUCCESS)
{
printf("mach_vm_deallocate() failed with message %s!\n", mach_error_string(suc));
}
// MEMORY ALLOCATION
kern_return_t all_suc = mach_vm_allocate(port, (mach_vm_address_t *) &address_a, (vm_size_t) 26, false);
if (all_suc!=KERN_SUCCESS)
{
printf("mach_vm_allocate() failed with message %s!\n", mach_error_string(all_suc));
}
// WRITE TO MEMORY
kern_return_t success = mach_vm_write(port, (vm_address_t) address, (vm_address_t)data, 26);
if (success!=KERN_SUCCESS)
{
printf("mach_vm_write() failed with message %s!\n", mach_error_string(success));
}
// READ FROM MEMORY
kern_return_t read_success = mach_vm_read(port, (vm_address_t) 0x6000018c4030, 26, &buf, &sz);
if (read_success!=KERN_SUCCESS)
{
printf("mach_vm_read() failed with message %s!\n", mach_error_string(read_success));
}
char * newstr = (char *) buf;
printf("%s\n", newstr);
return 0;
}
address and address_a were entered manually after figuring out the variable's address. However, when I tried this with a python process where I again just constantly printed out the string and address, I got the following error message the instant I ran the code above:
zsh: segmentation fault python3 strtest.py
I have no knowledge about CPython, so even after playing around a bit and trying to make it work, nothing happened. How can I make this work even on programs? I know its possible as Bit-Slicer made it work but I wasn't able to found out how.

Reading certain letters after a specified string from a text file [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 11 months ago.
Improve this question
I want to get out the characters and numbers immediately after the very specific characters "data-permalink=" in a huge text file (50MB). The output should ideally be written in a simple (separate) text file looking something like this:
34k89
456ij
233a4
...
the "data-permalink="" stays always the exact same (as usual in source codes), but the id within can be any combination of characters and numbers. It seemed simple at first, but since it is not at the start of a line, or the needed output is not a separate word I was not able to come up with a working solution at all in the required time. I am running out of time and need a solution or hints to this immediately, so any help is greatly appreciated
example of data in the source data file:
random stuff above
....
I would understand c++ or python the most, so such a solution using these languages would be nice.
I tried something like this:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream in ("data.txt");
if(in.fail())
{
cout<<"error";
}
else
{
char c;
while(in.get(c))
{
if(c=="data-permalink=")
cout<<"lol this is awesome"
else
cout<<" ";
}
}
return 0;
}
It is just a random attempt to see if the structure works, nowhere near a solution. This prob. also gives u guys a good guess on how bad i am currently lmao.
Hm, basically 50MB is considered "small" nowadays. With taht small data, you can read the whole file into one std::stringand then do a linear search.
So, the algorithm is:
Open files and check, if they could be opened
Read complete file into a std::string
Do a linear search for the string "data-permalink=""
Remember the start position of the permalink
Search for the closing "
Use the std::strings substrfunction to create the output permalink string
Write this to a file
Goto 1.
I created a 70MB random test file with random data.
The whole procedure takes less than 1s. Even with slow linear search.
But caveat. You want to parse a HTML file. This will most probably not work, because of potential nested structures. For this you should use existing HTML parsers.
Anyway. Here is one of many possible solutions.
#include <iostream>
#include <fstream>
#include <string>
#include <random>
#include <iterator>
#include <algorithm>
std::string randomSourceCharacters{ " abcdefghijklmnopqrstuvwxyz" };
const std::string sourceFileName{ "r:\\test.txt" };
const std::string linkFileName{ "r:\\links.txt" };
void createRandomData() {
std::random_device randomDevice;
std::mt19937 randomGgenerator(randomDevice());
std::uniform_int_distribution<> randomCharacterDistribution(0, randomSourceCharacters.size() - 1);
std::uniform_int_distribution<> randomLength(10, 30);
if (std::ofstream ofs{ sourceFileName }; ofs) {
for (size_t i{}; i < 1000000; ++i) {
const int prefixLength{ randomLength(randomGgenerator) };
const int linkLength{ randomLength(randomGgenerator) };
const int suffixLength{ randomLength(randomGgenerator) };
for (int k{}; k < prefixLength; ++k)
ofs << randomSourceCharacters[randomCharacterDistribution(randomGgenerator)];
ofs << "data-permalink=\"";
for (int k{}; k < linkLength; ++k)
ofs << randomSourceCharacters[randomCharacterDistribution(randomGgenerator)];
ofs << "\"";
for (int k{}; k < suffixLength; ++k)
ofs << randomSourceCharacters[randomCharacterDistribution(randomGgenerator)];
}
}
else std::cerr << "\nError: Could not open source file '" << sourceFileName << "' for writing\n";
}
int main() {
// Please uncomment if you want to create a file with test data
// createRandomData();
// Open source file for reading and check, if file could be opened
if (std::ifstream ifs{ sourceFileName }; ifs) {
// Open link file for writing and check, if file could be opened
if (std::ofstream ofs{ linkFileName }; ofs) {
// Read the complete 50MB file into a string
std::string data(std::istreambuf_iterator<char>(ifs), {});
const std::string searchString{ "data-permalink=\"" };
const std::string permalinkEndString{ "\"" };
// Do a linear search
for (size_t posBegin{}; posBegin < data.length(); ) {
// Search for the begin of the permalink
if (posBegin = data.find(searchString, posBegin); posBegin != std::string::npos) {
const size_t posStartForEndSearch = posBegin + searchString.length() ;
// Search fo the end of the perma link
if (size_t posEnd = data.find(permalinkEndString, posStartForEndSearch); posEnd != std::string::npos) {
// Output result
const size_t lengthPermalink{ posEnd - posStartForEndSearch };
const std::string output{ data.substr(posStartForEndSearch, lengthPermalink) };
ofs << output << '\n';
posBegin = posEnd + 1;
}
else break;
}
else break;
}
}
else std::cerr << "\nError: Could not open source file '" << sourceFileName << "' for reading\n";
}
else std::cerr << "\nError: Could not open source file '" << sourceFileName << "' for reading\n";
}
Edit
If you need unique links you may store the result in an std::unordered_set and then output later.
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <algorithm>
#include <unordered_set>
const std::string sourceFileName{ "r:\\test.txt" };
const std::string linkFileName{ "r:\\links.txt" };
int main() {
// Open source file for reading and check, if file could be opened
if (std::ifstream ifs{ sourceFileName }; ifs) {
// Open link file for writing and check, if file could be opened
if (std::ofstream ofs{ linkFileName }; ofs) {
// Read the complete 50MB file into a string
std::string data(std::istreambuf_iterator<char>(ifs), {});
const std::string searchString{ "data-permalink=\"" };
const std::string permalinkEndString{ "\"" };
// Here we will store unique results
std::unordered_set<std::string> result{};
// Do a linear search
for (size_t posBegin{}; posBegin < data.length(); ) {
// Search for the begin of the permalink
if (posBegin = data.find(searchString, posBegin); posBegin != std::string::npos) {
const size_t posStartForEndSearch = posBegin + searchString.length();
// Search fo the end of the perma link
if (size_t posEnd = data.find(permalinkEndString, posStartForEndSearch); posEnd != std::string::npos) {
// Output result
const size_t lengthPermalink{ posEnd - posStartForEndSearch };
const std::string output{ data.substr(posStartForEndSearch, lengthPermalink) };
result.insert(output);
posBegin = posEnd + 1;
}
else break;
}
else break;
}
for (const std::string& link : result)
ofs << link << '\n';
}
else std::cerr << "\nError: Could not open source file '" << sourceFileName << "' for reading\n";
}
else std::cerr << "\nError: Could not open source file '" << sourceFileName << "' for reading\n";
}

Python properly and effectively obtaining DBUS object path (e.g. /org/bluez/dev_XX_XX_XX_XX_XX_XX/playerY)

I would like to get the device path for bluez-based A2DP bluetooth player that I am creating. I am stuck implementing Play/Pause/Next/Previous commands efficiently, because the dbus availability and player path changes depending on the media player you choose. Furthermore, bluez sometimes decides to send a lot of useless information (for me) such as playlist details that makes the payload bigger for my application to handle. So the goal here is to obtain /org/bluez/dev_XX_XX_XX_XX_XX_XX/playerY when a function is called.
def update_player():
manager = dbus.Interface(self.bus.get_object("org.bluez", "/"), "org.freedesktop.DBus.ObjectManager")
objects = manager.GetManagedObjects()
player_path = getFromDict(objects,[self.devicepath,"org.bluez.MediaControl1", "Player"])
When I try to change the media player, or bluez sends some logs (so 5% of the time in general), dbus org.freedesktop.DBus.ObjectManager receives a lot of information which makes manager.GetManagedObjects() get stuck for 10~20 seconds.
Is there a way of determining bluez object path without having to receive the entire org.freedesktop.DBus.ObjectManager objects; or Is there a way to just limit the amount of message sent by bluez. I really would like to get the object path efficiently. Any help is greately appreciated.
EDIT:
Although I did not test it in the embedded system that had the problem with ObjectManager being populated, thanks to Partiban's great suggestion, I was able to use InterfacesAdded and some regex in order to match the path I needed.
self.bus.add_signal_receiver(self.objectPathHandler,
bus_name="org.bluez",
dbus_interface="org.freedesktop.DBus.ObjectManager",
signal_name="InterfacesAdded",
path_keyword="path")
def objectPathHandler(self, interface, changed, path):
iface = interface[interface.rfind(".") + 1:]
#print("InterfacesAdded: {}; changed: {}; path {}".format(iface, changed, path))
self.playerpath = re.findall('/org/bluez/hci[0-9]/dev_[\dA-F]{2}_[\dA-F]{2}_[\dA-F]{2}_[\dA-F]{2}_[\dA-F]{2}_[\dA-F]{2}/player[0-9]+', iface)[0]
print "Object path:"
print self.playerpath
def update_player(self):
print "Updating player"
if self.devicepath != "None" and self.playerpath != "None":
if self.playerpath:
self.connected = 1
self.getPlayer (self.playerpath)
player_properties = self.player.GetAll(PLAYER_IFACE, dbus_interface="org.freedesktop.DBus.Properties")
You should not be using org.freedesktop.DBus.ObjectManager.GetManagedObjects to get the object path every time. This GetManagedObjects is meant to get existing or previously available interface and it's details when your application starts.
For example, assuming Bluez is started and 1 end device is connected. Later your application starts, during init/start of your application you may need to get all the available/connected devices, so you can use GetManagedObjects to get it.
For the purpose of runtime creation of interfaces, object path you should rely on signals InterfacesAdded and InterfacesRemoved of the objectmanager.
I don't have examples in python, but the below example in C typically does the StartDiscovery and monitor for new devices using signals. So you adapt to similar example in python using signals. The below example is just for clarity purpose (more details on this example is here in Linumiz).
/*
* bluez_adapter_scan.c - Scan for bluetooth devices
* - This example scans for new devices after powering the adapter, if any devices
* appeared in /org/hciX/dev_XX_YY_ZZ_AA_BB_CC, it is monitered using "InterfaceAdded"
* signal and all the properties of the device is printed
* - Scanning continues to run until any device is disappered, this happens after 180 seconds
* automatically if the device is not used.
* gcc `pkg-config --cflags glib-2.0 gio-2.0` -Wall -Wextra -o ./bin/bluez_adapter_scan ./bluez_adapter_scan.c `pkg-config --libs glib-2.0 gio-2.0`
*/
#include <glib.h>
#include <gio/gio.h>
GDBusConnection *con;
static void bluez_property_value(const gchar *key, GVariant *value)
{
const gchar *type = g_variant_get_type_string(value);
g_print("\t%s : ", key);
switch(*type) {
case 'o':
case 's':
g_print("%s\n", g_variant_get_string(value, NULL));
break;
case 'b':
g_print("%d\n", g_variant_get_boolean(value));
break;
case 'u':
g_print("%d\n", g_variant_get_uint32(value));
break;
case 'a':
/* TODO Handling only 'as', but not array of dicts */
if(g_strcmp0(type, "as"))
break;
g_print("\n");
const gchar *uuid;
GVariantIter i;
g_variant_iter_init(&i, value);
while(g_variant_iter_next(&i, "s", &uuid))
g_print("\t\t%s\n", uuid);
break;
default:
g_print("Other\n");
break;
}
}
static void bluez_device_appeared(GDBusConnection *sig,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
(void)sig;
(void)sender_name;
(void)object_path;
(void)interface;
(void)signal_name;
(void)user_data;
GVariantIter *interfaces;
const char *object;
const gchar *interface_name;
GVariant *properties;
g_variant_get(parameters, "(&oa{sa{sv}})", &object, &interfaces);
while(g_variant_iter_next(interfaces, "{&s#a{sv}}", &interface_name, &properties)) {
if(g_strstr_len(g_ascii_strdown(interface_name, -1), -1, "device")) {
g_print("[ %s ]\n", object);
const gchar *property_name;
GVariantIter i;
GVariant *prop_val;
g_variant_iter_init(&i, properties);
while(g_variant_iter_next(&i, "{&sv}", &property_name, &prop_val))
bluez_property_value(property_name, prop_val);
g_variant_unref(prop_val);
}
g_variant_unref(properties);
}
return;
}
#define BT_ADDRESS_STRING_SIZE 18
static void bluez_device_disappeared(GDBusConnection *sig,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
(void)sig;
(void)sender_name;
(void)object_path;
(void)interface;
(void)signal_name;
GVariantIter *interfaces;
const char *object;
const gchar *interface_name;
char address[BT_ADDRESS_STRING_SIZE] = {'\0'};
g_variant_get(parameters, "(&oas)", &object, &interfaces);
while(g_variant_iter_next(interfaces, "s", &interface_name)) {
if(g_strstr_len(g_ascii_strdown(interface_name, -1), -1, "device")) {
int i;
char *tmp = g_strstr_len(object, -1, "dev_") + 4;
for(i = 0; *tmp != '\0'; i++, tmp++) {
if(*tmp == '_') {
address[i] = ':';
continue;
}
address[i] = *tmp;
}
g_print("\nDevice %s removed\n", address);
g_main_loop_quit((GMainLoop *)user_data);
}
}
return;
}
static void bluez_signal_adapter_changed(GDBusConnection *conn,
const gchar *sender,
const gchar *path,
const gchar *interface,
const gchar *signal,
GVariant *params,
void *userdata)
{
(void)conn;
(void)sender;
(void)path;
(void)interface;
(void)userdata;
GVariantIter *properties = NULL;
GVariantIter *unknown = NULL;
const char *iface;
const char *key;
GVariant *value = NULL;
const gchar *signature = g_variant_get_type_string(params);
if(g_strcmp0(signature, "(sa{sv}as)") != 0) {
g_print("Invalid signature for %s: %s != %s", signal, signature, "(sa{sv}as)");
goto done;
}
g_variant_get(params, "(&sa{sv}as)", &iface, &properties, &unknown);
while(g_variant_iter_next(properties, "{&sv}", &key, &value)) {
if(!g_strcmp0(key, "Powered")) {
if(!g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
g_print("Invalid argument type for %s: %s != %s", key,
g_variant_get_type_string(value), "b");
goto done;
}
g_print("Adapter is Powered \"%s\"\n", g_variant_get_boolean(value) ? "on" : "off");
}
if(!g_strcmp0(key, "Discovering")) {
if(!g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
g_print("Invalid argument type for %s: %s != %s", key,
g_variant_get_type_string(value), "b");
goto done;
}
g_print("Adapter scan \"%s\"\n", g_variant_get_boolean(value) ? "on" : "off");
}
}
done:
if(properties != NULL)
g_variant_iter_free(properties);
if(value != NULL)
g_variant_unref(value);
}
static int bluez_adapter_call_method(const char *method)
{
GVariant *result;
GError *error = NULL;
result = g_dbus_connection_call_sync(con,
"org.bluez",
/* TODO Find the adapter path runtime */
"/org/bluez/hci0",
"org.bluez.Adapter1",
method,
NULL,
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if(error != NULL)
return 1;
g_variant_unref(result);
return 0;
}
static int bluez_adapter_set_property(const char *prop, GVariant *value)
{
GVariant *result;
GError *error = NULL;
result = g_dbus_connection_call_sync(con,
"org.bluez",
"/org/bluez/hci0",
"org.freedesktop.DBus.Properties",
"Set",
g_variant_new("(ssv)", "org.bluez.Adapter1", prop, value),
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if(error != NULL)
return 1;
g_variant_unref(result);
return 0;
}
int main(void)
{
GMainLoop *loop;
int rc;
guint prop_changed;
guint iface_added;
guint iface_removed;
con = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
if(con == NULL) {
g_print("Not able to get connection to system bus\n");
return 1;
}
loop = g_main_loop_new(NULL, FALSE);
prop_changed = g_dbus_connection_signal_subscribe(con,
"org.bluez",
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
NULL,
"org.bluez.Adapter1",
G_DBUS_SIGNAL_FLAGS_NONE,
bluez_signal_adapter_changed,
NULL,
NULL);
iface_added = g_dbus_connection_signal_subscribe(con,
"org.bluez",
"org.freedesktop.DBus.ObjectManager",
"InterfacesAdded",
NULL,
NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
bluez_device_appeared,
loop,
NULL);
iface_removed = g_dbus_connection_signal_subscribe(con,
"org.bluez",
"org.freedesktop.DBus.ObjectManager",
"InterfacesRemoved",
NULL,
NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
bluez_device_disappeared,
loop,
NULL);
rc = bluez_adapter_set_property("Powered", g_variant_new("b", TRUE));
if(rc) {
g_print("Not able to enable the adapter\n");
goto fail;
}
rc = bluez_adapter_call_method("StartDiscovery");
if(rc) {
g_print("Not able to scan for new devices\n");
goto fail;
}
g_main_loop_run(loop);
rc = bluez_adapter_call_method("StopDiscovery");
if(rc)
g_print("Not able to stop scanning\n");
g_usleep(100);
rc = bluez_adapter_set_property("Powered", g_variant_new("b", FALSE));
if(rc)
g_print("Not able to disable the adapter\n");
fail:
g_dbus_connection_signal_unsubscribe(con, prop_changed);
g_dbus_connection_signal_unsubscribe(con, iface_added);
g_dbus_connection_signal_unsubscribe(con, iface_removed);
g_object_unref(con);
return 0;
}
In this example of scanning of devices using StartDiscovery I have used both the signals InterfaceRemoved and InterfaceAdded to demonstrate. So when new devices appeared on /org/hciX/, bluez_device_appeared is called and removal happens in the same way.
If you have more then one bluetooth adapter connected, you can filter them under g_dbus_connection_signal_subscribe by specifying the adapters path e.g as /org/bluez/hciX.
All the DBUS based daemons use signals to notify the clients on the bus, so we see lots messaged on the bus. So we need to subscribe based on the exact need. This filter is applied at dbus daemon level and messages are forwarded.
To add MediaControl1 interface of bluez is outdated and deprecated. All new applications should use MediaPlayer as defined here.

Use script to send string through socket

I am using a program written in Python which accepts an input from user though socket (I an not providing the code here in order not to confuse, since it runs fine with passing a String like: Hello world). Though what i want is to pass a big String through socket using python like:
$(python -c 'print "A" * 8000')
and the server to read 8000 times the letter 'A' not the above String as input. How is this possible?
EDIT:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define KEYFILESIZE 41
#define BUFF_SIZE 0X1000
#define PORTNO 12345
void firstFunc(int FD){
char buf[BUFF_SIZE];
int cookie=*(int*)(buf+0x1000);
printf("cookie: %x\n",cookie); //the server operator gets this info
read(FD,buf,BUFF_SIZE*2); //overflow the buffer 2x
return;
}
int servlet(int fd){
char greetings[BUFF_SIZE];
sprintf(greetings,"Greetings client #%d\n",fd);
write(fd,greetings,strlen(greetings));
firstFunc(fd);
char* sorry="Sorry";
write(fd,sorry,strlen(sorry));
return 0;
}
int main(int argc, char *argv[])
{
//char buffer[BUFFER_SIZE];
int sockfd, newsockfd, portno, pid;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
/* if (argc < 2) { */
/* fprintf(stderr,"ERROR, no port provided\n"); */
/* exit(1); */
/* } */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0){
perror("ERROR opening socket");
exit(1);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
// portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORTNO);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0){
perror("ERROR on binding");
exit(1);
}
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0){
perror("ERROR on accept");
exit(1);
}
pid = fork();
if (pid < 0){
perror("ERROR on fork");
exit(1);
}
if (pid == 0) {
close(sockfd);
servlet(newsockfd);
exit(0);
}
//make sure to wait at some point to avoid zombies
else close(newsockfd);
waitpid(-1, NULL, WNOHANG);
}
close(sockfd);
return 0;
}
Ok so the above is the code of the server running in an Ubuntu vm. With netcat i connect to the server from another vm (running Kali) and i have tried to send as input:
1. $(python -c 'print "A" * 8000')
(python -c 'print "A" * 8000')
3.python -c 'print "A" * 8000'
None of the above worked. Below is a picture of what the server sees after each of the above
enter image description here
Of course what i wanted it to see in each case is 8000 'A' (AAAAAAAAAAAA....)
The answer to the question is to write a file in python which after the connection has been established (that is the part which i have done manually above with netcat ) will print the number of 'A' or any any string required. Example:
import socket
from struct import pack
host='ip_to_connect_to'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port_to_connect_to))
answer=s.recv(1024)
print answer
padding=800 * "A"
s.send(padding)

Import error in Python for libcurl library

I have written a program in c using libcurl to load url and send the return value to Python (I am passing 2 integer value from Python to C. i am yet to enhance the code, currently trying the logic and variable accessibility between Python and C.). I am able to compile the program successfully. When i load the module in Python i am getting error saying "undefined symbol: curl_easy_getinfo". Please let me know how to fix the issue.
Code:
#include <Python.h>
#include <stdio.h>
#include <time.h>
#include <stdio.h>
#include <pthread.h>
#include <curl/curl.h>
#define NUMT 4
/*
List of URLs to fetch.
If you intend to use a SSL-based protocol here you MUST setup the OpenSSL
callback functions as described here:
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
*/
const char * const urls[NUMT]= {
"http://www.google.com",
"http://www.yahoo.com/",
"http://www.haxx.se/done.html",
"http://www.haxx.se/"
};
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3
struct myprogress {
double lastruntime;
curl_off_t totdnld;
void *url;
CURL *curl;
};
static PyObject *foo1_add(PyObject *self, PyObject *args)
{
int a;
int b;
int s;
if (!PyArg_ParseTuple(args, "ii", &a, &b))
{
return NULL;
}
s = sum (a, b);
return Py_BuildValue("i", s);
// return Py_BuildValue("i", a + b);
}
static PyMethodDef foo1_methods[] = {
{ "add", (PyCFunction)foo1_add, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
PyMODINIT_FUNC initfoo1()
{
Py_InitModule3("foo1", foo1_methods, "My first extension module.");
}
int sum(int x, int y) {
int z;
z = x + y;
z = geturl (x, y);
return (z);
}
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
#ifdef 0
static int xferinfo(void *p,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
struct myprogress *myp = (struct myprogress *)p;
CURL *curl = myp->curl;
double curtime = 0;
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime);
/* under certain circumstances it may be desirable for certain functionality
to only run every N seconds, in order to do this the transaction time can
be used */
if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {
myp->lastruntime = curtime;
fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
}
if (dlnow > 0) {
fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
" DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
"\r\n",
ulnow, ultotal, dlnow, dltotal);
}
myp->totdnld = myp->totdnld + dlnow;
if (dlnow > 0) {
fprintf(stderr, "TOTAL Download: %" CURL_FORMAT_CURL_OFF_T " url is: %s \r\n", myp->totdnld, myp->url);
}
// if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
// return 1;
return 0;
}
#endif
/* for libcurl older than 7.32.0 (CURLOPT_PROGRESSFUNCTION) */
static int older_progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
{
return xferinfo(p,
(curl_off_t)dltotal,
(curl_off_t)dlnow,
(curl_off_t)ultotal,
(curl_off_t)ulnow);
}
static void *pull_one_url(void *url)
{
CURL *curl;
CURLcode res = CURLE_OK;
struct myprogress prog;
curl = curl_easy_init();
if(curl) {
prog.lastruntime = 0;
prog.curl = curl;
prog.url = url;
prog.totdnld = (curl_off_t) 0;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, older_progress);
/* pass the struct pointer into the progress function */
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
#ifdef 0
#if LIBCURL_VERSION_NUM >= 0x072000
/* xferinfo was introduced in 7.32.0, no earlier libcurl versions will
compile as they won't have the symbols around.
If built with a newer libcurl, but running with an older libcurl:
curl_easy_setopt() will fail in run-time trying to set the new
callback, making the older callback get used.
New libcurls will prefer the new callback and instead use that one even
if both callbacks are set. */
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
/* pass the struct pointer into the xferinfo function, note that this is
an alias to CURLOPT_PROGRESSDATA */
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
#endif
#endif
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr, "%s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
return NULL;
}
/*
int pthread_create(pthread_t *new_thread_ID,
const pthread_attr_t *attr,
void * (*start_func)(void *), void *arg);
*/
int geturl(int x, int y)
{
pthread_t tid[NUMT];
int i;
int error;
/* Must initialize libcurl before any threads are started */
curl_global_init(CURL_GLOBAL_ALL);
for(i=0; i< NUMT; i++) {
error = pthread_create(&tid[i],
NULL, /* default attributes please */
pull_one_url,
(void *)urls[i]);
if(0 != error)
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
else
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
}
/* now wait for all threads to terminate */
for(i=0; i< NUMT; i++) {
error = pthread_join(tid[i], NULL);
fprintf(stderr, "Thread %d terminated\n", i);
}
return (x * y);
}
Command used for compilation:
gcc -lcurl -lpthread -shared -I/usr/include/python2.7 -fPIC sample.c –o add.so
Error:
>>> import foo1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./foo1.so: undefined symbol: curl_easy_perform
>>>
Try moving -lcurl and -lpthread to after sample.c in your compilation command. The linker resolves symbols in left-to-right order, so references from sample.c (e.g., curl_easy_getinfo) will be resolved from libraries specified after it.
It's better to use -pthread than -lpthread by the way. It sets preprocessor flags to make some functions reentrant for example.

Categories